VOC数据集格式转化成COCO数据集格式

                  VOC数据集格式转化成COCO数据集格式
一、唠叨
     之前写过一篇关于coco数据集转化成VOC格式的博客COCO2VOC,最近读到CenterNet的官方代码,实现上则是将voc转化成coco数据格式,这样的操作我个人感觉很不习惯,也觉得有些奇葩,可能是每个人习惯不一样吧,我们知道有时候我们会采用labelImg标注数据,标注出来的格式就是voc,如果直接训练就可以用来训练是不是更加友好。

     为了不大规模修改原始训练代码(虽然自己修改了一个版本的voc数据集就能直接训练centernet 😊),同时也看到网上很多大佬也做了将VOC数据格式转化成COCO用于其训练,这里我自己做一个精细一点的,作为笔记。

二、转化过程
   数据格式的转换实际是annotation标注文件的转化,voc的数据标注文件为以.xml结尾的文件,而且每张图片均有一个对应的同名标注文件;COCO则是将所有的标注信息写在一个json文件中。VOC数据集目录如下:

    在之前的coco2voc博客中做了详细的介绍,现在直接开始转化,目标就是将Annotations中的所有标注文件中的bbox标注信息转化为json文件,根据训练集和测试集,则主要转化为四个json文件,分别是test.json、train.json、val.json和trainval.json .这里我根据ImageSets中的train.txt val.txt trainval.txt生成后三个json文件,当然也可以直接从Annotations文件夹生成。

