【MBJC】(labelimg)txt转换xml,xml转换txt,txt修改标签名称,xml修改标签名称,python脚本(VOC-yolo)【001】

xml_txt_mutual_conversion

VOC Yolo tag modification conversion script

Github:

链接: https://github.com/Samsara0Null/xml_txt_mutual_conversion

CSDN主页:

链接: https://blog.csdn.net/noneNull0?type=blog

Bilibili视频演示讲解:

链接: https://www.bilibili.com/video/BV1ie4y1D77dvd_source=a6067b731745325c01a4edfa46bf5a04

umm,评论区有提出在使用txt_xml.py时,标签为字符类型,会报类似ValueError: could not convert string ‘A’ to float64 at row 0, column 1.
雀氏有道理,简单修改了一下,作为补充,用法同之前,修改路径,应该可以直接用,有相关需求可以尝试一下

链接: https://wwin.lanzoue.com/i12Yt0pj83fg

这是一些帮助转换txt和xml格式标签文件格式和修改标签名称的脚本(适用于VOC-yolo项目格式的标签)

可能需要安装一些依赖,配置好环境(跟着MoudleNotFound报错走就好了)

我的环境:

  • VSCode+Anaconda
  • python==3.6.13
  • pillow==8.3.1
  • opencv-python==4.6.0.66
  • numpy==1.19.5
  • lxml==3.8.0

演示样本:

在这里插入图片描述
在这里插入图片描述

txt_change_label.py

# 项目名称:DI_QueXianShiJueJianCe
# 程序内容:修改txt标签名称
# 作   者:MBJC
# 开发时间:2022/7/26 11:10

import os
import re
# 路径
path = './txt/'
# 文件列表
files = []
for file in os.listdir(path):
    if file.endswith(".txt"):
        files.append(path+file)
# 逐文件读取-修改-重写
for file in files:
    with open(file, 'r') as f:
        new_data = re.sub('^0', 'car', f.read(), flags=re.MULTILINE)  # 将列中的0替换为car
    with open(file, 'w') as f:
        f.write(new_data)
    with open(file, 'r') as f:
        new_data = re.sub('^1', 'horse', f.read(), flags=re.MULTILINE)  # 将列中的1替换为horse
    with open(file, 'w') as f:
        f.write(new_data)
    with open(file, 'r') as f:
        new_data = re.sub('^2', 'chair', f.read(), flags=re.MULTILINE)  # 将列中的2替换为chair
    with open(file, 'w') as f:
        f.write(new_data)
    with open(file, 'r') as f:
        new_data = re.sub('^3', 'bicycle', f.read(), flags=re.MULTILINE)  # 将列中的3替换为bicycle
    with open(file, 'w') as f:
        f.write(new_data)
  • 代码作用:修改txt标签名称
  • 1、修改存放txt标签文件的文件夹路径
    这里用了相对脚本的路径

在这里插入图片描述

  • 2、依葫芦画瓢修改想要的修改前和修改后标签名称

在这里插入图片描述

  • 3、运行 txt_change_label.py

在这里插入图片描述

  • 4、结果展示

运行前:

在这里插入图片描述

运行后:

在这里插入图片描述

txt_xml.py

# 项目名称:xml_txt_mutual_conversion
# 程序内容:jpg,txt转换xml
# 作   者:MBJC
# 开发时间:2022/8/1 9:59

import time
import os
from PIL import Image
import cv2
import numpy as np

'''人为构造xml文件的格式'''
out0 = '''<annotation>
    <folder>%(folder)s</folder>
    <filename>%(name)s</filename>
    <path>%(path)s</path>
    <source>
        <database>None</database>
    </source>
    <size>
        <width>%(width)d</width>
        <height>%(height)d</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
'''
out1 = '''    <object>
        <name>%(class)s</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>%(xmin)d</xmin>
            <ymin>%(ymin)d</ymin>
            <xmax>%(xmax)d</xmax>
            <ymax>%(ymax)d</ymax>
        </bndbox>
    </object>
'''

out2 = '''</annotation>
'''

'''txt转xml函数'''


