Datos de formato VOC configurados en formato yolo (darknet)

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, darknetel yolov3、yolov4formato 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 .xmlarchivo 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:

Inserte la descripción de la imagen aquí

Uno .txtcorresponde 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 BoundingBoxen (中心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.pypara 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 VOCdevkitcarpeta. Habrá VOC2007subcarpetas o VOC2012subcarpetas o ambas en esta carpeta . En VOC2007y VOC2012debajo 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.
Inserte la descripción de la imagen aquí

2, los voc_label.pyarchivos de secuencia de comandos y sus VOCdevkitcarpetas en la misma ruta al siguiente nivel.

3. Modifique el código de acuerdo con la situación real:

  • La primera es sets: debe usar setsel lugar en el código, por ejemplo, el siguiente código para comprender setsqué 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 VOCdevkitsolo hay una VOC2007subcarpeta debajo de mi archivo, y hay archivos debajo de la VOCdevkit/VOC2007/ImageSets/Mainruta train.txt, val.txty test.txtse 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 setsconfiguració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 VOCdevkitgenerará en el mismo nivel de directorio de la carpeta 2007_train.txt,2007_val.txt,2007_test.txt, y se VOCdevkit/VOC2007generará una labelcarpeta debajo de la ruta .

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí
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.txtla ruta completa del nombre de archivo almacenado en la imagen . Eso y train.txt, val.txt, test.txten 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.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

  • labels文件夹

Los archivos almacenados en esta carpeta .txtcorresponden 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.
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Cuatro, resumen

Ya sabemos que algunos archivos nuevos y reorganizados se generan al voc_label.pyconvertir el VOCconjunto de datos formateados a un yoloformato, 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!

Supongo que te gusta

Origin blog.csdn.net/qq_39507748/article/details/110819929
Recomendado
Clasificación