划分VOC数据集,以及转换为划分后的COCO数据集格式

1.VOC数据集

    LabelImg是一款广泛应用于图像标注的开源工具,主要用于构建目标检测模型所需的数据集。Visual Object Classes(VOC)数据集作为一种常见的目标检测数据集,通过labelimg工具在图像中标注边界框和类别标签,为训练模型提供了必要的注解信息。VOC数据集源于对PASCAL挑战赛的贡献,涵盖多个物体类别,成为目标检测领域的重要基准之一,推动着算法性能的不断提升。

    使用labelimg标注或者其他VOC标注工具标注后,会得到两个文件夹,如下:

Annotations    ------->>>  存放.xml标注信息文件
JPEGImages     ------->>>  存放图片文件

在这里插入图片描述

2.划分VOC数据集

    如下代码是按照训练集:验证集 = 8:2来划分的,会找出没有对应.xml的图片文件,且划分的时候支持JPEGImages文件夹下有如下图片格式:

['.jpg', '.png', '.gif', '.bmp', '.tiff', '.jpeg', '.webp', '.svg', '.psd', '.cr2', '.nef', '.dng']

整体代码为:

import os
import random

image_extensions = ['.jpg', '.png', '.gif', '.bmp', '.tiff', '.jpeg', '.webp', '.svg', '.psd', '.cr2', '.nef', '.dng']


def split_voc_dataset(dataset_dir, train_ratio, val_ratio):
    if not (0 < train_ratio + val_ratio <= 1):
        print("Invalid ratio values. They should sum up to 1.")
        return

    annotations_dir = os.path.join(dataset_dir, 'Annotations')
    images_dir = os.path.join(dataset_dir, 'JPEGImages')
    output_dir = os.path.join(dataset_dir, 'ImageSets/Main')

    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    dict_info = dict()
    # List all the image files in the JPEGImages directory
    for file in os.listdir(images_dir):
        if any(ext in file for ext in image_extensions):
            jpg_files, endwith = os.path.splitext(file)
            dict_info[jpg_files] = endwith

    # List all the XML files in the Annotations directory
    xml_files = [file for file in os.listdir(annotations_dir) if file.endswith('.xml')]
    random.shuffle(xml_files)

    num_samples = len(xml_files)
    num_train = int(num_samples * train_ratio)
    num_val = int(num_samples * val_ratio)

    train_xml_files = xml_files[:num_train]
    val_xml_files = xml_files[num_train:num_train + num_val]

    with open(os.path.join(output_dir, 'train_list.txt'), 'w') as train_file:
        for xml_file in train_xml_files:
            image_name = os.path.splitext(xml_file)[0]
            if image_name in dict_info:
                image_path = os.path.join('JPEGImages', image_name + dict_info[image_name])
                annotation_path = os.path.join('Annotations', xml_file)
                train_file.write(f'{image_path} {annotation_path}\n')
            else:
                print(f"没有找到图片 {os.path.join(images_dir, image_name)}")

    with open(os.path.join(output_dir, 'val_list.txt'), 'w') as val_file:
        for xml_file in val_xml_files:
            image_name = os.path.splitext(xml_file)[0]
            if image_name in dict_info:
                image_path = os.path.join('JPEGImages', image_name + dict_info[image_name])
                annotation_path = os.path.join('Annotations', xml_file)
                val_file.write(f'{image_path} {annotation_path}\n')
            else:
                print(f"没有找到图片 {os.path.join(images_dir, image_name)}")

    labels = set()
    for xml_file in xml_files:
        annotation_path = os.path.join(annotations_dir, xml_file)
        with open(annotation_path, 'r') as f:
            lines = f.readlines()
            for line in lines:
                if '<name>' in line:
                    label = line.strip().replace('<name>', '').replace('</name>', '')
                    labels.add(label)

    with open(os.path.join(output_dir, 'labels.txt'), 'w') as labels_file:
        for label in labels:
            labels_file.write(f'{label}\n')


if __name__ == "__main__":
    dataset_dir = 'BirdNest/'
    train_ratio = 0.8  # Adjust the train-validation split ratio as needed
    val_ratio = 0.2
    split_voc_dataset(dataset_dir, train_ratio, val_ratio)


