xml-dota-yolo数据集格式转换

1、yolo转xml

python 复制代码
from xml.dom.minidom import Document
import os
import cv2
# def makexml(txtPath, xmlPath, picPath):  # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
def makexml(picPath, txtPath, xmlPath):  # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
    """此函数用于将yolo格式txt标注文件转换为voc格式xml标注文件
    """
    dic = {'0': "plane",  # 创建字典用来对类型进行转换
           '1': "baseball diamond",  # 此处的字典要与自己的classes.txt文件中的类对应,且顺序要一致
           '2': "bridge",
           '3': "ground track field",
           '4': "small vehicle",
           '5': "large vehicle",
           '6': "ship",
           '7': "tennis court",
           '8': "basketball court",
           '9': "storage tank",
           '10': "soccer ball field",
           '11': "roundabout",
           '12': "harbor",
           '13': "swimming pool",
           '14': "helicopter",
           }
    files = os.listdir(txtPath)
    for i, name in enumerate(files):
        xmlBuilder = Document()
        annotation = xmlBuilder.createElement("annotation")  # 创建annotation标签
        xmlBuilder.appendChild(annotation)
        txtFile = open(txtPath + name)
        txtList = txtFile.readlines()
        img = cv2.imread(picPath + name[0:-4] + ".jpg")
        Pheight, Pwidth, Pdepth = img.shape
        folder = xmlBuilder.createElement("folder")  # folder标签
        foldercontent = xmlBuilder.createTextNode("driving_annotation_dataset")
        folder.appendChild(foldercontent)
        annotation.appendChild(folder)  # folder标签结束
        filename = xmlBuilder.createElement("filename")  # filename标签
        filenamecontent = xmlBuilder.createTextNode(name[0:-4] + ".jpg")
        filename.appendChild(filenamecontent)
        annotation.appendChild(filename)  # filename标签结束
        size = xmlBuilder.createElement("size")  # size标签
        width = xmlBuilder.createElement("width")  # size子标签width
        widthcontent = xmlBuilder.createTextNode(str(Pwidth))
        width.appendChild(widthcontent)
        size.appendChild(width)  # size子标签width结束
        height = xmlBuilder.createElement("height")  # size子标签height
        heightcontent = xmlBuilder.createTextNode(str(Pheight))
        height.appendChild(heightcontent)
        size.appendChild(height)  # size子标签height结束
        depth = xmlBuilder.createElement("depth")  # size子标签depth
        depthcontent = xmlBuilder.createTextNode(str(Pdepth))
        depth.appendChild(depthcontent)
        size.appendChild(depth)  # size子标签depth结束
        annotation.appendChild(size)  # size标签结束
        for j in txtList:
            oneline = j.strip().split(" ")
            object = xmlBuilder.createElement("object")  # object 标签
            picname = xmlBuilder.createElement("name")  # name标签
            namecontent = xmlBuilder.createTextNode(dic[oneline[0]])
            picname.appendChild(namecontent)
            object.appendChild(picname)  # name标签结束
            pose = xmlBuilder.createElement("pose")  # pose标签
            posecontent = xmlBuilder.createTextNode("Unspecified")
            pose.appendChild(posecontent)
            object.appendChild(pose)  # pose标签结束
            truncated = xmlBuilder.createElement("truncated")  # truncated标签
            truncatedContent = xmlBuilder.createTextNode("0")
            truncated.appendChild(truncatedContent)
            object.appendChild(truncated)  # truncated标签结束
            difficult = xmlBuilder.createElement("difficult")  # difficult标签
            difficultcontent = xmlBuilder.createTextNode("0")
            difficult.appendChild(difficultcontent)
            object.appendChild(difficult)  # difficult标签结束
            bndbox = xmlBuilder.createElement("bndbox")  # bndbox标签
            xmin = xmlBuilder.createElement("xmin")  # xmin标签
            mathData = int(((float(oneline[1])) * Pwidth + 1) - (float(oneline[3])) * 0.5 * Pwidth)
            xminContent = xmlBuilder.createTextNode(str(mathData))
            xmin.appendChild(xminContent)
            bndbox.appendChild(xmin)  # xmin标签结束
            ymin = xmlBuilder.createElement("ymin")  # ymin标签
            mathData = int(((float(oneline[2])) * Pheight + 1) - (float(oneline[4])) * 0.5 * Pheight)
            yminContent = xmlBuilder.createTextNode(str(mathData))
            ymin.appendChild(yminContent)
            bndbox.appendChild(ymin)  # ymin标签结束
            xmax = xmlBuilder.createElement("xmax")  # xmax标签
            mathData = int(((float(oneline[1])) * Pwidth + 1) + (float(oneline[3])) * 0.5 * Pwidth)
            xmaxContent = xmlBuilder.createTextNode(str(mathData))
            xmax.appendChild(xmaxContent)
            bndbox.appendChild(xmax)  # xmax标签结束
            ymax = xmlBuilder.createElement("ymax")  # ymax标签
            mathData = int(((float(oneline[2])) * Pheight + 1) + (float(oneline[4])) * 0.5 * Pheight)
            ymaxContent = xmlBuilder.createTextNode(str(mathData))
            ymax.appendChild(ymaxContent)
            bndbox.appendChild(ymax)  # ymax标签结束
            object.appendChild(bndbox)  # bndbox标签结束
            annotation.appendChild(object)  # object标签结束
        f = open(xmlPath + name[0:-4] + ".xml", 'w')
        xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
        f.close()
