VOC dataset to YOLO dataset

Make your own VOC dataset

First, store the pictures and .xml files in the VOC dataset according to the following folder format.
insert image description here
My dataset folders at all levels are shown in the figure:
Please add a picture description
Please add a picture description

Please add a picture description
Please add a picture description
Please add a picture description

Generate dataset name file

The names of all dataset images are stored in train.txt (note that they are names without suffixes !!!)
Please add a picture description
As shown in the figure, there are several .jpg files in my images folder, in this images folder Create a .txt file with the content as shown in the figure:
Please add a picture description

 DIR  *.*/B>train.txt 

Modify the suffix of the .txt file to .bat, as shown in the figure:
insert image description here
Double-click the .bat file, and you will see that a train.txt file is generated.
Please add a picture description
Open the train.txt, and you can see that the contents are the names of all the files in the images folder. .
insert image description here
Delete the two lines of list.bat and train.txt, leaving only the name of the picture
Note: Since only the name of the picture can be kept in the final train.txt without the suffix , it is necessary to put ".jpg" in each line of the train.txt file "Delete, you can manually delete, but if the data set is too large, you can use the following python script to delete:

import os
filename = r"train.txt"
new_filename = r"train1.txt"
with open(filename,encoding="utf-8") as f1, open(new_filename,"w",encoding="utf-8") as f2:
    for line in f1:
        new_line = line[:-5]
        f2.write(new_line)
        f2.write('\n')
f1.close()
f2.close()

The running effect is shown in the figure:
insert image description here
Open the newly generated train1.txt and you can see that the suffixes have been deleted.
insert image description here
At this time, copy the contents of train1.txt to \data\ImageSets\Main\train.txt.

.xml file to .txt file

The .xml to .txt file yolo model officially provides the conversion code, and the usage method is shown below:

Create a .py file with the following content:

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd

sets = ['train', 'val', 'test'] 
classes = ['red', 'yellow','green', 'turn_left',  'turn_right', 'stop']   # 改成自己的类别
abs_path = os.getcwd()
print(abs_path)

def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return x, y, w, h

def convert_annotation(image_id):
    in_file = open('C:/Users/Lenovo/Desktop/data/Annotations/%s.xml' % (image_id),encoding='utf-8')
    out_file = open('C:/Users/Lenovo/Desktop/data/labels/%s.txt' % (image_id), 'w',encoding='utf-8')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        # difficult = obj.find('difficult').text
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        b1, b2, b3, b4 = b
        # 标注越界修正
        if b2 > w:
            b2 = w
        if b4 > h:
            b4 = h
        b = (b1, b2, b3, b4)
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')

wd = getcwd()
for image_set in sets:
    if not os.path.exists('C:/Users/Lenovo/Desktop/data/labels/'):
        os.makedirs('C:/Users/Lenovo/Desktop/data/labels/')
    image_ids = open('C:/Users/Lenovo/Desktop/data/ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
    list_file = open('%s.txt' % (image_set), mode='w', encoding='utf-8')
    for image_id in image_ids:
        list_file.write('C:/Users/Lenovo/Desktop/data/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

Notes on conversion code usage:

  1. Change the sixth line to 'train', 'val', 'test'
  2. Change the content in the seventh line classes to the category name in your own data set
  3. Pay attention to the writing of each address, be sure to use backslashes

After running this script, you will find that a new labels folder is generated in the data, which means that the data conversion is successful
Please add a picture description
insert image description here

Improve your own YOLO data set

Finally, copy the labels folder into the yolo dataset.

Guess you like

Origin blog.csdn.net/qq_52109814/article/details/124864143