【数据集转换】VOC数据集转COCO数据集·代码实现+操作步骤

在自己的数据集上实验时,往往需要将VOC数据集转化为coco数据集,因为这种需求所以才记录这篇文章,代码出处未知,感谢开源。

在远程服务器上测试目标检测算法需要用到测试集,最常用的是coco2014/2017和voc07/12数据集。


coco数据集的地址为http://cocodataset.org/#download
voc和coco的镜像为https://pjreddie.com/projects/pascal-voc-dataset-mirror/

一、数据集格式对比

1.1 VOC数据集

VOC_ROOT     #根目录├── JPEGImages         # 存放源图,(当然图片并不一定要是**.jpg格式的,只是规定文件夹名字叫JPEGImages**);│     ├── aaaa.jpg     │     ├── bbbb.jpg  │     └── cccc.jpg├── Annotations        # 存放xml文件,VOC的标注是xml格式,与JPEGImages中的图片一一对应│     ├── aaaa.xml │     ├── bbbb.xml │     └── cccc.xml └── ImageSets          └── Main├── train.txt    # txt文件中每一行包含一个图片的名称└── val.txt

1.2 COCO数据集

COCO_ROOT     #根目录├── annotations        # 存放json格式的标注│     ├── instances_train2017.json   │     └── instances_val2017.json└── train2017         # 存放图片文件│     ├── 000000000001.jpg │     ├── 000000000002.jpg │     └── 000000000003.jpg └── val2017        ├── 000000000004.jpg └── 000000000005.jpg 

1.2.3 json标注格式

VOC一个文件一个xml标注不同,COCO所有的目标框标注都是放在一个json文件中的。
这个json文件解析出来是一个字典,格式如下:

{"info": info, "images": [image], "annotations": [annotation], "categories": [categories],"licenses": [license],
}

二、转换步骤

2.1 程序总体目录

 2.2  标签文件转换代码实现(xml文件转json格式)VOC_To_CoCo_01.py

这里需要运行三次,因为train.txt val.txt test.txt是三个文件,具体看注释

