Dados do formato VOC definidos para o formato yolo (darknet)

I. Introdução

No artigo anterior, aprendemos sobre o formato de organização do conjunto de dados VOC . Se quisermos treinar nosso próprio conjunto de dados, podemos organizar seus dados de acordo com o formato VOC.

Claro, algumas ferramentas podem ser necessárias e falarei sobre isso mais tarde, se tiver uma chance! ! !

Porém, darkneto yolov3、yolov4formato de dados exigido da versão oficial não é assim, e ainda precisamos fazer algumas conversões. Mas a boa notícia é que podemos usar alguns scripts Python para nos ajudar a concluir a conversão de formato rapidamente! ! !

Dois, o formato de dados do yolo

Conforme mencionado anteriormente, o formato dos dados de yolo é diferente do de voc, o que se reflete principalmente na diferente organização da categoria e informação de coordenadas , ou seja, o primeiro não usa diretamente o .xmlarquivo mencionado no artigo anterior para ler os dados, mas usa dados de leitura em um arquivo que salva informações de categorias e coordenadas em um determinado formato .txt. Então, qual é o formato específico do yolo para salvar informações de categorias e coordenadas ? Ver abaixo:

Insira a descrição da imagem aqui

Um .txtcorresponde a uma imagem e seus nomes são os mesmos.

Uma linha correspondente ao objeto, a primeira parte é class_id, os próximos quatro números estão BoundingBoxdentro (中心x坐标,中心y坐标,宽,高). Essas coordenadas são coordenadas relativas de 0 a 1.

Três, conversão de formato

Portanto, como o formato dos dados da etiqueta em voc é diferente do yolo, precisamos convertê-lo, podemos usar o oficial voc_label.pypara fazer a conversão. Vamos falar brevemente sobre o que devemos prestar atenção! ! !

1. Em primeiro lugar, suponha que você obteve o conjunto de dados de voc antes e o armazenou na VOCdevkitpasta. Haverá VOC2007subpastas ou VOC2012subpastas ou ambas nesta pasta . Em VOC2007e VOC2012abaixo disso está armazenado no referido artigo Annotations、ImageSets和JPEGImages, como uma subpasta. (Observe que os conjuntos de dados para verificação e teste de treinamento são separados durante o download, mas seus nomes de imagem e nomes de arquivo xml são contínuos, ou seja, eles não têm nomes idênticos um antes do outro, portanto, são todas as imagens diretamente misturadas. Portanto, se você deseja converter todos os dados de treinamento, val e teste de uma vez, apenas copie os arquivos da pasta com o mesmo nome no conjunto de dados de teste baixado para a pasta com o mesmo nome no conjunto de dados de verificação de treinamento.)

Na verdade Main, os outros arquivos da pasta não são usados ​​e não há problema em manter apenas os arquivos da figura abaixo.
Insira a descrição da imagem aqui

2, os voc_label.pyarquivos de script e suas VOCdevkitpastas no mesmo caminho para o próximo nível.

3. Modifique o código de acordo com a situação real:

  • A primeira é sets: você deve usar setso local no código, por exemplo, o código a seguir para entender setsquais valores devem ser definidos em você, na verdade, ele está intimamente relacionado ao nome e ao caminho da sua pasta.
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 VOCdevkithá apenas uma VOC2007subpasta em meu arquivo e há arquivos no VOCdevkit/VOC2007/ImageSets/Maincaminho train.txt, val.txte test.txtos nomes das imagens usadas para treinamento, verificação e teste em todas as categorias (ou todas as imagens) são armazenados. Então, minhas setsconfigurações se tornaram sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')].

  • A segunda é classes: aqui estão as várias categorias incluídas em seu conjunto de dados.
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. Execute voc_label.pye finalmente será VOCdevkitgerado no diretório de mesmo nível da pasta 2007_train.txt,2007_val.txt,2007_test.txt, e VOCdevkit/VOC2007uma labelpasta será gerada sob o caminho .

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui
Então, quais são os conteúdos específicos dos arquivos gerados acima?

  • 2007_train.txt,2007_val.txt,2007_test.txt

Como mostrado abaixo, que é armazenado train.txt, val.txt, test.txto caminho completo do nome de arquivo armazenado na imagem . Isso e train.txt, val.txt, test.txtem comparação com fotos basta colocar dentro da loja em um nome de caminho completo, o outro em termos de número e correspondentes imagens são exatamente o mesmo.
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

  • labels文件夹

Os arquivos armazenados nesta pasta .txtcorrespondem a todas as imagens (treinamento + verificação + teste), uma imagem e um arquivo, e os nomes são todos iguais. O que é armazenado em cada arquivo são informações de categoria e coordenada , conforme mostrado abaixo.
Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

Quatro, resumo

Já sabemos que alguns arquivos novos e reorganizados são gerados pela voc_label.pyconversão do VOCconjunto de dados formatado em um yoloformato, então, como esses arquivos devem ser usados? Em relação a como usá-los para treinamento, vamos esperar até o próximo artigo! Espero que o conteúdo acima possa ajudá-lo!

Acho que você gosta

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