📜  将 pascal 注释转换为 yolo - Python (1)

📅  最后修改于: 2023-12-03 15:25:14.580000             🧑  作者: Mango

将 Pascal 注释转换为 YOLO - Python

在 Object Detection 领域,YOLO(You Only Look Once)是一种经典的神经网络架构,常用于识别物体并进行定位,许多数据集都是以 YOLO 标注格式存在的。但在实际应用中,我们可能会遇到一些封装了 Pascal 注释格式的数据集,因此需要将其转换为 YOLO 标注格式。本文将介绍如何使用 Python 实现将 Pascal 注释转换为 YOLO 标注格式的功能。

Pascal 注释格式

Pascal 注释格式是一种常用的物体识别标注方式,其中每个物体都需要包含以下信息:

  • object 类别(class)
  • bbox 坐标,即物体的框(bounding box)
  • 必要时还可以包含其他信息,如 occlusion 信息等

注释文件通常为 XML 格式,每个注释文件会对应一个图像文件,文件名可以相同或不同。例如如下一个例子:

<annotation>
    <folder>images</folder>
    <filename>sample.jpg</filename>
    <size>
        <width>640</width>
        <height>480</height>
        <depth>3</depth>
    </size>
    <object>
        <name>car</name>
        <bndbox>
            <xmin>145</xmin>
            <ymin>55</ymin>
            <xmax>202</xmax>
            <ymax>128</ymax>
        </bndbox>
    </object>
    <object>
        <name>person</name>
        <bndbox>
            <xmin>366</xmin>
            <ymin>231</ymin>
            <xmax>456</xmax>
            <ymax>394</ymax>
        </bndbox>
    </object>
</annotation>
YOLO 标注格式

YOLO 标注格式是一种常用的物体识别标注方式,其中每个物体都需要包含以下信息:

  • object 类别(class)
  • bbox 中心坐标(x, y)
  • bbox 宽度和高度(w, h)

注释文件通常为 txt 格式,每个注释文件会对应一个图像文件,文件名必须相同,例如如下一个例子:

# class x_center y_center width height
0 0.372 0.569 0.484 0.697
1 0.711 0.563 0.257 0.661
将 Pascal 注释转换为 YOLO

在 Python 中,我们可以使用 xml.etree.ElementTree 模块来解析 Pascal XML 注释文件,然后根据 YOLO 标注格式生成相应的 txt 注释文件。

下面是一个简单的代码示例,可以用于将指定目录下所有 Pascal XML 注释文件转换为 YOLO txt 注释文件:

import os
import xml.etree.ElementTree as ET

def pascal_to_yolo(pascal_path, yolo_path, classes):
    for filename in os.listdir(pascal_path):
        if not filename.endswith('.xml'):  # 忽略非 xml 文件
            continue
        xml_path = os.path.join(pascal_path, filename)
        yolo_filename = os.path.splitext(filename)[0] + '.txt'
        yolo_path = os.path.join(yolo_path, yolo_filename)
        with open(xml_path, 'r') as f:
            tree = ET.parse(f)
            for obj in tree.findall('object'):
                cls = obj.find('name').text
                if cls not in classes:
                    continue
                bbox = obj.find('bndbox')
                xmin = int(bbox.find('xmin').text)
                ymin = int(bbox.find('ymin').text)
                xmax = int(bbox.find('xmax').text)
                ymax = int(bbox.find('ymax').text)
                x_center = ((xmin + xmax) / 2.0) / image_width
                y_center = ((ymin + ymax) / 2.0) / image_height
                width = (xmax - xmin) / image_width
                height = (ymax - ymin) / image_height
                with open(yolo_path, 'a') as out_file:
                    out_file.write(f'{classes.index(cls)} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n')

其中,pascal_path 为 Pascal 注释文件所在目录,yolo_path 为 YOLO 注释文件所保存的目录,classes 为类别列表,例如 ['car', 'person']。

总结

Pascal 注释和 YOLO 标注是常用的物体识别标注方式,在实际应用中可能会遇到需要将其转换的场景。我们可以使用 Python 的 xml.etree.ElementTree 模块解析 Pascal 注释,然后根据 YOLO 标注格式生成相应的 txt 注释。