if __name__ == "__main__":
    picPath = "./images/test/"  # 图片所在文件夹路径,后面的/一定要带上
    txtPath = "./labels/test/"  # txt所在文件夹路径,后面的/一定要带上
    xmlPath = "./annotations/test/"  # xml文件保存路径,后面的/一定要带上
    makexml(picPath, txtPath, xmlPath)

xml格式

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
	<annotation>
		<folder>driving_annotation_dataset</folder>
		<filename>0.jpg</filename>
		<size>
			<width>640</width>
			<height>640</height>
			<depth>3</depth>
		</size>
		<object>
			<name>plane</name>
			<pose>Unspecified</pose>
			<truncated>0</truncated>
			<difficult>0</difficult>
			<bndbox>
				<xmin>315</xmin>
				<ymin>248</ymin>
				<xmax>422</xmax>
				<ymax>304</ymax>
			</bndbox>
		</object>
	</annotation>

2、xml转dota

python 复制代码
import os
import xml.etree.ElementTree as ET


def convert_voc_to_dota_simple(xml_folder, output_folder):
    # 创建输出文件夹(如果不存在)
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # 遍历 XML 文件夹中的所有文件
    for xml_file in os.listdir(xml_folder):
        if xml_file.endswith('.xml'):  # 只处理 XML 文件
            # 解析 XML 文件
            tree = ET.parse(os.path.join(xml_folder, xml_file))
            root = tree.getroot()

            # 初始化 DOTA 格式的字符串列表
            dota_annotations = []

            # 遍历 XML 中的 'object' 元素
            for obj in root.iter('object'):
                # 获取标准矩形边界框坐标
                bndbox = obj.find('bndbox')
                # 获取类别和难度级别
                category = obj.find('name').text
                difficult = obj.find('difficult').text

                # 提取矩形边界框的坐标
                xmin = int(bndbox.find('xmin').text)
                ymin = int(bndbox.find('ymin').text)
                xmax = int(bndbox.find('xmax').text)
                ymax = int(bndbox.find('ymax').text)

                # 将矩形边界框的四个角作为旋转边界框的顶点
                coords = [
                    xmin, ymin,  # 左上角
                    xmax, ymin,  # 右上角
                    xmax, ymax,  # 右下角
                    xmin, ymax  # 左下角
                ]

                # 将坐标、类别和难度级别转换为 DOTA 格式
                dota_format = ' '.join(map(str, coords + [category, difficult]))
                dota_annotations.append(dota_format)

            # 写入转换后的信息到 TXT 文件
            output_file_path = os.path.join(output_folder, xml_file.replace('.xml', '.txt'))
            with open(output_file_path, 'w') as f:
                for annotation in dota_annotations:
                    f.write("%s\n" % annotation)  # 每个注释占一行


# 调用函数,传入 XML 文件夹路径和输出文件夹路径
xml_folder = './annotations/val'  # 请替换为您的 XML 文件夹路径
output_folder = './DOTA_labels/val'  # 请替换为您希望保存输出 TXT 文件的文件夹路径
convert_voc_to_dota_simple(xml_folder, output_folder)

3、验证dota 画框

python 复制代码
import xml.etree.ElementTree as ET
import os
import math
import cv2
import numpy as np
import dota_utils as util
import random

img_root = r"./images/train/"
label_root = r"./DOTA_labels/train/"
drawed_img_root = r"./DOTA_labels_drawed/train/"
image_name = os.listdir(img_root)
for i in range(len(image_name)):
    img_path = os.path.join(img_root, image_name[i])
    label_path = os.path.join(label_root, image_name[i].split('.')[0] + '.txt')
    drawed_img_path = os.path.join(drawed_img_root, image_name[i])
    objects = util.parse_dota_poly(label_path)
    print(objects)
    img = cv2.imread(img_path)
    poly = []
    for i in range(len(objects)):
        poly.append(np.array(objects[i]['poly'], dtype=np.int32))
    print(poly)
    cv2.polylines(img, poly, isClosed=True, color=(35, 37, 133), thickness=2)
    drawed_img_path = drawed_img_path.replace('.bmp', '.png')
    cv2.imwrite(drawed_img_path, img)
相关推荐
葬爱家族小阿杰6 分钟前
python执行测试用例,allure报乱码且未成功生成报告
开发语言·python·测试用例
xx155802862xx8 分钟前
Python如何给视频添加音频和字幕
java·python·音视频
酷爱码8 分钟前
Python实现简单音频数据压缩与解压算法
开发语言·python
花果山总钻风35 分钟前
SQLAlchemy 中的 func 函数使用指南
python
知识中的海王1 小时前
Python html 库用法详解
开发语言·python
面朝大海,春不暖,花不开1 小时前
使用 Python 正则表达式实现文本替换与电话号码规范化
python·mysql·正则表达式
淘小白_TXB21961 小时前
Python网页自动化Selenium中文文档
python·selenium·自动化·网页自动化
Clair-Sean1 小时前
【JavaSE】多线程基础学习笔记
笔记·python·学习
EverBule3 小时前
Python 训练 day46
开发语言·python
WangY_ZQ3 小时前
Python 如何在Python 3.6上安装PIP
linux·python·pip