# VOC_To_CoCo_01.pyimport os
import argparse
import json
import xml.etree.ElementTree as ET
from typing import Dict, List
import redef get_label2id(labels_path: str) -> Dict[str, int]:"""id is 1 start"""with open(labels_path, 'r') as f:labels_str = f.read().split()labels_ids = list(range(1, len(labels_str) + 1))return dict(zip(labels_str, labels_ids))def get_annpaths(ann_dir_path: str = None,ann_ids_path: str = None,ext: str = '',annpaths_list_path: str = None) -> List[str]:# If use annotation paths listif annpaths_list_path is not None:with open(annpaths_list_path, 'r') as f:ann_paths = f.read().split()return ann_paths# If use annotaion ids listext_with_dot = '.' + ext if ext != '' else ''with open(ann_ids_path, 'r') as f:ann_ids = f.read().split()ann_paths = [os.path.join(ann_dir_path, aid + ext_with_dot) for aid in ann_ids]return ann_pathsdef get_image_info(annotation_root, extract_num_from_imgid=True):path = annotation_root.findtext('path')if path is None:filename = annotation_root.findtext('filename')else:filename = os.path.basename(path)img_name = os.path.basename(filename)img_id = os.path.splitext(img_name)[0]if extract_num_from_imgid and isinstance(img_id, str):img_id = int(re.findall(r'\d+', img_id)[0])size = annotation_root.find('size')width = int(size.findtext('width'))height = int(size.findtext('height'))image_info = {'file_name': filename,'height': height,'width': width,'id': img_id}return image_infodef get_coco_annotation_from_obj(obj, label2id):label = obj.findtext('name')assert label in label2id, f"Error: {label} is not in label2id !"category_id = label2id[label]bndbox = obj.find('bndbox')xmin = int(bndbox.findtext('xmin')) - 1ymin = int(bndbox.findtext('ymin')) - 1xmax = int(bndbox.findtext('xmax'))ymax = int(bndbox.findtext('ymax'))assert xmax > xmin and ymax > ymin, f"Box size error !: (xmin, ymin, xmax, ymax): {xmin, ymin, xmax, ymax}"o_width = xmax - xmino_height = ymax - yminann = {'area': o_width * o_height,'iscrowd': 0,'bbox': [xmin, ymin, o_width, o_height],'category_id': category_id,'ignore': 0,'segmentation': []  # This script is not for segmentation}return anndef convert_xmls_to_cocojson(annotation_paths: List[str],label2id: Dict[str, int],output_jsonpath: str,extract_num_from_imgid: bool = True):output_json_dict = {"images": [],"type": "instances","annotations": [],"categories": []}bnd_id = 1  # START_BOUNDING_BOX_ID, TODO input as args ?for a_path in annotation_paths:# Read annotation xmlann_tree = ET.parse(a_path)ann_root = ann_tree.getroot()img_info = get_image_info(annotation_root=ann_root,extract_num_from_imgid=extract_num_from_imgid)img_id = img_info['id']output_json_dict['images'].append(img_info)for obj in ann_root.findall('object'):ann = get_coco_annotation_from_obj(obj=obj, label2id=label2id)ann.update({'image_id': img_id, 'id': bnd_id})output_json_dict['annotations'].append(ann)bnd_id = bnd_id + 1for label, label_id in label2id.items():category_info = {'supercategory': 'none', 'id': label_id, 'name': label}output_json_dict['categories'].append(category_info)with open(output_jsonpath, 'w') as f:output_json = json.dumps(output_json_dict)f.write(output_json)print('Convert successfully !')def main():parser = argparse.ArgumentParser(description='This script support converting voc format xmls to coco format json')parser.add_argument('--ann_dir', type=str, default='./VOCdevkit/Annotations')parser.add_argument('--ann_ids', type=str, default='./VOCdevkit/ImageSets/Main/val.txt') # 这里修改 train val test 一共修改三次#parser.add_argument('--ann_ids', type=str, default='./VOCdevkit/ImageSets/Main/train.txt')#parser.add_argument('--ann_ids', type=str, default='./VOCdevkit/ImageSets/Main/test.txt')parser.add_argument('--ann_paths_list', type=str, default=None)parser.add_argument('--labels', type=str, default='./VOCdevkit/labels.txt')parser.add_argument('--output', type=str, default='./output/annotations/val.json') # 这里修改 train val test 一共修改三次#parser.add_argument('--output', type=str, default='./output/annotations/train.json')#parser.add_argument('--output', type=str, default='./output/annotations/test.json')parser.add_argument('--ext', type=str, default='xml')args = parser.parse_args()label2id = get_label2id(labels_path=args.labels)ann_paths = get_annpaths(ann_dir_path=args.ann_dir,ann_ids_path=args.ann_ids,ext=args.ext,annpaths_list_path=args.ann_paths_list)convert_xmls_to_cocojson(annotation_paths=ann_paths,label2id=label2id,output_jsonpath=args.output,extract_num_from_imgid=True)if __name__ == '__main__':if not os.path.exists('./output/annotations'):os.makedirs('./output/annotations')main()

2.3 数据集图像文件copy代码实现(复制图片数据集到coco中)VOC_To_CoCo_02.py

# VOC_To_CoCo_02.pyimport os
import shutilimages_file_path = './VOCdevkit/JPEGImages/'
split_data_file_path = './VOCdevkit/ImageSets/Main/'
new_images_file_path = './output/'if not os.path.exists(new_images_file_path + 'train'):os.makedirs(new_images_file_path + 'train')
if not os.path.exists(new_images_file_path + 'val'):os.makedirs(new_images_file_path + 'val')
if not os.path.exists(new_images_file_path + 'test'):os.makedirs(new_images_file_path + 'test')dst_train_Image = new_images_file_path + 'train/'
dst_val_Image = new_images_file_path + 'val/'
dst_test_Image = new_images_file_path + 'test/'total_txt = os.listdir(split_data_file_path)
for i in total_txt:name = i[:-4]if name == 'train':txt_file = open(split_data_file_path + i, 'r')for line in txt_file:line = line.strip('\n')line = line.strip('\r')srcImage = images_file_path + line + '.jpg'dstImage = dst_train_Image + line + '.jpg'shutil.copyfile(srcImage, dstImage)txt_file.close()elif name == 'val':txt_file = open(split_data_file_path + i, 'r')for line in txt_file:line = line.strip('\n')line = line.strip('\r')srcImage = images_file_path + line + '.jpg'dstImage = dst_val_Image + line + '.jpg'shutil.copyfile(srcImage, dstImage)txt_file.close()elif name == 'test':txt_file = open(split_data_file_path + i, 'r')for line in txt_file:line = line.strip('\n')line = line.strip('\r')srcImage = images_file_path + line + '.jpg'dstImage = dst_test_Image + line + '.jpg'shutil.copyfile(srcImage, dstImage)txt_file.close()else:print("Error, Please check the file name of folder")

