YOLOv5 支持的标签(labels)格式为 txt 文件,其内容与每个图像一一对应,通常放在与图像同名的文件中(例如,图像为 image1.jpg
,则标签为 image1.txt
)。YOLOv5 的标签格式如下:
class_id x_center y_center width height
其中每一行代表一个目标(object),包括以下几个字段:
- class_id:类别 ID,代表目标的类别,从 0 开始的整数。这个 ID 对应于模型的类别定义文件。
- x_center:目标中心的 x 坐标,相对于图像宽度进行归一化(范围为 0 到 1)。
- y_center:目标中心的 y 坐标,相对于图像高度进行归一化(范围为 0 到 1)。
- width:目标的宽度,相对于图像宽度进行归一化(范围为 0 到 1)。
- height:目标的高度,相对于图像高度进行归一化(范围为 0 到 1)。
例如,假设图像中有一个类别 ID 为 1 的物体,其归一化后的标签可能如下所示:
1 0.5000 0.5000 0.2000 0.3000
这意味着类别为 1 的物体位于图像中心,宽度为图像宽度的 20%,高度为图像高度的 30%。
归一化 是指将像素坐标相对于图像的总宽高进行比例缩放,使坐标值介于 0 到 1 之间,以便适应不同尺寸的图像。
这样格式化的标签能够被 YOLOv5 模型直接使用进行训练和推理。
但是实际上我们往往标注得到的是XML文件
在目标检测任务中,XML 文件格式通常遵循 PASCAL VOC 数据集的标签格式,用于存储图像中目标物体的位置信息和类别信息。这种格式广泛用于标注数据集中的标签信息,尤其是在经典的 PASCAL VOC 数据集中。下面是如何获取或生成 XML 文件的常见方法:
标注工具可以直接生成 XML 格式的标注文件,常见的标注工具包括:
- LabelImg:这是一个流行的开源图像标注工具,支持 PASCAL VOC XML 格式。使用该工具,你可以手动标注图像中的物体边界框及其类别,生成相应的 XML 文件。
步骤:
- 下载并安装 LabelImg。
- 加载图像进行手动标注。
- 将标注保存为 PASCAL VOC 格式,工具会自动生成与图像同名的 XML 文件。
XML 文件内容结构:
-
一个典型的 XML 文件包含图像的基本信息(文件名、大小)和标注的目标物体的边界框信息。示例如下:
<annotation>
<folder>images</folder>
<filename>image1.jpg</filename>
<path>/path/to/image1.jpg</path>
<size>
<width>800</width>
<height>600</height>
<depth>3</depth>
</size>
<object>
<name>cat</name> <!-- 类别 -->
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>100</xmin>
<ymin>200</ymin>
<xmax>300</xmax>
<ymax>400</ymax>
</bndbox>
</object>
</annotation>
字段说明:
folder
: 图像所在文件夹名称。filename
: 图像的文件名。size
: 图像的大小,包括宽度、高度和深度(颜色通道数)。object
: 目标物体信息,包括类别name
和边界框bndbox
,其中xmin
,ymin
,xmax
,ymax
分别是物体的左上角和右下角坐标(像素值)。
小编这里提供了一个XML转为YOLO标签TXT文件
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir , getcwd
from os.path import join
import glob
classes = ["blue"]
def convert(size, box):
dw = 1.0/size[0]
dh = 1.0/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(image_name):
in_file = open('PATH/'+image_name[:-3]+'xml') #xml文件路径
out_file = open('PATH/'+image_name[:-3]+'txt', 'w') #转换后的txt文件存放路径
f = open('C:/Users/张佳珲/Desktop/cr/xml/'+image_name[:-3]+'xml','rb')
xml_text = f.read()
root = ET.fromstring(xml_text)
f.close()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
print(cls)
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()
if __name__ == '__main__':
for image_path in glob.glob("PATH/*.jpg"): #每一张图片都对应一个xml文件这里写xml对应的图片的路径
image_name = image_path.split('\\')[-1]
convert_annotation(image_name)