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, darknet
o yolov3、yolov4
formato 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 .xml
arquivo 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:
Um
.txt
corresponde 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
BoundingBox
dentro(中心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.py
para 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 VOCdevkit
pasta. Haverá VOC2007
subpastas ou VOC2012
subpastas ou ambas nesta pasta . Em VOC2007
e VOC2012
abaixo 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.
2, os voc_label.py
arquivos de script e suas VOCdevkit
pastas 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 usarsets
o local no código, por exemplo, o código a seguir para entendersets
quais 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 VOCdevkit
há apenas uma VOC2007
subpasta em meu arquivo e há arquivos no VOCdevkit/VOC2007/ImageSets/Main
caminho train.txt
, val.txt
e test.txt
os nomes das imagens usadas para treinamento, verificação e teste em todas as categorias (ou todas as imagens) são armazenados. Então, minhas sets
configuraçõ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.py
e finalmente será VOCdevkit
gerado no diretório de mesmo nível da pasta 2007_train.txt,2007_val.txt,2007_test.txt
, e VOCdevkit/VOC2007
uma label
pasta será gerada sob o caminho .
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.txt
o caminho completo do nome de arquivo armazenado na imagem . Isso e train.txt
, val.txt
, test.txt
em 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.
labels文件夹
Os arquivos armazenados nesta pasta .txt
correspondem 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.
Quatro, resumo
Já sabemos que alguns arquivos novos e reorganizados são gerados pela voc_label.py
conversão do VOC
conjunto de dados formatado em um yolo
formato, 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!