三、效果展示

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idea spring tomcat启动失败_技术篇 | 实用IDEA插件和工具系列

前 言本章主要分享一些工作中常用的IDEA插件(Maven Helper、Lombok、Mybatis Log Plugin、RestfulToolkit、JRebel And XRebel)和实用工具arthas。01Maven Helper作用:能清晰的查看当项目的Maven依赖版本、依赖关系、依赖冲突等情况。使用步骤:①安装后,…

【数据集可视化】VOC数据集标注可视化+代码实现

二、VOC可视化数据集 1、作用 在做目标检测时,首先要检查标注数据。一方面是要了解标注的情况,另一方面是检查数据集的标注和格式是否正确,只有正确的情况下才能进行下一步的训练。 2、代码实现 import os # import sys import cv2 import…

串口UART串行总线协议

串口UART 串行端口是异步的(不传输时钟相关数据),两个设备在使用串口通信时,必须先约定一个数据传输速率,并且这两个设备各自的时钟频率必须与这个速率保持相近,某一方的时钟频率相差很大都会导致数据传输…

基于Springboot外卖系统01:技术构成+功能模块介绍

外卖系统是专门为餐饮企业(餐厅、饭店)定制的一款软件产品,包括 系统管理后台 和 移动端应用 两部分。其中系统管理后台主要提供给餐饮企业内部员工使用,可以对餐厅的分类、菜品、套餐、订单、员工等进行管理维护。移动端应用主要…

HTML5本地图片裁剪并上传

最近做了一个项目,这个项目中需要实现的一个功能是:用户自定义头像(用户在本地选择一张图片,在本地将图片裁剪成满足系统要求尺寸的大小)。这个功能的需求是:头像最初剪切为一个正方形。如果选择的图片小于…

嵌入式就应该这样学!!

嵌入式就应该这样学!! 1、Linux内核 Linux 内核定时器 Linux进程上下文和中断上下文内核空间和用户空间 Linux内核链表 Linux 内核模块编译 Linux内核使用Gdb调试 Linux动态打印kernel日志 Linux的中断可以嵌套吗 Linux内核定时器 Linux 驱动之Ioctl Lin…

基于Springboot外卖系统02:数据库搭建+Maven仓库搭建

1 数据库环境搭建 1.1 创建数据库 可以通过以下两种方式中的任意一种, 来创建项目的数据库: 1).图形界面 注意: 本项目数据库的字符串, 选择 utf8mb4 2).命令行 1.2 数据库表导入 项目的数据库创建好了之后, 可以直接将 资料/数据模型/db_reggie.sql 直接导入到数据库中, …

margin 负边距应用

margin-right:负值&#xff0c;在没有设置DOM元素宽度的前提下&#xff0c;DOM元素宽度变宽。 1 <!DOCTYPE html>2 <html lang"zh-CN">3 4 <head>5 <meta charset"UTF-8">6 <meta http-equiv"X-UA-Co…

基于Springboot外卖系统03:pom.xml导入依赖+数据库配置文件+Boot启动类+静态资源映射

1).在pom.xml中导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache…

写给过得很辛苦很迷茫的你~一定要看啊

#前面的话 我是一个农村的孩子&#xff0c;我家很穷&#xff0c;小时候过得非常苦&#xff0c;每次开学是我最害怕的时候&#xff0c;我害怕我爸妈拿不出学费&#xff0c;我害怕我爸妈会让我辍学在家帮忙干活&#xff0c;每次跟我妈吵架的时候&#xff0c;当我妈跟我说不让我读…

