Python DOTA与PASCAL VOC格式标签数据的相互转化

该博客介绍了如何在遥感影像目标检测领域中,将DOTA数据集的倾斜框坐标转换为PASCALVOC的矩形框坐标,并提供了相应的Python代码实现。同时,也展示了从PASCALVOC XML格式标签文件转换回DOTA的txt格式。这两个转换函数对于处理不同数据集或模型训练时的目标检测任务非常有用。

DOTA数据集是遥感影像目标检测的常用标准数据集,其标签文件以txt的形式存储,一个txt对应一张样本影像,txt中的每一行对应影像中的一个目标,每个目标的外围边界框表示为【 x1 y1 x2 y2 x3 y3 x4 y4 label difficult 】,具体如下所示:

 PASCAL VOC也是目标检测、图像分割任务中常用的基准数据之一,其样本标签以xml的文件形式存储,每个xml对应一张样本影像,object的边界框信息由顶点坐标值【xmin ymin xmax ymax】表示,具体如下所示:

有时候,我们同时想用倾斜框和矩形框模型对目标进行检测,就可以将标记的DOTA格式的倾斜框坐标转化为PASCAL VOC格式的矩形框坐标,转化方式如下所示:

import os
from xml.dom.minidom import Document
from xml.dom.minidom import parse
import xml.dom.minidom
import numpy as np
import csv
import cv2
import string


def poly2rect(box_list):
    box_list = np.array(box_list)
    x, y, w, h = cv2.boundingRect(box_list)
    xmin = x - w / 2.0
    ymin = y - h / 2.0
    xmax = x + w / 2.0
    ymax = y + h / 2.0
    return xmin, ymin, xmax, ymax


def WriterXMLFiles(filename, path, box_list, label_list, w, h, d):
    # dict_box[filename]=json_dict[filename]
    doc = xml.dom.minidom.Document()
    root = doc.createElement('annotation')
    doc.appendChild(root)

    foldername = doc.createElement("folder")
    foldername.appendChild(doc.createTextNode("JPEGImages"))
  
### DOTA数据换为VOC格式 为了获取并处理DOTA相关的VOC数据集,需先了解两个主要的数据集结构差异以及具体的换方法。 #### DOTA数据集特点 DOTA是一个大规模的遥感图像目标检测数据集,其标注文件通常采用txt格式存储,每行记录一个实例的目标类别及其边界框坐标[^1]。 #### VOC数据集结构概述 VOC(Visual Object Classes)挑战赛所使用的数据集有着特定的目录结构和XML格式的标注文件。这些XML文件包含了图片尺寸、对象数量及每个对象的位置信息等细节[^2]。 #### 换过程概览 要将DOTA数据转化为适用于VOC框架的形式,关键在于编写脚本读取原始TXT标签并将它们重写为符合PASCAL VOC标准的新XML文件。此过程中需要注意调整路径设置以匹配实际环境中的文件位置,例如`out_xml_dir = '/mnt/D/yuangan/datasets/nwpu/VOC2007/Annotations/'`用于指定保存新创建的XML文件的目的地[^3]。 ```python import os from xml.etree.ElementTree import Element, SubElement, tostring from xml.dom.minidom import parseString def create_voc_annotation(image_name, objects, output_folder): """ 创建单张图片对应的VOC XML注解文件 参数: image_name (str): 图片名称 objects (list of dict): 对象列表 [{'name': 'plane', 'bbox': [xmin,ymin,xmax,ymax]}...] output_folder (str): 输出xml文件夹路径 返回值: None """ annotation = Element('annotation') folder = SubElement(annotation, 'folder').text = "VOC2007" filename = SubElement(annotation, 'filename').text = f"{image_name}.png" source = SubElement(annotation, 'source') database = SubElement(source, 'database').text = "The DOTAV1.0 Database" annotation_source = SubElement(source, 'annotation').text = "DOTAV1.0" image = SubElement(source, 'image').text = "flickr" size_part = SubElement(annotation, 'size') width = SubElement(size_part, 'width').text = str(800) # 假设宽度为800像素 height = SubElement(size_part, 'height').text = str(800) # 假设高度为800像素 depth = SubElement(size_part, 'depth').text = str(3) segmented = SubElement(annotation, 'segmented').text = "0" for obj in objects: object_item = SubElement(annotation, 'object') name = SubElement(object_item, 'name').text = obj['name'] pose = SubElement(object_item, 'pose').text = "Unspecified" truncated = SubElement(object_item, 'truncated').text = "0" difficult = SubElement(object_item, 'difficult').text = "0" bndbox = SubElement(object_item, 'bndbox') xmin = SubElement(bndbox, 'xmin').text = str(obj['bbox'][0]) ymin = SubElement(bndbox, 'ymin').text = str(obj['bbox'][1]) xmax = SubElement(bndbox, 'xmax').text = str(obj['bbox'][2]) ymax = SubElement(bndbox, 'ymax').text = str(obj['bbox'][3]) rough_string = tostring(annotation, 'utf-8') reparsed = parseString(rough_string) formatted_output = reparsed.toprettyxml(indent=" ") with open(os.path.join(output_folder, f'{os.path.splitext(image_name)[0]}.xml'), 'w') as file: file.write(formatted_output) # 示例调用函数 create_voc_annotation( image_name='example_image', objects=[{'name': 'ship', 'bbox': [100, 150, 200, 250]}, {'name': 'plane', 'bbox': [300, 400, 500, 600]}], output_folder='/path/to/output/folder' ) ``` 上述Python代码片段展示了如何基于给定的信息构建满足VOC要求的XML文档,并将其保存到指定目录下。这一步骤对于准备训练材料至关重要,在完成全部样本转化之后即可利用该版本的数据集开展进一步的研究工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小李AI飞刀^_^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值