目标检测标签格式转换 txt->xml

目标检测标签格式转换 txt->xml

将YOLO格式的标签转换成VOC格式的标签,用于适应多种算法的目标检测

# _*_ coding:utf-8 _*_
import xml.etree.ElementTree as ET
import os
import cv2
"""
标签格式转换:txt->xml
时间:2022.04.15
作者:余小晖
"""

# 增加换行符
def __indent(elem, level=0):
    i = "\n" + level*"\t"
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "\t"
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            __indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i


def txt_xml(img_size, txt_file_path):
    # object-class> <x_center> <y_center> <width> <height>
    bboxs = []  # cls_name, xmin, ymin, xmax, ymax
    width, height= img_size[1], img_size[0]     # 获取对应图像的宽高
    with open(txt_file_path, 'r', encoding='UTF-8')as f:
        lines = f.readlines()   # 可能含有空的txt文件,空txt文件将直接返回空bboxs列表
        # 读取txt文件中每一行数据,每一行数据包含有一个目标
        for line in lines :
            line= line.split()
            line = [float(i) for i in line ]
            cls_name= int(line[0])
            xmin = int((line[1]- line[3]/2)* width)
            xmax = int((line[1]+ line[3]/2)* width)
            ymin = int((line[2]- line[4]/2)* height)
            ymax = int((line[2]+ line[4]/2)* height)
            bbox = [cls_name, xmin, ymin, xmax, ymax]
            bboxs.append(bbox)
    return bboxs


def write_xml(img_path, txt_path, xml_save_path):
    txt_files = os.listdir(txt_path)
    # txt_files.sort(key=lambda x: int(x.split('_')[-1][:-4]))  # 按照数字排序
    for num, txt_file in enumerate(txt_files):
        txt_name_list = txt_file.split('.')
        xml_name = txt_name_list[0]+ '.xml'
        img_name = txt_name_list[0]+ '.jpg' # 图片后缀为jpg时
        # 获取图像尺寸width、height、depth
        image = cv2.imread(img_path+ img_name)
        img_size = image.shape
        txt_file_path = txt_path+ txt_file
        bboxs = txt_xml(img_size, txt_file_path)
        root = ET.Element('annotation')
        tree = ET.ElementTree(root)
        # 添加root子节点filename
        filename = ET.Element('filename')
        filename.text = img_name
        root.append(filename)
        #添加root子节点size
        size = ET.Element('size')
        img_width = ET.Element('width')
        img_width.text = str(img_size[1])
        size.append(img_width)
        img_height = ET.Element('height')
        img_height.text = str(img_size[0])
        size.append(img_height)
        img_depth = ET.Element('depth')
        img_depth.text = str(img_size[-1])
        size.append(img_depth)
        root.append(size)
        # 添加root子节点object
        for i in range(len(bboxs)):
            #添加所有的object子节点
            object = ET.Element('object')
            cls_name = ET.Element('name')
            cls_name.text = cls_dict[str(bboxs[i][0])]
            object.append(cls_name)
            difficult = ET.Element('difficult')
            difficult.text = str(0)
            object.append(difficult)
            bndbox = ET.Element('bndbox')
            element_list = ['xmin','ymin', 'xmax', 'ymax']
            for j, element in enumerate(element_list):
                ele = ET.Element(element)
                ele.text = str(bboxs[i][j+1])
                bndbox.append(ele)
            object.append(bndbox)
            root.append(object)
        __indent(root)  # 增加换行符
        tree.write(xml_save_path+ xml_name, encoding='utf-8', xml_declaration=True)
        print('num------------------------',num+1,'==',txt_file)


if __name__ == '__main__':
    txt_path= './face_mask-1/ann_txt/'  #txt标签路径
    xml_save_path = './face_mask-1/ann_xml-1/'  #xml文件保存路径
    img_path = './face_mask-1/images/'  #图像路径
    if not os.path.exists(xml_save_path):
        os.makedirs(xml_save_path)
    cls_dict = {'0': 'face', '1': 'face_mask'}  #ID以及对应类别
    write_xml(img_path, txt_path, xml_save_path)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

XTX_AI

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

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

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

打赏作者

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

抵扣说明:

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

余额充值