flatpickr功能强大的日期时间选择器插件

flatpickr日期时间选择器支持移动手机&#xff0c;提供多种内置的主题效果&#xff0c;并且提供对中文的支持。它的特点还有&#xff1a; 使用SVG作为界面的图标。 兼容jQuery。 支持对各种日期格式的解析。 轻量级&#xff0c;高性能&#xff0c;压缩后的版本仅6K大小。 对…

基于Springboot外卖系统04:后台系统用户登录+登出功能

登录业务流程 ① 在登录页面输入用户名和密码 ② 调用后台接口进行验证 ③ 通过验证之后&#xff0c;根据后台的响应状态跳转到项目主页 2. 登录业务的相关技术点 http 是无状态的通过 cookie 在客户端记录状态通过 session 在服务器端记录状态通过 token 方式维持状态如果前端…

排序算法时间复杂度、空间复杂度、稳定性比较

排序算法分类 排序算法比较表格填空 排序算法平均时间复杂度最坏时间复杂度空间复杂度是否稳定冒泡排序:————-::—–::—–::—–:选择排序:————-::—–::—–::—–:直接插入排序:————-::—–::—–::—–:归并排序:————-::—–::—–::—–:快速排序:———…

基于Springboot外卖系统05:用户非登陆状态的页面拦截器实现

1. 完善登录功能 1.1 问题分析 用户访问接口验证&#xff0c;如果用户没有登录&#xff0c;则不让他访问除登录外的任何接口。 1.前端登录&#xff0c;后端创建session&#xff0c;返给前端 2.前端访问其他接口&#xff0c;失效或不存在&#xff0c;则返回失效提示&#xff…

python删除指定行_关于csv:删除python中的特定行和对应文件

我想删除90%的"转向"值等于0的行。这三个图像都有一个对应的图像文件&#xff0c;中间&#xff0c;左边和右边。我也要删除它们。csv文件如下&#xff1a;我编写了以下代码&#xff0c;以至少获取转向值为0的文件。我所需要的就是随机获取90%的文件并删除它们的代码。…

I2C总线传输协议

简介 I2C&#xff08;Inter-integrated Circuit&#xff09;总线支持设备之间的短距离通信&#xff0c;用于处理器和一些外围设备之间的接口&#xff0c;它只需要两根信号线来完成信息交换。I2C最早是飞利浦在1982年开发设计并用于自己的芯片上&#xff0c;一开始只允许100kHz…

基于Springboot外卖系统06: 新增员工功能+全局异常处理器

2. 新增员工 2.1 需求分析 后台系统中可以管理员工信息&#xff0c;通过新增员工来添加后台系统用户。点击[添加员工]按钮跳转到新增页面&#xff0c;如下 当填写完表单信息, 点击"保存"按钮后, 会提交该表单的数据到服务端, 在服务端中需要接受数据, 然后将数据保…

spring aop实现原理_Spring 异步实现原理与实战分享

最近因为全链路压测项目需要对用户自定义线程池 Bean 进行适配工作&#xff0c;我们知道全链路压测的核心思想是对流量压测进行标记&#xff0c;因此我们需要给压测的流量请求进行打标&#xff0c;并在链路中进行传递&#xff0c;那么问题来了&#xff0c;如果项目中使用了多线…

基于Springboot外卖系统07:员工分页查询+ 分页插件配置+分页代码实现

1. 员工分页查询 1.1 需求分析 在分页查询页面中, 以分页的方式来展示列表数据&#xff0c;以及查询条件 "员工姓名"。 请求参数 搜索条件&#xff1a; 员工姓名(模糊查询) 分页条件&#xff1a; 每页展示条数 &#xff0c; 页码 响应数据 总记录数 结果列表 1…

1045-Access denied for user 'root'@'localhost'(using password:YES)

解决&#xff1a; 1. 开始 --> cmd --> net stop mysql (停用MySQL服务 没启动的可以省略) 2. 找到安装路径 MySQL Server 5.1下的my.ini 3. 打开 my.ini 找到 [mysqld] 然后在下面加上 这句&#xff1a; skip_grant_tables &#xff08;意思好像是 启动MySQL服务…