[tool Script] in target detection, VOC format data is transferred to COCO format data. Pro test! No bug! No mistake!

When we do target detection, sometimes we need to convert our VOC training data to COCO format. Here we provide the corresponding script, pro test, and error free!

instructions:

1) VOC? CLSES: sets the class name of your own dataset.

2) voc2007xmls: Specifies the path of xml file in VOC format data.

3) test_txt: the name of the xml file specified in the txt file. (the content in txt only has the name of xml file, without path and suffix!)

4) json_name: Specifies the name of the generated json format file.

OK, that's all nonsense. Let's play the leading role next!

# coding=utf-8
import xml.etree.ElementTree as ET
import os
import json

# Modify here according to your category name<<----
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:  # Traverse first level nodes
        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)   # Remove the following + 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)   # Save the image ID corresponding to the current box
                    bbox.append(cat_id)
                    # anno area
                    bbox.append((xmax - xmin) * (ymax - ymin) - 10.0)   # ares of bbox
                    # The ares value in coco is < w * h, because it's actually calculated by the area of segmentation, so I'll take - 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'   #Set the path of the xml file
voc2007xmls = '/data_1/script_file/model_test_script-master/mAp/input/Annotations'

# test_txt = 'voc2007/test.txt'  #Set the name of the xml file (note! Only file name in txt, no need to specify path and name suffix)
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'   #Set the name of the saved json file
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 more beautiful display

 

72 original articles published, praised 17, visited 70000+
Private letter follow

Tags: xml JSON

Posted on Sat, 11 Jan 2020 12:19:44 -0500 by neroag