def translate(fdir, lists):
    source = {}
    label = {}
    for jpg in lists:
        print(jpg)
        if jpg[-4:] == '.jpg':
            image = cv2.imread(jpg)  # 路径不能有中文
            h, w, _ = image.shape  # 图片大小
            #            cv2.imshow('1',image)
            #            cv2.waitKey(1000)
            #            cv2.destroyAllWindows()

            fxml = jpg.replace('.jpg', '.xml')
            fxml = open(fxml, 'w')
            imgfile = jpg.split('/')[-1]
            source['name'] = imgfile
            source['path'] = jpg
            source['folder'] = os.path.basename(fdir)

            source['width'] = w
            source['height'] = h

            fxml.write(out0 % source)
            txt = jpg.replace('.jpg', '.txt')

            lines = np.loadtxt(txt)  # 读入txt存为数组
            # print(type(lines))

            for box in lines:
                # print(box.shape)
                if box.shape != (5,):
                    box = lines

                '''把txt上的第一列(类别)转成xml上的类别
                   我这里是labelimg标123,对应txt上面的012'''
                label['class'] = str(int(box[0]) + 1)  # 类别索引从1开始

                '''把txt上的数字(归一化)转成xml上框的坐标'''
                xmin = float(box[1] - 0.5 * box[3]) * w
                ymin = float(box[2] - 0.5 * box[4]) * h
                xmax = float(xmin + box[3] * w)
                ymax = float(ymin + box[4] * h)

                label['xmin'] = xmin
                label['ymin'] = ymin
                label['xmax'] = xmax
                label['ymax'] = ymax

                # if label['xmin']>=w or label['ymin']>=h or label['xmax']>=w or label['ymax']>=h:
                #     continue
                # if label['xmin']<0 or label['ymin']<0 or label['xmax']<0 or label['ymax']<0:
                #     continue

                fxml.write(out1 % label)
            fxml.write(out2)


if __name__ == '__main__':
    file_dir = 'E:/CSDN/xml_txt_mutual_conversion/jpg_txt' #修改目标文件夹路径
    lists = []
    for i in os.listdir(file_dir):
        if i[-3:] == 'jpg':
            lists.append(file_dir + '/' + i)
            # print(lists)
    translate(file_dir, lists)
    print('---------------Done!!!--------------')
  • 代码作用:txt标签格式和对应jpg图片转换xml标签格式
  • 1、txt和对应jpg放在同一文件夹内

在这里插入图片描述

  • 2、修改目标文件夹路径

在这里插入图片描述

  • 3、运行txt_xml.py

在这里插入图片描述

  • 4、结果展示

运行前:

在这里插入图片描述

运行后:

在这里插入图片描述

可在labelimg中打开(注意txt中的标签0会变成xml中的标签1)

在这里插入图片描述

在这里插入图片描述

在文件夹中搜索xml即可得到文件

在这里插入图片描述

xml_change_label.py

# 项目名称:DI_QueXianShiJueJianCe
# 程序内容:修改xml标签名
# 作   者:MBJC
# 开发时间:2022/7/10 8:30

"""
批量修改xml文件中的缺陷类别名称
当有多个物体时,多个物体的名称均能被修改
"""

from lxml.etree import Element, SubElement, tostring, ElementTree
from xml.dom import minidom
import xml.etree.ElementTree as ET
import os
# 修改自己的路径
template_file = r'E:\CSDN\xml_txt_mutual_conversion\xml'  #这里是存放xml文件的文件夹
xmllist = os.listdir(template_file)
for xml in xmllist:
    #print(xml)
    tree = ET.parse(os.path.join(template_file,xml))
    root = tree.getroot() # 获取根节点
    for child in root:
        print(child.tag,child.attrib)
        if child.tag == 'object':
            name=child.find('name').text
            # print(name)
            if name == '1':
                child.find('name').text = 'car'
                tree=ET.ElementTree(root)
            elif name == '2':
                child.find('name').text = 'horse'
                tree = ET.ElementTree(root)
            elif name == '3':
                child.find('name').text = 'chair'
                tree = ET.ElementTree(root)
            elif name == '4':
                child.find('name').text = 'bicycle'
                tree = ET.ElementTree(root)
    tree.write(os.path.join(template_file,xml))

  • 代码作用:修改xml标签名称
  • 1、修改存放xml标签文件的文件夹路径

在这里插入图片描述

  • 2、修改自己想要修改的标签,例:1->car,标签数不同删减或增加elif语句即可