划分好后的截图:
在这里插入图片描述

3.VOC转COCO格式

目前很多框架大多支持的是COCO格式,因为存放与使用起来方便,采用了json文件来代替xml文件。

import json
import os
from xml.etree import ElementTree as ET


def parse_xml(dataset_dir, xml_file):
    xml_path = os.path.join(dataset_dir, xml_file)
    tree = ET.parse(xml_path)
    root = tree.getroot()

    objects = root.findall('object')
    annotations = []

    for obj in objects:
        bbox = obj.find('bndbox')
        xmin = int(bbox.find('xmin').text)
        ymin = int(bbox.find('ymin').text)
        xmax = int(bbox.find('xmax').text)
        ymax = int(bbox.find('ymax').text)

        # Extract label from XML annotation
        label = obj.find('name').text
        if not label:
            print(f"Label not found in XML annotation. Skipping annotation.")
            continue

        annotations.append({
            'xmin': xmin,
            'ymin': ymin,
            'xmax': xmax,
            'ymax': ymax,
            'label': label
        })

    return annotations


def convert_to_coco_format(image_list_file, annotations_dir, output_json_file, dataset_dir):
    images = []
    annotations = []
    categories = []

    # Load labels
    with open(os.path.join(os.path.dirname(image_list_file), 'labels.txt'), 'r') as labels_file:
        label_lines = labels_file.readlines()
        categories = [{'id': i + 1, 'name': label.strip()} for i, label in enumerate(label_lines)]

    # Load image list file
    with open(image_list_file, 'r') as image_list:
        image_lines = image_list.readlines()
        for i, line in enumerate(image_lines):
            image_path, annotation_path = line.strip().split(' ')
            image_id = i + 1
            image_filename = os.path.basename(image_path)

            images.append({
                'id': image_id,
                'file_name': image_filename,
                'height': 0,  # You need to fill in the actual height of the image
                'width': 0,  # You need to fill in the actual width of the image
                'license': None,
                'flickr_url': None,
                'coco_url': None,
                'date_captured': None
            })

            # Load annotations from XML files
            xml_annotations = parse_xml(dataset_dir, annotation_path)
            for xml_annotation in xml_annotations:
                label = xml_annotation['label']
                category_id = next((cat['id'] for cat in categories if cat['name'] == label), None)
                if category_id is None:
                    print(f"Label '{label}' not found in categories. Skipping annotation.")
                    continue

                bbox = {
                    'xmin': xml_annotation['xmin'],
                    'ymin': xml_annotation['ymin'],
                    'xmax': xml_annotation['xmax'],
                    'ymax': xml_annotation['ymax']
                }

                annotations.append({
                    'id': len(annotations) + 1,
                    'image_id': image_id,
                    'category_id': category_id,
                    'bbox': [bbox['xmin'], bbox['ymin'], bbox['xmax'] - bbox['xmin'], bbox['ymax'] - bbox['ymin']],
                    'area': (bbox['xmax'] - bbox['xmin']) * (bbox['ymax'] - bbox['ymin']),
                    'segmentation': [],
                    'iscrowd': 0
                })

    coco_data = {
        'images': images,
        'annotations': annotations,
        'categories': categories
    }

    with open(output_json_file, 'w') as json_file:
        json.dump(coco_data, json_file, indent=4)


if __name__ == "__main__":
    # 根据需要调整路径
    dataset_dir = 'BirdNest/'
    image_sets_dir = 'BirdNest/ImageSets/Main/'
    train_list_file = os.path.join(image_sets_dir, 'train_list.txt')
    val_list_file = os.path.join(image_sets_dir, 'val_list.txt')
    output_train_json_file = os.path.join(dataset_dir, 'train_coco.json')
    output_val_json_file = os.path.join(dataset_dir, 'val_coco.json')

    convert_to_coco_format(train_list_file, image_sets_dir, output_train_json_file, dataset_dir)
    convert_to_coco_format(val_list_file, image_sets_dir, output_val_json_file, dataset_dir)
    print("The json file has been successfully generated!!!")

转COCO格式成功截图:
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/126987.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【2021研电赛】管道巡检机器人

