I. Introducción
En el artículo anterior, hemos aprendido sobre el formato de organización del conjunto de datos de VOC . Si queremos entrenar nuestro propio conjunto de datos, entonces podemos organizar sus datos de acuerdo con el formato de VOC.
Por supuesto, es posible que se necesiten algunas herramientas, ¡y hablaré de ello más adelante si tengo la oportunidad! ! !
Sin embargo, darknet
el yolov3、yolov4
formato de datos requerido de la versión oficial no es así, y aún necesitamos hacer alguna conversión. ¡Pero la buena noticia es que podemos usar algunos scripts de Python para ayudarnos a completar rápidamente la conversión de formato! ! !
Dos, formato de datos de yolo
Como se mencionó anteriormente, el formato de datos de yolo es diferente al de voc, lo que se refleja principalmente en la diferente organización de la información de categorías y coordenadas , es decir, el primero no usa directamente el .xml
archivo mencionado en el artículo anterior para leer datos, pero usa Leer datos en un archivo que guarda información de categorías y coordenadas en un formato determinado .txt
. Entonces, ¿ cuál es el formato específico para que yolo guarde la información de categorías y coordinaciones ? Vea abajo:
Uno
.txt
corresponde a una imagen y sus nombres son los mismos.
Una línea correspondiente al objeto, la primera parte es class_id, los siguientes cuatro números están
BoundingBox
en(中心x坐标,中心y坐标,宽,高)
. Estas coordenadas son coordenadas relativas de 0 a 1.
Tres, conversión de formato
Entonces, dado que el formato de datos de la parte de la etiqueta en voc es diferente al de yolo, entonces necesitamos convertirlo. Podemos usar el oficial voc_label.py
para lograr la conversión. ¡Hablemos brevemente sobre lo que debemos prestar atención! ! !
1. Primero suponga que ha obtenido el conjunto de datos voc antes y lo ha almacenado en la VOCdevkit
carpeta. Habrá VOC2007
subcarpetas o VOC2012
subcarpetas o ambas en esta carpeta . En VOC2007
y VOC2012
debajo de eso se almacena en dicho artículo Annotations、ImageSets和JPEGImages
, como una subcarpeta. (Tenga en cuenta que los conjuntos de datos para la verificación de entrenamiento y las pruebas están separados cuando se descargan, pero sus nombres de imagen y los nombres de archivo xml son continuos, es decir, no tienen nombres idénticos antes que el otro, por lo que todas las imágenes están directamente mezcladas. Entonces, si desea convertir todos los datos de entrenamiento, val y prueba a la vez, simplemente copie los archivos en la carpeta con el mismo nombre en el conjunto de datos de prueba descargado a la carpeta con el mismo nombre en el conjunto de datos de verificación de entrenamiento.)
De hecho Main
, los otros archivos de la carpeta no se utilizan y está bien mantener solo los archivos de la siguiente figura.
2, los voc_label.py
archivos de secuencia de comandos y sus VOCdevkit
carpetas en la misma ruta al siguiente nivel.
3. Modifique el código de acuerdo con la situación real:
- La primera es
sets
: debe usarsets
el lugar en el código, por ejemplo, el siguiente código para comprendersets
qué valores deben establecerse en usted, de hecho, está estrechamente relacionado con el nombre y la ruta de su carpeta.
for year, image_set in sets:
if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):
os.makedirs('VOCdevkit/VOC%s/labels/'%(year))
image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'
%(year, image_set)).read().strip().split()
Porque VOCdevkit
solo hay una VOC2007
subcarpeta debajo de mi archivo, y hay archivos debajo de la VOCdevkit/VOC2007/ImageSets/Main
ruta train.txt
, val.txt
y test.txt
se almacenan los nombres de las imágenes utilizadas para el entrenamiento, la verificación y las pruebas en todas las categorías (o todas las imágenes). Entonces, mi sets
configuración se convirtió en sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
.
- La segunda es
classes
: aquí están las diversas categorías incluidas en su conjunto de datos.
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=[('2007', 'train'), ('2007', 'val'),('2007', 'test')]
classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus",
"car", "cat", "chair", "cow", "diningtable", "dog", "horse",
"motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
def convert(size, box):
dw = 1./size[0]
dh = 1./size[1]
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
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(year, image_id):
in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')
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
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))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
wd = getcwd()
for year, image_set in sets:
if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):
os.makedirs('VOCdevkit/VOC%s/labels/'%(year))
image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'
%(year, image_set)).read().strip().split()
list_file = open('%s_%s.txt'%(year, image_set), 'w')
for image_id in image_ids:
list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'
%(wd, year, image_id))
convert_annotation(year, image_id)
list_file.close()
4. Ejecutar voc_label.py
, y finalmente se VOCdevkit
generará en el mismo nivel de directorio de la carpeta 2007_train.txt,2007_val.txt,2007_test.txt
, y se VOCdevkit/VOC2007
generará una label
carpeta debajo de la ruta .
Entonces, ¿cuáles son los contenidos específicos de los archivos generados anteriormente?
2007_train.txt,2007_val.txt,2007_test.txt
Como se muestra a continuación, que se almacena train.txt
, val.txt
, test.txt
la ruta completa del nombre de archivo almacenado en la imagen . Eso y train.txt
, val.txt
, test.txt
en comparación con las imágenes sólo hay que poner dentro de la tienda en un nombre de ruta completo, el otro en términos de número y correspondientes imágenes son exactamente los mismos.
labels文件夹
Los archivos almacenados en esta carpeta .txt
corresponden a todas las imágenes (entrenamiento + verificación + prueba), una imagen y un archivo, y los nombres son todos iguales. Lo que se almacena en cada archivo es información de categorías y coordenadas , como se muestra a continuación.
Cuatro, resumen
Ya sabemos que algunos archivos nuevos y reorganizados se generan al voc_label.py
convertir el VOC
conjunto de datos formateados a un yolo
formato, entonces, ¿cómo se deben usar estos archivos? En cuanto a cómo usarlos para entrenar, ¡esperemos hasta el próximo artículo! ¡Espero que el contenido anterior pueda ayudarte!