目标检测是计算机视觉中非常重要的任务,而YOLO(You Only Look Once)作为一种高效的目标检测算法,广泛应用于各类视觉任务中。在进行YOLO训练时,标注数据的格式是至关重要的。本文将详细介绍如何将XML格式的标注文件转换为YOLO所需的TXT格式标注,以便能够在YOLO框架中进行训练。
一、背景介绍
在计算机视觉任务中,尤其是目标检测任务,数据的标注格式常常不统一。常见的标注格式有:
PASCAL VOC 格式:基于 XML 文件,每个 XML 文件中包含图像信息和对应的目标框位置。
YOLO 格式:采用 TXT 文件,每一行记录一个物体的类别及其在图像中的位置(相对于图像的归一化坐标)。
YOLO 格式的标注文件要求每个物体信息以行的形式存储,每行包括以下数据:
<类别ID> <x_center> <y_center> <width> <height>
其中,x_center、y_center、width 和 height 是相对于图像尺寸归一化后的值(取值范围为0到1)。
在本文中,我们将介绍如何将标准的PASCAL VOC XML格式标注转换为YOLO所需的TXT格式标注。
二、XML格式标注文件解析
PASCAL VOC XML格式标注文件通常包含如下结构:
<annotation>
<folder>JPEGImages</folder>
<filename>image_1.jpg</filename>
<size>
<width>1920</width>
<height>1080</height>
<depth>3</depth>
</size>
<object>
<name>drone</name>
<bndbox>
<xmin>400</xmin>
<ymin>300</ymin>
<xmax>500</xmax>
<ymax>400</ymax>
</bndbox>
</object>
</annotation>
上述 XML 文件标注了图像的尺寸和目标物体(例如 drone)的位置,其中 <bndbox> 标签下包含了目标物体的边界框信息。
三、YOLO格式转换步骤
YOLO要求标注信息以TXT格式保存,每个标注文件对应一个图像。每一行包含一个物体的信息,格式如下:
<类别ID> <x_center> <y_center> <width> <height>
-
类别ID :从预定义的类别列表中获取(如本文中的
["drone"])。 -
x_center, y_center :边界框中心的归一化坐标,分别为
(xmin + xmax) / 2和(ymin + ymax) / 2。 -
width, height :边界框的宽度和高度,分别为
(xmax - xmin)和(ymax - ymin)。 -
归一化:YOLO要求坐标以相对于图像宽高的比例来表示。即:
-
x_center = (xmin + xmax) / 2 / 图像宽度 -
y_center = (ymin + ymax) / 2 / 图像高度 -
width = (xmax - xmin) / 图像宽度 -
height = (ymax - ymin) / 图像高度
-
四、实现代码
以下是将PASCAL VOC XML标注文件转换为YOLO格式标注文件的Python代码实现:
import xml.etree.ElementTree as ET
import os
import glob
# 定义类别,这里定义自己的类别,有多少类按照顺序写上
classes = ["drone"]
# 将标注框转换为YOLO格式
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)
# 转换 XML 标注文件为 YOLO 格式
def convert_annotation(image_name):
# 构造 XML 和 TXT 文件路径
xml_path = os.path.join('./Annotations', image_name[:-3] + 'xml')
txt_path = os.path.join('./labels', image_name[:-3] + 'txt')
# 如果标签输出文件夹不存在,创建它
os.makedirs(os.path.dirname(txt_path), exist_ok=True)
# 打开并读取 XML 文件
try:
with open(xml_path, 'r') as f:
xml_text = f.read()
root = ET.fromstring(xml_text)
except FileNotFoundError:
print(f"XML 文件未找到: {xml_path}")
return
# 获取图片的宽度和高度
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
# 打开输出的 TXT 文件进行写入
with open(txt_path, 'w') as out_file:
# 遍历每个 object 标签
for obj in root.iter('object'):
cls = obj.find('name').text
# 如果该类别不在指定类别列表中,跳过
if cls not in classes:
print(f"跳过类别: {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(f"{cls_id} {' '.join([str(a) for a in bb])}\n")
# 主程序
if __name__ == '__main__':
# 遍历所有的 .jpg 图片文件,并转换成相应的 .xml 文件
for image_path in glob.glob("./JPEGImages/*.jpg"): # 图片路径
image_name = os.path.basename(image_path) # 获取图片文件名
convert_annotation(image_name) # 调用转换函数
五、代码解析
转换函数
convert:该函数将标注框从像素坐标转换为YOLO所需的归一化格式。
convert_annotation函数:该函数读取每个XML标注文件,提取图像的宽度、高度以及目标框信息,并将其转换为YOLO格式,最后保存到TXT文件中。主程序 :遍历
./JPEGImages/目录下的所有.jpg文件,依次调用convert_annotation函数进行转换。
六、总结
本文详细介绍了如何将 PASCAL VOC XML 格式标注文件转换为 YOLO 格式标注文件。这对于使用 YOLO 进行目标检测训练非常重要,因为YOLO要求标注数据以特定格式存储。通过 Python 脚本自动化这个过程,我们可以快速将原始标注数据转换为 YOLO 所需的格式,从而为模型训练做准备。
希望本文对你有所帮助,如果你有任何问题,欢迎留言讨论!