首页 > 分享 > 将用LabelImg标注得到的VOC格式数据集标签(xml文件)转换成COCO格式(json文件)

将用LabelImg标注得到的VOC格式数据集标签(xml文件)转换成COCO格式(json文件)

写在前面的话
制作数据集和处理数据看似是体力活,但对于机器学习和深度学习应用而言是非常重要的,千万不能掉以轻心,要认真对待,及时检查。如果数据有问题或者没处理好,再好的模型也无济于事。

自从Facebook开源了Detectron目标检测框架后,很多原先用VOC格式数据集(指标注文件)训练目标检测模型的人需要将VOC格式的xml标注文件转换成COCO格式的json标注文件,但Detectron中并未提供VOC格式转json格式的官方代码,虽然cocoapi有提供转换好的COCO json格式的Pascal VOC文件以及VOC转COCO的MatlabAPI,但要想把自己用LabelImg标注得到的VOC格式标注文件转换成COCO格式还是要花一番功夫,我自己在转换的时候就遇到了不少问题,于是把过程记录下来,以做日后参考,也希望对有类似需求的朋友有所帮助。

平台环境:Ubuntu16.04

1 安装Matlab

如果电脑没有安装Matalb,需要先安装matlab,我安装的版本是matlab2014b,主要参考了这篇博客Ubuntu 16.04LTS安装MATLAB2014b简明指南,按照博客中的操作步骤来一般都能安装并激活成功,只是我最后的matlab环境变量设置出了问题,不过不影响使用,直接sudo /usr/local/MATLAB/R2014b/bin/matlab 就能成功启动matlab

2 调用cocoapi的MatlabAPI将VOC数据集标签转换为COCO数据集标签

主要参考了这篇博客使用自己的数据集(voc2007格式)训练Detectron

从github下载cocoapi,然后matlab新建脚本文件,并将cocoapi下MatlabAPI添加到路径或在matlab中直接将当前路径切换到MatlabAPI路径下。
matlab脚本如下:

mex('CXXFLAGS=$CXXFLAGS -std=c++11 -Wall','-largeArrayDims',... 'private/gasonMex.cpp','../common/gason.cpp',... '-I../common/','-outdir','private'); CocoUtils.convertPascalGt( 'D:/datasets', '2007', 'trainval', 'D:/datasets/pascal_trainval2007.json') CocoUtils.convertPascalGt( 'D:/datasets', '2007', 'test', 'D:/datasets/pascal_test2007.json')12345

上面脚本里面的 trainval和test对应的是包含相应图片名的txt文件,也就是类似Pascal VOC文件夹Annotations/Main下的文件。
convertPascalGT函数说明如下

% Convert ground truth for PASCAL to COCO format. % % USAGE % CocoUtils.convertPascalGt( dataDir, year, split, annFile ) % % INPUTS % dataDir - dir containing VOCdevkit/ % year - dataset year (e.g. '2007') % split - dataset split (e.g. 'val') % annFile - annotation file for writing results12345678910

在执行上面的matlab文件时,可能会遇到类似“未定义函数或变量’VOCinit’”的错误,这是因为在dataDir的VOCdevkit路径下可能少了VOCcode文件夹,该文件夹里面含有VOCinit.m文件,该文件夹可以从Pascal VOC的VOCdevkit文件夹中拷贝过来,但要让convertPascalGT函数能识别出自己数据集的目标检测类别时需要修改VOCinit.m文件中的VOCopts.classes变量,把里面的Pascal VOC类别换成自定义的类别标签。如下:

1. VOCopts.classes={... 2. '你的标签1' 3. '你的标签2' 4. '你的标签3' 5. '你的标签4'}; 123456

转换结束后,务必要查看一下生成的json文件里面的内容是否与预期的相符,我在检查的时候就发现里面的images字段的id都是”-nan”,对比原始Pascal VOC数据集的xml和自己数据集的xml文件后才发现自己数据集的xml文件中filename字段包含了非数字字符,也就是说我自己数据集的图片名并不是完全用数字编号的,而Pascal VOC数据集的图片均是用数字编号的,于是只得回过头来把自己数据集的所有xml标注文件都进行修改(参见第3部分)。修改完并检查无误后,把生成的json文件标签按照如下的文件夹结构放入到Annotations下,即可用于后续Detectron的模型训练。

VOC<year> //主文件夹可以起其它名字 |_ JPEGImages | |_ <im-1-name>.jpg | |_ ... | |_ <im-N-name>.jpg |_ Annotations | |_ pascal_trainval<year>.json | |_ ... |_ VOCdevkit<year>123456789

