使用Python将yolov5的推理保存的txt文本格式转换为XML格式

文章介绍了一个Python脚本,该脚本能将文本格式的目标检测标注转换为XML,适用于计算机视觉中的图像数据集管理,特别是VOC数据集格式。脚本遍历图像文件,读取相应的文本标注信息,然后创建XML文档结构,包括物体类别、边界框坐标等,并保存为XML文件。
摘要由CSDN通过智能技术生成

目标检测是计算机视觉中的基础任务,可以让机器在图像中识别和定位物体。为了高效地标注和存储目标检测数据,我们使用了各种不同的数据格式。其中一种常用的格式是XML结构,通常用于VOC数据集格式。在本文中,我们将探讨一个Python脚本,它可以将目标检测标注从特定的文本文件格式转换为XML格式。

问题描述

假设您有一个图像数据集,同时还有相应的文本文件,其中包含目标检测的标注信息。每个文本文件都提供了有关图像中存在的物体的信息。例如,在每个文本文件中,每行可能包含物体类别、边界框坐标等信息。然而,您希望将这些标注信息转换为XML格式,以便更好地组织和管理数据。

Python脚本实现

以下是一个使用Python编写的脚本,用于将目标检测标注从文本格式转换为XML格式:

# 导入所需库
import os
import cv2
import shutil
from xml.dom.minidom import Document

# 定义物体类别
cls_names = ['人', '狗']

def makexml(picPath, txtPath, xmlPath):
    # 删除已有的XML保存路径,并创建新的路径
    if os.path.exists(xmlPath):
        shutil.rmtree(xmlPath)
    os.makedirs(xmlPath)

    # 获取图片文件列表
    files = os.listdir(picPath)

    # 遍历每个图片文件
    for i, name in enumerate(files):
        ss = os.path.join(picPath, name)
        print(ss)
        img = cv2.imread(ss)
        Pheight, Pwidth, Pdepth = img.shape

        # 创建XML文档对象
        xmlBuilder = Document()
        annotation = xmlBuilder.createElement("annotation")  # 创建annotation标签
        xmlBuilder.appendChild(annotation)

        # 添加folder标签
        folder = xmlBuilder.createElement("folder")
        folderContent = xmlBuilder.createTextNode("VOC2007")
        folder.appendChild(folderContent)
        annotation.appendChild(folder)

        # 添加filename标签
        filename = xmlBuilder.createElement("filename")
        filenameContent = xmlBuilder.createTextNode(name)
        filename.appendChild(filenameContent)
        annotation.appendChild(filename)

        # 添加size标签
        size = xmlBuilder.createElement("size")
        width = xmlBuilder.createElement("width")
        widthContent = xmlBuilder.createTextNode(str(Pwidth))
        width.appendChild(widthContent)
        size.appendChild(width)
        height = xmlBuilder.createElement("height")
        heightContent = xmlBuilder.createTextNode(str(Pheight))
        height.appendChild(heightContent)
        size.appendChild(height)
        depth = xmlBuilder.createElement("depth")
        depthContent = xmlBuilder.createTextNode(str(Pdepth))
        depth.appendChild(depthContent)
        size.appendChild(depth)
        annotation.appendChild(size)

        # 读取对应的文本文件
        txt = os.path.join(txtPath, name[0:-3] + "txt")
        if not os.path.exists(txt):
            # 若文本文件不存在,则直接保存XML文件并处理下一张图片
            print(txt)
            f = open(os.path.join(xmlPath, name[0:-4] + '.xml'), 'w', encoding="utf-8")
            xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
            f.close()
            continue

        # 若文本文件存在,则读取文本内容并添加相应的标签
        txtFile = open(txt)
        txtList = txtFile.readlines()

        for i in txtList:
            oneline = i.strip().split(" ")
            object = xmlBuilder.createElement("object")
            picname = xmlBuilder.createElement("name")
            nameContent = xmlBuilder.createTextNode(cls_names[int(oneline[0])])
            picname.appendChild(nameContent)
            object.appendChild(picname)

            # 添加pose、truncated、difficult等标签
            # 添加bndbox标签,并计算bounding box的坐标
            # 将以上标签添加至annotation标签下
             pose = xmlBuilder.createElement("pose")
            poseContent = xmlBuilder.createTextNode("Unspecified")
            pose.appendChild(poseContent)
            object.appendChild(pose)
            truncated = xmlBuilder.createElement("truncated")
            truncatedContent = xmlBuilder.createTextNode("0")
            truncated.appendChild(truncatedContent)
            object.appendChild(truncated)
            difficult = xmlBuilder.createElement("difficult")
            difficultContent = xmlBuilder.createTextNode("0")
            difficult.appendChild(difficultContent)
            object.appendChild(difficult)
            bndbox = xmlBuilder.createElement("bndbox")
            xmin = xmlBuilder.createElement("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)
            ymin = xmlBuilder.createElement("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)
            xmax = xmlBuilder.createElement("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)
            ymax = xmlBuilder.createElement("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)
            object.appendChild(bndbox)
            annotation.appendChild(object)

        # 保存生成的XML文件
        f = open(os.path.join(xmlPath, name[0:-4] + '.xml'), 'w', encoding="utf-8")
        xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
        f.close()

# 调用函数进行转换
makexml("../data/images/", "../runs/detect/exp19/labels/", "../data/all/annotations/")

结论

通过使用上述Python脚本,您可以将yolov5的推理保存的txt从文本格式转换为更为常见的XML格式,从而更好地管理和组织您的数据集。转换后的XML格式可以被广泛用于各种目标检测算法和数据处理工具中,为计算机视觉研究和应用提供便利。

可以使用Python中的xml.etree.ElementTree模块将yolov5txt标注文件换为xml格式。具体实现可以参考以下代码: ```python import xml.etree.ElementTree as ET def convert_txt_to_xml(txt_path, xml_path, class_list): with open(txt_path, 'r') as f: lines = f.readlines() root = ET.Element('annotation') folder = ET.SubElement(root, 'folder') folder.text = 'images' filename = ET.SubElement(root, 'filename') filename.text = txt_path.split('/')[-1].split('.')[] + '.jpg' size = ET.SubElement(root, 'size') width = ET.SubElement(size, 'width') width.text = '416' height = ET.SubElement(size, 'height') height.text = '416' depth = ET.SubElement(size, 'depth') depth.text = '3' for line in lines: line = line.strip().split() class_name = class_list[int(line[])] xmin = line[1] ymin = line[2] xmax = line[3] ymax = line[4] object = ET.SubElement(root, 'object') name = ET.SubElement(object, 'name') name.text = class_name bndbox = ET.SubElement(object, 'bndbox') xmin_node = ET.SubElement(bndbox, 'xmin') xmin_node.text = xmin ymin_node = ET.SubElement(bndbox, 'ymin') ymin_node.text = ymin xmax_node = ET.SubElement(bndbox, 'xmax') xmax_node.text = xmax ymax_node = ET.SubElement(bndbox, 'ymax') ymax_node.text = ymax tree = ET.ElementTree(root) tree.write(xml_path) # 示例代码 txt_path = 'path/to/your/txt/file.txt' xml_path = 'path/to/your/xml/file.xml' class_list = ['class1', 'class2', 'class3'] # 类别列表 convert_txt_to_xml(txt_path, xml_path, class_list) ``` 其中,`txt_path`为yolov5txt标注文件路径,`xml_path`为换后的xml文件路径,`class_list`为类别列表,需要根据实际情况进行修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

random_2011

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

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

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

打赏作者

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

抵扣说明:

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

余额充值