在这里插入图片描述

  • 3、运行xml_change_label.py

在这里插入图片描述

  • 4、结果展示

运行前:

在这里插入图片描述

运行后:

在这里插入图片描述

xml_txt.py

# 项目名称:xml_txt_mutual_conversion
# 程序内容:xml转txt
# 作   者:MBJC
# 开发时间:2022/8/1 11:29

import xml.etree.ElementTree as ET
import os
from os import getcwd
import glob

# 1.
# 自己创建文件夹,例如:label_mal label_txt  也可以修改别的
image_set = 'xml'  # 需要转换的文件夹名称(文件夹内放xml标签文件)
imageset2 = 'txt'  # 保存txt的文件夹
# 2.
# 换成你的类别 当前的顺序,就txt 0,1,2,3 四个类别
classes = ['car', 'horse', 'chair', 'bicycle']  # 标注时的标签 注意顺序一定不要错。

# 3.
# # 转换文件夹的绝对路径
# data_dir = 'D:/detectAuto_/data'
# 或者 读取当前路径
data_dir = getcwd()  # 当前路径


'''
xml中框的左上角坐标和右下角坐标(x1,y1,x2,y2)
》》txt中的中心点坐标和宽和高(x,y,w,h),并且归一化
'''


def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def convert_annotation(data_dir, imageset1, imageset2, image_id):
    in_file = open(data_dir + '/%s/%s.xml' % (imageset1, image_id))  # 读取xml
    out_file = open(data_dir + '/%s/%s.txt' % (imageset2, image_id), 'w')  # 保存txt

    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)  # 获取类别索引
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str('%.6f' % a) for a in bb]) + '\n')


image_ids = []
for x in glob.glob(data_dir + '/%s' % image_set + '/*.xml'):
    image_ids.append(os.path.basename(x)[:-4])
print('\n%s数量:' % image_set, len(image_ids))  # 确认数量
i = 0
for image_id in image_ids:
    i = i + 1
    convert_annotation(data_dir, image_set, imageset2, image_id)
    print("%s 数据:%s/%s文件完成!" % (image_set, i, len(image_ids)))

print("Done!!!")
  • 代码作用:xml标签格式转换txt标签格式

  • 1、修改待修改xml文件夹和目标txt文件夹路径

[外链图片转存失败,源站可能有防盗在这里插入!链机制,建描述]议将图片上https://传(imblog.csnmg.ci/1ngx5f06aa398049420a868e0b560d21fda.png2(https://ig-blog.csdnimg.cn/5f06aa398049420a868e0b5620d21fda.png)]

温馨提示:注意,如果读取当前路径的话,前两个路径要修改成相对路径

在这里插入图片描述

  • 2、换成待转换xml标签名称所想排顺序的名称序列

在这里插入图片描述

  • 3、运行xml_txt.py

在这里插入图片描述

4、结果展示

运行前:

在这里插入图片描述

运行后:

在这里插入图片描述

Author: MBJC
Last modification time: 2022/8/2 19:48

你可以使用readFileToXML模块中的readFileToXML类来将txt文件转换xml文件。首先,你需要在Linux上运行脚本,所以你需要修改调用方式。在代码中,你可以看到通过sys.argv获取命令行输入的文件路径,如果没有输入参数,则提示用户输入文件路径。然后,你可以实例化readFileToXML类,并传入文件路径作为参数。最后,调用makeXML方法将txt文件转换xml文件。\[1\] 如果你想调试代码,你可以使用调试代码部分中的代码。你可以实例化readFileToXML类,并传入文件路径作为参数。然后,你可以调用makeXML方法将txt文件转换xml文件。你还可以打印JSON格式和XML格式的数据,以及路径和文件。\[2\] 对于转换的具体格式,你可以参考引用\[3\]中给出的示例。每个txt文件中的数据表示一个类别,包括xmin、ymin、w和h。你需要将这些数据转换为对应的xml格式。 #### 引用[.reference_title] - *1* *2* [使用PythonTXT文本内容读取后生成指定XML格式的文件](https://blog.csdn.net/weixin_34104341/article/details/91746431)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [python 批量txtxml](https://blog.csdn.net/m0_46529214/article/details/124495369)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 83
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值