本作品介绍参与极术社区的有奖征集|分享研电赛作品扩大影响力&#xff0c;更有重磅电子产品免费领取! 团队介绍 参赛单位&#xff1a;广西科技大学 参赛队伍&#xff1a;OMEN 参赛队员&#xff1a;吴海晨 陈永亮 乔亚坤 第1章 项目意义 1.1 研究背景及意义 据媒体报道&am…

Linux学习笔记之五(父子进程、孤儿进程、僵尸进程、守护进程)

Linux 1、进程1.1、进程的六种状态1.2、创建子进程1.3、添加子进程任务1.4、孤儿进程、僵尸进程、守护进程1.4.1、避免僵尸进程1.4.2、创建守护进程1.4.3、杀死守护进程 1.5、综合练习 1、进程 进程可以简单的理解为一个正在执行的程序&#xff0c;它是计算机系统中拥有资源和…

Ionic 组件 ion-item-divider ion-item-group ion-item-sliding ion-label ion-note

1 ion-item-divider Item dividers是块元素&#xff0c;可用于分隔列表中的items 。它们类似于列表标题&#xff0c;但它们不应该只放在列表的顶部&#xff0c;而应该放在items之间。 <ion-list><ion-item-group><ion-item-divider><ion-label> Secti…

使用小程序插件【用户信息功能页】获取用户昵称、头像、openid

摘要 因为获取用户信息的接口 wx.getUserInfo 存在滥用&#xff0c;使用不规范等原因&#xff0c;微信官方已经将这个接口权限回收&#xff0c;改为用户信息填写&#xff0c;即引导用户主动填写微信昵称和上传头像。这种做法确实是麻烦了点。 但是微信小程序插件&#xff0c;…

浏览器标签页之间的通信

前言 在开发管理后台页面的时候&#xff0c;会遇到这样一种需求&#xff1a;有一个列表页面&#xff0c;一个新增按钮&#xff0c;一个新增页面&#xff0c;点击新增按钮&#xff0c;在一个新的标签页中打开新增页面。并且&#xff0c;新增后要自动实时的更新列表页面的数据。…

机器学习概论

目录 一、机器学习概述 1、机器学习与人工智能、深度学习的关系 2、机器学习的范围 3、机器学习可以解决什么问题 给定数据的预测问题&#xff1a; 二、机器学习的类型 1、监督学习 分类&#xff08;Classification&#xff09; 回归&#xff08;Regression、Prediction&am…

Vue知识点总结

路由 使用 参数传递的两种方式 路由的params传参 路由的query传参 组件 概念 局部功能代码&#xff08;html、css js&#xff09;和资源(mp3 mp4 ttf .zip)的集合 非单文件组件 一个文件对应多个组件&#xff0c;以html结尾 使用 <xuexiao>即可使用 注意&#xf…

MySQL字符串需要注意的事项

char(N)&#xff0c;N在0-255间 varchar(N)&#xff0c;N在0-65536间 需要注意N是字符&#xff0c;不是字节&#xff0c;英文字母一个字符一个字节&#xff0c;阿拉伯字母一个字符两个字节&#xff0c;中文日文一个字符三个字节&#xff0c;emoji是一个字符四个字节 当今移动端…

arcgis 批量删除Table中的某些Field

当shp或者table文件较少时&#xff0c;可以手动删除每个文件中的某些字段&#xff0c;当文件较多时&#xff0c;就需要使用arcpy或者model进行处理。

SUB-1G芯片---PAN3031低功耗远距离无线收发芯片

PAN3031 是一款采用 ChirpIoT TM 调制解调技术的低功耗远距离无线收发芯片&#xff0c;支持半双工无线通信&#xff0c;工作频段为 370~590 MHz 和 740~1180MHz&#xff0c;该芯片具有高抗干扰性、高灵敏度、低功耗和超远传输距离等特性。最高具有-129dBm 的灵敏度&#xff0c;…

文件夹找不到了怎么恢复?4个正确恢复方法分享!

