Article directory
Make your own VOC dataset
First, store the pictures and .xml files in the VOC dataset according to the following folder format.
My dataset folders at all levels are shown in the figure:
Generate dataset name file
The names of all dataset images are stored in train.txt (note that they are names without suffixes !!!)
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:
DIR *.*/B>train.txt
Modify the suffix of the .txt file to .bat, as shown in the figure:
Double-click the .bat file, and you will see that a train.txt file is generated.
Open the train.txt, and you can see that the contents are the names of all the files in the images folder. .
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:
Open the newly generated train1.txt and you can see that the suffixes have been deleted.
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:
- Change the sixth line to 'train', 'val', 'test'
- Change the content in the seventh line classes to the category name in your own data set
- 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
Improve your own YOLO data set
Finally, copy the labels folder into the yolo dataset.