【工具脚本】目标检测中VOC格式数据转COCO格式数据。亲测!无bug!不报错!
程序员文章站
2022-04-17 18:32:08
...
前言:我们在做目标检测时,有时需要将自己的VOC格式的训练数据转换为COCO格式,这里提供对应的脚本,亲测,不会报错!
使用说明:
1)voc_clses:设置自己数据集的类别名称。
2)voc2007xmls:指定VOC格式数据中xml文件的路径。
3)test_txt:txt文件中指定xml文件的名称。(txt中的内容只有xml文件的名称,不需要带路径和后缀!)
4)json_name:指定生成好的json格式文件的名称。
好的,废话就说到这里,接下来放主角!
# coding=utf-8
import xml.etree.ElementTree as ET
import os
import json
# 此处按照自己的类别名称修改 <<----
voc_clses = ['none_of_the_above','chepai','chedeng', 'chebiao','person',]
categories = []
for iind, cat in enumerate(voc_clses):
cate = {}
cate['supercategory'] = cat
cate['name'] = cat
cate['id'] = iind
categories.append(cate)
def getimages(xmlname, id):
sig_xml_box = []
tree = ET.parse(xmlname)
root = tree.getroot()
images = {}
for i in root: # 遍历一级节点
if i.tag == 'filename':
file_name = i.text # 0001.jpg
# print('image name: ', file_name)
images['file_name'] = file_name
if i.tag == 'size':
for j in i:
if j.tag == 'width':
width = j.text
images['width'] = width
if j.tag == 'height':
height = j.text
images['height'] = height
if i.tag == 'object':
for j in i:
if j.tag == 'name':
cls_name = j.text
# cat_id = voc_clses.index(cls_name) + 1
cat_id = voc_clses.index(cls_name) # 去掉后面的+1
if j.tag == 'bndbox':
bbox = []
xmin = 0
ymin = 0
xmax = 0
ymax = 0
for r in j:
if r.tag == 'xmin':
xmin = eval(r.text)
if r.tag == 'ymin':
ymin = eval(r.text)
if r.tag == 'xmax':
xmax = eval(r.text)
if r.tag == 'ymax':
ymax = eval(r.text)
bbox.append(xmin)
bbox.append(ymin)
bbox.append(xmax - xmin)
bbox.append(ymax - ymin)
bbox.append(id) # 保存当前box对应的image_id
bbox.append(cat_id)
# anno area
bbox.append((xmax - xmin) * (ymax - ymin) - 10.0) # bbox的ares
# coco中的ares数值是 < w*h 的, 因为它其实是按segmentation的面积算的,所以我-10.0一下...
sig_xml_box.append(bbox)
# print('bbox', xmin, ymin, xmax - xmin, ymax - ymin, 'id', id, 'cls_id', cat_id)
images['id'] = id
# print ('sig_img_box', sig_xml_box)
return images, sig_xml_box
def txt2list(txtfile):
f = open(txtfile)
l = []
for line in f:
l.append(line[:-1])
return l
# voc2007xmls = 'anns' #设置xml文件的路径
voc2007xmls = '/data_1/script_file/model_test_script-master/mAp/input/Annotations'
# test_txt = 'voc2007/test.txt' #设置xml文件的名称(注意!txt中只有文件名称,无需指定路径和名称后缀)
test_txt = '/data_1/script_file/model_test_script-master/mAp/input/ImageSets/Main/test.txt'
xml_names = txt2list(test_txt)
xmls = []
bboxes = []
ann_js = {}
for ind, xml_name in enumerate(xml_names):
xmls.append(os.path.join(voc2007xmls, xml_name + '.xml'))
json_name = 'instances_voc2007val.json' #设置保存的json文件的名称
images = []
for i_index, xml_file in enumerate(xmls):
print(xml_file)
image, sig_xml_bbox = getimages(xml_file, i_index)
images.append(image)
bboxes.extend(sig_xml_bbox)
ann_js['images'] = images
ann_js['categories'] = categories
annotations = []
for box_ind, box in enumerate(bboxes):
anno = {}
anno['image_id'] = box[-3]
anno['category_id'] = box[-2]
anno['bbox'] = box[:-3]
anno['id'] = box_ind
anno['area'] = box[-1]
anno['iscrowd'] = 0
annotations.append(anno)
ann_js['annotations'] = annotations
json.dump(ann_js, open(json_name, 'w'), indent=4) # indent=4 更加美观显示
上一篇: uva 11292
下一篇: 138. Redis 消息队列