VOC2COCO.pyimport xml.etree.ElementTree as ET
import os
import jsoncoco = dict()
coco['images'] = []
coco['type'] = 'instances'
coco['annotations'] = []
coco['categories'] = []category_set = dict()
image_set = set()category_item_id = -1
image_id = 20180000000
annotation_id = 0def addCatItem(name):global category_item_idcategory_item = dict()category_item['supercategory'] = 'none'category_item_id += 1category_item['id'] = category_item_idcategory_item['name'] = namecoco['categories'].append(category_item)category_set[name] = category_item_idreturn category_item_iddef addImgItem(file_name, size):global image_idif file_name is None:raise Exception('Could not find filename tag in xml file.')if size['width'] is None:raise Exception('Could not find width tag in xml file.')if size['height'] is None:raise Exception('Could not find height tag in xml file.')image_id += 1image_item = dict()image_item['id'] = image_idimage_item['file_name'] = file_nameimage_item['width'] = size['width']image_item['height'] = size['height']coco['images'].append(image_item)image_set.add(file_name)return image_iddef addAnnoItem(object_name, image_id, category_id, bbox):global annotation_idannotation_item = dict()annotation_item['segmentation'] = []seg = []# bbox[] is x,y,w,h# left_topseg.append(bbox[0])seg.append(bbox[1])# left_bottomseg.append(bbox[0])seg.append(bbox[1] + bbox[3])# right_bottomseg.append(bbox[0] + bbox[2])seg.append(bbox[1] + bbox[3])# right_topseg.append(bbox[0] + bbox[2])seg.append(bbox[1])annotation_item['segmentation'].append(seg)annotation_item['area'] = bbox[2] * bbox[3]annotation_item['iscrowd'] = 0annotation_item['ignore'] = 0annotation_item['image_id'] = image_idannotation_item['bbox'] = bboxannotation_item['category_id'] = category_idannotation_id += 1annotation_item['id'] = annotation_idcoco['annotations'].append(annotation_item)def _read_image_ids(image_sets_file):ids = []with open(image_sets_file) as f:for line in f:ids.append(line.rstrip())return ids"""通过txt文件生成"""
#split ='train' 'va' 'trainval' 'test'
def parseXmlFiles_by_txt(data_dir,json_save_path,split='train'):print("hello")labelfile=split+".txt"image_sets_file = data_dir + "/ImageSets/Main/"+labelfileids=_read_image_ids(image_sets_file)for _id in ids:xml_file=data_dir + f"/Annotations/{_id}.xml"bndbox = dict()size = dict()current_image_id = Nonecurrent_category_id = Nonefile_name = Nonesize['width'] = Nonesize['height'] = Nonesize['depth'] = Nonetree = ET.parse(xml_file)root = tree.getroot()if root.tag != 'annotation':raise Exception('pascal voc xml root element should be annotation, rather than {}'.format(root.tag))# elem is <folder>, <filename>, <size>, <object>for elem in root:current_parent = elem.tagcurrent_sub = Noneobject_name = Noneif elem.tag == 'folder':continueif elem.tag == 'filename':file_name = elem.textif file_name in category_set:raise Exception('file_name duplicated')# add img item only after parse <size> tagelif current_image_id is None and file_name is not None and size['width'] is not None:if file_name not in image_set:current_image_id = addImgItem(file_name, size)print('add image with {} and {}'.format(file_name, size))else:raise Exception('duplicated image: {}'.format(file_name))# subelem is <width>, <height>, <depth>, <name>, <bndbox>for subelem in elem:bndbox['xmin'] = Nonebndbox['xmax'] = Nonebndbox['ymin'] = Nonebndbox['ymax'] = Nonecurrent_sub = subelem.tagif current_parent == 'object' and subelem.tag == 'name':object_name = subelem.textif object_name not in category_set:current_category_id = addCatItem(object_name)else:current_category_id = category_set[object_name]elif current_parent == 'size':if size[subelem.tag] is not None:raise Exception('xml structure broken at size tag.')size[subelem.tag] = int(subelem.text)# option is <xmin>, <ymin>, <xmax>, <ymax>, when subelem is <bndbox>for option in subelem:if current_sub == 'bndbox':if bndbox[option.tag] is not None:raise Exception('xml structure corrupted at bndbox tag.')bndbox[option.tag] = int(option.text)# only after parse the <object> tagif bndbox['xmin'] is not None:if object_name is None:raise Exception('xml structure broken at bndbox tag')if current_image_id is None:raise Exception('xml structure broken at bndbox tag')if current_category_id is None:raise Exception('xml structure broken at bndbox tag')bbox = []# xbbox.append(bndbox['xmin'])# ybbox.append(bndbox['ymin'])# wbbox.append(bndbox['xmax'] - bndbox['xmin'])# hbbox.append(bndbox['ymax'] - bndbox['ymin'])print('add annotation with {},{},{},{}'.format(object_name, current_image_id, current_category_id,bbox))addAnnoItem(object_name, current_image_id, current_category_id, bbox)json.dump(coco, open(json_save_path, 'w'))"""直接从xml文件夹中生成"""
def parseXmlFiles(xml_path,json_save_path):for f in os.listdir(xml_path):if not f.endswith('.xml'):continuebndbox = dict()size = dict()current_image_id = Nonecurrent_category_id = Nonefile_name = Nonesize['width'] = Nonesize['height'] = Nonesize['depth'] = Nonexml_file = os.path.join(xml_path, f)print(xml_file)tree = ET.parse(xml_file)root = tree.getroot()if root.tag != 'annotation':raise Exception('pascal voc xml root element should be annotation, rather than {}'.format(root.tag))# elem is <folder>, <filename>, <size>, <object>for elem in root:current_parent = elem.tagcurrent_sub = Noneobject_name = Noneif elem.tag == 'folder':continueif elem.tag == 'filename':file_name = elem.textif file_name in category_set:raise Exception('file_name duplicated')# add img item only after parse <size> tagelif current_image_id is None and file_name is not None and size['width'] is not None:if file_name not in image_set:current_image_id = addImgItem(file_name, size)print('add image with {} and {}'.format(file_name, size))else:raise Exception('duplicated image: {}'.format(file_name))# subelem is <width>, <height>, <depth>, <name>, <bndbox>for subelem in elem:bndbox['xmin'] = Nonebndbox['xmax'] = Nonebndbox['ymin'] = Nonebndbox['ymax'] = Nonecurrent_sub = subelem.tagif current_parent == 'object' and subelem.tag == 'name':object_name = subelem.textif object_name not in category_set:current_category_id = addCatItem(object_name)else:current_category_id = category_set[object_name]elif current_parent == 'size':if size[subelem.tag] is not None:raise Exception('xml structure broken at size tag.')size[subelem.tag] = int(subelem.text)# option is <xmin>, <ymin>, <xmax>, <ymax>, when subelem is <bndbox>for option in subelem:if current_sub == 'bndbox':if bndbox[option.tag] is not None:raise Exception('xml structure corrupted at bndbox tag.')bndbox[option.tag] = int(option.text)# only after parse the <object> tagif bndbox['xmin'] is not None:if object_name is None:raise Exception('xml structure broken at bndbox tag')if current_image_id is None:raise Exception('xml structure broken at bndbox tag')if current_category_id is None:raise Exception('xml structure broken at bndbox tag')bbox = []# xbbox.append(bndbox['xmin'])# ybbox.append(bndbox['ymin'])# wbbox.append(bndbox['xmax'] - bndbox['xmin'])# hbbox.append(bndbox['ymax'] - bndbox['ymin'])print('add annotation with {},{},{},{}'.format(object_name, current_image_id, current_category_id,bbox))addAnnoItem(object_name, current_image_id, current_category_id, bbox)json.dump(coco, open(json_save_path, 'w'))if __name__ == '__main__':#通过txt文件生成# voc_data_dir="E:/VOCdevkit/VOC2007"# json_save_path="E:/VOCdevkit/voc2007trainval.json"# parseXmlFiles_by_txt(voc_data_dir,json_save_path,"trainval")#通过文件夹生成ann_path="E:/VOCdevkit/VOC2007/Annotations"json_save_path="E:/VOCdevkit/test.json"parseXmlFiles(ann_path,json_save_path)

 生成之后就是这样:

