生成VOC数据集的xml文件

脚本

采用写入xml的方式来生成voc的数据集标注文件,脚本及使用方法如下

import cv2
import os
import argparse
from lxml.etree import Element, SubElement, tostring
from xml.dom.minidom import parseString

def make_xml(xmin_tuple,ymin_tuple,xmax_tuple,ymax_tuple,image_name,image_shape):
    node_root = Element('annotation')
    # node_folder = SubElement(node_root, 'folder')
    # node_folder.text = 'VOC'

    node_filename = SubElement(node_root, 'filename')
    node_filename.text = image_name

    node_object_num = SubElement(node_root, 'object_num')
    node_object_num.text = str(len(xmin_tuple))

    node_size = SubElement(node_root, 'size')
    node_width = SubElement(node_size, 'width')
    node_width.text = str(image_shape[1])

    node_height = SubElement(node_size, 'height')
    node_height.text = str(image_shape[0])

    for i in range(len(xmin_tuple)):  
        node_object = SubElement(node_root, 'object')
        # node_name = SubElement(node_object, 'name')
        # node_name.text = 'ship'
        # node_difficult = SubElement(node_object, 'difficult')
        # node_difficult.text = '0'

        node_bndbox = SubElement(node_object, 'bndbox')
        node_xmin = SubElement(node_bndbox, 'xmin')
        node_xmin.text = str(xmin_tuple[i])
        node_ymin = SubElement(node_bndbox, 'ymin')
        node_ymin.text = str(ymin_tuple[i])
        node_xmax = SubElement(node_bndbox, 'xmax')
        node_xmax.text = str(xmax_tuple[i])
        node_ymax = SubElement(node_bndbox, 'ymax')
        node_ymax.text = str(ymax_tuple[i])

    xml = tostring(node_root)
    dom = parseString(xml)
    return dom

def saveXmlFiles(src,dst):
    img = cv2.imread(src,0) 

    if len(img.shape) == 3:
        gray_image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    else:
        gray_image = img

    a,b,status,d = cv2.connectedComponentsWithStats(gray_image)
    # print(a,src,status)
    xmin_tuple = []
    ymin_tuple = []
    xmax_tuple = []
    ymax_tuple = []
    for i in range(1,len(status)):
        x=status[i][0]
        y=status[i][1]
        w=status[i][2]
        h=status[i][3]

        xmin_tuple.append(x)
        ymin_tuple.append(y)
        xmax_tuple.append(x + w)
        ymax_tuple.append(y + h)

    dom = make_xml(xmin_tuple, ymin_tuple, xmax_tuple, ymax_tuple, src.split('/')[-1],img.shape)
    with open(dst,'wb') as f:
        f.write(dom.toprettyxml(indent='\t',encoding = 'utf-8'))

if __name__ == "__main__":
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--inputdir",default='trainlabel',help='要输入的数据目录')
    parser.add_argument("--outputdir",default='Annotations',help='xml存储目录')
    args = parser.parse_args()

    assert os.path.exists(args.inputdir),'The value of inputdir:{} is not found!'.format(args.inputdir)
    
    for dir in sorted(os.listdir(args.inputdir)):
        subdir = os.path.join(args.inputdir,dir)
        outputdir = os.path.join(args.outputdir,dir)
        
        if not os.path.exists(outputdir):
            os.makedirs(outputdir)

        for fname in os.listdir(subdir):
            imagefile = os.path.join(subdir,fname)
            outputfile =  os.path.join(outputdir,fname.replace('.bmp','.xml'))
            
            saveXmlFiles(imagefile,outputfile)

生成的文件如下所示
在这里插入图片描述
但我们需要的xml文件是没有第一行<?xml version="1.0" encoding="utf-8"?>标注的。这该如何解决。

取消生成的xml文件第一行

进入导入包from xml.dom.minidom import parseString中的minidom文件,搜索writexml函数,在1789行,注释掉下面这部分即可。
在这里插入图片描述
之后重新运行,生成的xml文件就符合我们的要求了。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
将txt文件转换为VOC数据集xml格式,需要进行以下步骤: 1. 创建VOC数据集xml文件模板。 2. 读取txt文件中的标注信息,包括类别、位置信息等。 3. 将读取到的信息填充到xml文件模板中。 4. 将生成xml文件保存到指定的目录中。 以下是一个简单的Python代码实现: ```python import os import xml.etree.cElementTree as ET def txt_to_xml(txt_file_path, xml_file_path, image_size, class_list): # 创建xml文件模板 root = ET.Element("annotation") ET.SubElement(root, "folder").text = os.path.dirname(txt_file_path) ET.SubElement(root, "filename").text = os.path.basename(txt_file_path).replace('.txt', '.jpg') size = ET.SubElement(root, "size") ET.SubElement(size, "width").text = str(image_size[0]) ET.SubElement(size, "height").text = str(image_size[1]) ET.SubElement(size, "depth").text = str(image_size[2]) for cls in class_list: ET.SubElement(root, "object") # 读取txt文件中的标注信息 with open(txt_file_path, 'r') as f: lines = f.readlines() for line in lines: line = line.strip().split() cls = line[0] xmin, ymin, xmax, ymax = line[1:] # 将标注信息填充到xml文件模板中 obj = ET.SubElement(root, "object") ET.SubElement(obj, "name").text = cls bndbox = ET.SubElement(obj, "bndbox") ET.SubElement(bndbox, "xmin").text = xmin ET.SubElement(bndbox, "ymin").text = ymin ET.SubElement(bndbox, "xmax").text = xmax ET.SubElement(bndbox, "ymax").text = ymax # 保存生成xml文件 tree = ET.ElementTree(root) tree.write(xml_file_path) # 示例代码 txt_file_path = 'path/to/annotation.txt' xml_file_path = 'path/to/annotation.xml' image_size = (640, 480, 3) class_list = ['person', 'car', 'bike'] txt_to_xml(txt_file_path, xml_file_path, image_size, class_list) ``` 注意:以上代码仅是一个简单的示例,具体实现需要根据自己的数据集格式和要求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

贱贱的剑

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

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

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

打赏作者

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

抵扣说明:

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

余额充值