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)
相关推荐
小馋喵知识杂货铺1 小时前
pytest 截图功能
开发语言·python
MichaelIp3 小时前
LLM大语言模型中RAG切片阶段改进策略
人工智能·python·语言模型·自然语言处理·chatgpt·embedding·word2vec
我不是程序猿儿4 小时前
【C++】xml烧录 调用twinCat流程自动化
xml·c++·自动化
blues_C5 小时前
Pytest-Bdd-Playwright 系列教程(完结篇):本框架的功能参数说明
自动化测试·python·pytest·测试框架·bdd
nvvas5 小时前
Pytest安装Allure生成自动化测试报告
python·测试工具·pytest
Bruce-li__6 小时前
django解决跨域问题
后端·python·django
qq_273900236 小时前
pytorch torch.isclose函数介绍
人工智能·pytorch·python
生信与遗传解读6 小时前
XGBoost算法在自定义数据集中预测疾病风险
人工智能·python·算法·数据分析
人生无根蒂,飘如陌上尘8 小时前
网站自动签到
python·签到