到此就结束了,提供两个关键函数,一个是通过txt,另一个使用过文件夹,然后就可以用于centernet训练了,或者也可以用于其他的算法数据准备。

任何程序错误,以及技术疑问或需要解答的,请添加

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

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

相关文章

华为交换机S3700端口基本配置

1.配置AAA验证方式的用户名和密码(配置用户名admin,加密密码:admin@123,接入类型:telnet) 进入系统视图后 aaa local-user admin password cipher admin@123 local-user admin service-type telnet2.交换机配置端口为access方法 进入系统视图后 interface Ethernet0/0/2…

react native android6+拍照闪退或重启的解决方案

前言 android 6权限使用的时候需要动态申请&#xff0c;那么在使用rn的时候要怎么处理拍照权限问题呢&#xff1f;本文提供的是一揽子rn操作相册、拍照的解决方案&#xff0c;请看正文的提高班部分。 解决步骤 1、AndroidManifest.xml设置拍照权限&#xff1a; <uses-perm…

JavaScript中Object.keys、Object.getOwnPropertyNames区别

定义 Object.keys 定义&#xff1a;返回一个对象可枚举属性的字符串数组&#xff1b; Object.getOwnPropertyNames 定义&#xff1a;返回一个对象可枚举、不可枚举属性的名称&#xff1b; 属性的可枚举性、不可枚举性 定义&#xff1a;可枚举属性是指那些内部 “可枚举” …

yii框架cookie写入与读取方法

写入cookie: $cookie Yii::app()->request->getCookies(); unset($cookie[$name]); 读取cookie: $cookie Yii::app()->request->getCookies(); echo $cookie[mycookie]->value; 网站查询转载于:https://www.cnblogs.com/itxueba/p/3505979.html

华为交换机基本查询、目录、文件操作命令

1.基本查询命令(在用户视图下使用) pwd 查看当前目录 dir 显示当前目录下的文件信息 more 查看文本文件的具体内容 2.基本目录操作命令(在用户视图下使用) cd 切换目录 mkdir 创建新的目录 rmdir 删除目录 cd… 返回上级目录 3.基本文本操作命令(在用户视图下使用) cop…

学术论文SCI、期刊、毕业设计中的图表专用软件

Origin Origin是由OriginLab公司开发的一个科学绘图、数据分析软件&#xff0c;支持在Microsoft Windows下运行。Origin支持各种各样的2D/3D图形。Origin中的数据分析功能包括统计&#xff0c;信号处理&#xff0c;曲线拟合以及峰值分析。 Origin中的曲线拟合是采用基于Lever…

常用的学术论文图表(折线图、柱状图)matplotlib python代码模板

最终选用了pythonMatplotlib。Matplotlib是著名Python的标配画图包&#xff0c;其绘图函数的名字基本上与 Matlab 的绘图函数差不多。优点是曲线精致&#xff0c;软件开源免费&#xff0c;支持Latex公式插入&#xff0c;且许多时候只需要一行或几行代码就能搞定。 然后小编经过…

史上最详细nodejs版本管理器nvm的安装与使用(附注意事项和优化方案)

使用场景 在Node版本快速更新迭代的今天&#xff0c;新老项目使用的node版本号可能已经不相同了&#xff0c;node版本更新越来越快&#xff0c;项目越做越多&#xff0c;node切换版本号的需求越来越迫切&#xff0c;传统卸载一个版本在安装另一个版本的方式太过于麻烦&#xf…