“我在电脑上保存了很多的文件和文件夹&#xff0c;今天在查找文件时&#xff0c;发现我有一整个文件夹都消失了&#xff0c;不知道怎么才能找到呢。有朋友可以帮帮忙吗&#xff1f;” 电脑中文件夹突然找不到了可能会引发焦虑&#xff0c;尤其是如果这些文件夹包含重要的数据。…

[工业自动化-6]:西门子S7-15xxx编程 - PLC系统硬件组成与架构

目录 一、PLC系统组成 1.1 PLC 单机系统组成 1.2 PLC 分布式系统 二、PLC各个组件 2.1 PLC上位机 2.2 PLC主站&#xff1a;PLC CPU控制中心 &#xff08;1&#xff09;主要功能 &#xff08;2&#xff09;主站组成 2.3 PLC分布式从站: IO模块的拉远 &#xff08;1&am…

拖拽式能源管理平台,轻松掌握能源情况!

随着科技的进步&#xff0c;能源问题变得日益紧迫。为了提高能源利用效率&#xff0c;减少浪费&#xff0c;各能源使用企业开始重视能源管理&#xff0c;并寻求高效的节能工具来协助管理。因此&#xff0c;智慧能源管理平台应运而生&#xff0c;为能源使用企业提供强大的节能管…

C++ Qt 学习(五):Qt Web 编程

1. Chrome 技术介绍 大多数 web 技术都是基于 chrome&#xff0c;例如 CEF、QCefView 以及 QWebEngineView&#xff0c;这些都是在 native 界面里用来显示 html 网页&#xff0c;并且可以与 web 交互 例如常见的登录窗口、优酷的视频区域、WPS 的稻壳商城等&#xff0c;这些都…

拓世科技集团打造数字人营销解决方案,为车企提供新的“增长担当”

汽车&#xff0c;已经渐渐融入了现代人的日常生活&#xff0c;从高端的身份标志转变为普罗大众的出行选择&#xff0c;它驶入了千家万户&#xff0c;成为了我们日常出行的可靠伙伴&#xff0c;见证着人们的生活故事和时代的变迁。 中国汽车市场的蓬勃发展引起了业内外的广泛关…

ES|QL(Elasticsearch 查询语言)入门

作者&#xff1a;Ninoslav Miskovic 通过使用 ES|QL 直接从 Discover 创建聚合、可视化和警报&#xff0c;缩短获得见解的时间。 什么是 ES|QL&#xff08;Elasticsearch 查询语言&#xff09;&#xff1f; ES|QL&#xff08;Elasticsearch 查询语言&#xff09;是 Elastic 全…

掌握互联网的未来:5G时代的新机遇

随着5G技术的快速发展&#xff0c;我们正步入一个全新的互联网时代。5G不仅仅是速度的飞跃&#xff0c;它还代表着无限的可能性和前所未有的创新机遇。本文将探讨5G如何重新定义互联网&#xff0c;并为您提供洞察如何抓住这波科技浪潮。 5G技术的核心优势 超高速度&#xff1a…

Python 3D建模指南【numpy-stl | pymesh | pytorch3d | solidpython | pyvista】

想象一下&#xff0c;我们需要用 python 编程语言构建某个对象的三维模型&#xff0c;然后将其可视化&#xff0c;或者准备一个文件以便在 3D 打印机上打印。 有几个库可以解决这些问题。 让我们看一下如何在 python 中从点、边和图元构建 3D 模型。 如何执行基本 3D 建模技术&…

人车实时精准管控!北斗让换流站作业更安全

换流站是高压直流输电系统的核心组成部分&#xff0c;对促进电网稳定运行、保障电力行业的可持续发展有着重要作用。长期以来&#xff0c;随着电网主变改扩建设工程的开展&#xff0c;站内作业人员安全管控压力随之增大&#xff0c;仅依靠传统的“人盯人”和“自主”管控模式较…

CLion配置libtorch找不到xxx.dll

项目场景&#xff1a; 使用CLion配置libtorch时遇到该问题 问题描述 使用CLion配置libtorch时&#xff0c;CMakeLists.txt文件写完后&#xff0c;cmake也能成功&#xff0c;但是一旦运行代码就会报错找不到xxx.dll&#xff0c;比如找不到torch_cuda.dll或找不到c10.dll 原因分…