后续的用Detectron模型训练的过程可以参考我之前博客: Detectron研读和实践三:用faster_rcnn_R-50-FPN训练PASCAL VOC数据集 1.2节之后的内容,要注意的一点是如果想使用Pascal VOC的测评标准对在自己数据集上训练的模型进行测评的话,Detectron的dataset_catalog.py文件中的验证数据集名字要命名成和’voc_2007_val’或’voc_2012_val’一样的名字,否则测评器evaluator会识别不了。

3 批量修改Pascal VOC格式的xml标注文件

补充上一部分,我对xml文件的修改主要包括修改filename和folder字段、删除path字段,在修改xml文件的同时也把对应的图片名改掉了,批量修改xml建议使用xml.etree.ElementTree — The ElementTree XML API,另外部分参考了博客修改别人标注好的数据集xml文件,使用别人的数据集训练自己的网络,下面是我的修改代码以及修改前后的xml标注文件:

import cv2 from xml.etree.ElementTree import ElementTree,Element def modify_xml(data_root_path): """Modify folder,filename and delete path node of xml files""" annots_path = os.path.join(data_root_path, 'Annotations') imgs_path = os.path.join(data_root_path, 'JPEGImages') num_per_class = {'transformer':0, 'insulator':0, 'switch':0, 'fuse':0} for i,annot in enumerate(os.listdir(annots_path)): if annot.split('.')[-1] == 'xml': xml_path = os.path.join(annots_path, annot) tree = ElementTree() tree.parse(xml_path) # modify folder node folder = tree.find("folder") folder.text = "VOC2007" # modify filename node filename = tree.find("filename") new_name = '0'*(5-len(str(i+1)))+str(i+1) filename.text = new_name +'.jpg' # delete path node root = tree.getroot() path = root.find("path") root.remove(path) # count number of each class for object in root.findall('object'): name = object.find('name') if name.text not in num_per_class.keys(): print annot num_per_class[name.text] += 1 print num_per_class # save xml file new_xml_path = os.path.join(data_root_path, new_name+'.xml') # 注意写xml文件时要去掉xml开头的版本信息(xml_declaration=False), # 否则用MatlabAPI转格式时会出错 tree.write(new_xml_path, encoding="utf-8",xml_declaration=False) # modify img name print str(i+1)+":modifying "+annot.split('.')[0]+'.jpg' img_path = os.path.join(imgs_path, annot.split('.')[0]+'.jpg') img = cv2.imread(img_path) new_img_path = os.path.join(data_root_path, new_name+'.jpg') cv2.imwrite(new_img_path, img) print 'finished'

12345678910111213141516171819202122232425262728293031323334353637383940414243

修改前的xml标注文件:

<annotation> <folder>new</folder> <filename>flir_20180321T104306.jpg</filename> <path>/usr/elecEquipment/new/flir_20180321T104306.jpg</path> <source> <database>Unknown</database> </source> <size> <width>480</width> <height>640</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>transformer</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>161</xmin> <ymin>222</ymin> <xmax>348</xmax> <ymax>370</ymax> </bndbox> </object> <object> <name>insulator</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>276</xmin> <ymin>171</ymin> <xmax>365</xmax> <ymax>248</ymax> </bndbox> </object> </annotation>

1234567891011121314151617181920212223242526272829303132333435363738

修改后的xml标注文件

<annotation> <folder>VOC2007</folder> <filename>00001.jpg</filename> <source> <database>Unknown</database> </source> <size> <width>480</width> <height>640</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>transformer</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>161</xmin> <ymin>222</ymin> <xmax>348</xmax> <ymax>370</ymax> </bndbox> </object> <object> <name>insulator</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>276</xmin> <ymin>171</ymin> <xmax>365</xmax> <ymax>248</ymax> </bndbox> </object> </annotation>

12345678910111213141516171819202122232425262728293031323334353637

相关知识

YOLO目标检测——棉花病虫害检测数据集下载分享【含对应voc、coco和yolo三种格式标签】
【目标检测数据集】西蓝花数据集1930张VOC+YOLO格式
json格式
【yolo数据集】花朵数据集yolo
使用YOLOv8训练该数据集农业害虫检测数据集 农业虫害数据集.该数据集的害虫类别共为三类,该数据集共4010张JPG图片,标签文件为xml格式,4010个。
JSON格式化 json在线解析工具 在线json格式校验
农业病虫害图像数据集及构建
Python基于改进YOLOv5的烟叶病害检测系统(附带源码)
【叶片病虫害数据集】果树叶片病变识别 机器视觉 Python (含数据集)
XML基本解析

网址: 将用LabelImg标注得到的VOC格式数据集标签(xml文件)转换成COCO格式(json文件) https://m.huajiangbk.com/newsview1316233.html

所属分类:花卉
上一篇: 植物学野外实习教程
下一篇: 标签效应,是指人们一旦被帖上某种