华为交换机配置当前时区、日期和时间等参数

1.华为交换机时区设置 UTC和GMT 整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时(UTC, Universal Time Coordinated)。UTC与格林尼治平均时(GMT, Greenwich Mean Time)一样,都与英国伦敦的本地…

qtp:exit 函数

1、ExitAction() 退出当前操作&#xff0c;无论其本地&#xff08;操作&#xff09;循环属性是什么。2、ExitActionIteration() 退出操作的当前循环。3、ExitComponent()退出当前组件并继续业务流程测试中的下一个组件&#xff0c;无论组件的循环设置是什么。4、ExitComponentI…

【TensorFlow】 基于视频时序LSTM的行为动作识别

简介 本文基于LSTM来完成用户行为识别。数据集来源&#xff1a;https://archive.ics.uci.edu/ml/machine-learning-databases/00240/ 此数据集一共有6种行为状态&#xff1a; 行走&#xff1b; 站立&#xff1b; 躺下&#xff1b; 坐下&#xff1b; 上楼&#xff1b; 下楼&am…

javascript数组去重方法汇总

前言 数组去重已经是一个老生常谈的问题了&#xff0c;依然经久不息&#xff0c;经过岁月的变迁es标准的升级迭代&#xff0c;似乎有越来越多的方法和方式供我们使用&#xff0c;那么那种方式才是最优的&#xff1f;那种才是最简洁的&#xff1f;这个我们一起来探讨。 省略&am…

华为交换机认证aaa模式创建本地用户

在系统视图下 telnet server enable //enable选项开启Telnet服务 (普通系列一般为这个) user-interface vty 0 4 protocol inbound telnet //配置vty支持telnet协议 authentication-mode aaa user privilege level 15 aaa local-user admin password cipher admin@123 lo…

利用Asp.net MVC处理文件的上传下载

如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的&#xff0c;我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUpload就是其中一个&#xff0c;而这个控件的缺席给我们带来一些小问题。这篇文章主要说如何在Asp.net MVC中上传…

Python遍历文件夹下所有文件及目录

遍历文件夹中的所有子文件夹及子文件使用os.walk()方法非常简单。 语法格式大致如下&#xff1a; os.walk(top[, topdownTrue[, onerrorNone[, followlinksFalse]]]) top – 根目录下的每一个文件夹(包含它自己), 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文…

你必须知道的session与cookie

Session本质 提到Session我们能联想到的就是用户登录功能&#xff0c;而本身我们使用Session的基础是通过url进行访问的&#xff0c;也就是使用http协议进行访问的&#xff0c;而http协议本身是无状态的&#xff0c;那么问题来了服务器端是怎么验证客户端身份的&#xff1f; …

华为交换机telnet和ftp服务开启/关闭命令

1.telnet开启/关闭 在系统视图下 启用方式如下&#xff1a; telnet server enable //使能telnet服务关闭方式如下&#xff1a; undo telnet server //关闭telnet服务2.FTP开启/关闭 通过display ftp-server查看启用状态 如果已经启用&#xff0c;会在查看的命令中显示&#…

为什么用Spring来管理Hibernate?

为什么用Spring来管理Hibernate&#xff1f;为什么要用Hibernate框架&#xff1f;这个在《Hibernate介绍》博客中已经提到了。既然用Hibernate框架访问管理持久层&#xff0c;那为何又提到用Spring来管理以及整合Hibernate呢&#xff1f;首先我们来看一下Hibernate进行操作的步…

Python-Pandas之两个Dataframe的差异比较

昨天在外网找到一个比较dataframe的好库&#xff0c;叫datacompy&#xff0c;它的优点有&#xff1a; 1、可以把对比后的信息详情打印出来&#xff0c;比如列是否相等&#xff0c;行是否相等&#xff1b; 2、在数据中如果有不相等列&#xff0c;那么就只比较相同的列&#xf…

《JavaScript权威指南》——JavaScript核心

前言 这本由David Flanagan著作&#xff0c;并由淘宝前端团队译的《JavaScript权威指南》&#xff0c;也就是我们俗称的“犀牛书”&#xff0c;算是JS界公认的“圣经”了。本书较厚&#xff08;有1004页&#xff09;&#xff0c;读起来颇费功夫&#xff0c;但作为JavaScript&a…