脚本 yolov5数据集转换 txt_xml xml_txt

脚本 yolov5数据集转换 txt_xml xml_txt

txt_xml

import os
import xml.etree.ElementTree as ET
from PIL import Image
import numpy as np

# 图片文件夹,后面的/不能省
img_path = 'G:/Zhiwei/test/line_data/train/images/'

# txt文件夹,后面的/不能省
labels_path = 'G:/Zhiwei/test/line_data/train/labels/'

# xml存放的文件夹,后面的/不能省
annotations_path = 'G:/Zhiwei/test/line_data/train/labels_xml/'

labels = os.listdir(labels_path)

# 类别
classes = ["fault1","fault2","fault3"]  #类别名

# 图片的高度、宽度、深度
sh = sw = sd = 0

def write_xml(imgname, sw, sh, sd, filepath, labeldicts):
    '''
    imgname: 没有扩展名的图片名称
    '''

    # 创建Annotation根节点
    root = ET.Element('Annotation')

    # 创建filename子节点,无扩展名                 
    ET.SubElement(root, 'filename').text = str(imgname)        

    # 创建size子节点 
    sizes = ET.SubElement(root,'size')                                      
    ET.SubElement(sizes, 'width').text = str(sw)
    ET.SubElement(sizes, 'height').text = str(sh)
    ET.SubElement(sizes, 'depth').text = str(sd) 

    for labeldict in labeldicts:
        objects = ET.SubElement(root, 'object')                 
        ET.SubElement(objects, 'name').text = labeldict['name']
        ET.SubElement(objects, 'pose').text = 'Unspecified'
        ET.SubElement(objects, 'truncated').text = '0'
        ET.SubElement(objects, 'difficult').text = '0'
        bndbox = ET.SubElement(objects,'bndbox')
        ET.SubElement(bndbox, 'xmin').text = str(int(labeldict['xmin']))
        ET.SubElement(bndbox, 'ymin').text = str(int(labeldict['ymin']))
        ET.SubElement(bndbox, 'xmax').text = str(int(labeldict['xmax']))
        ET.SubElement(bndbox, 'ymax').text = str(int(labeldict['ymax']))
    tree = ET.ElementTree(root)
    tree.write(filepath, encoding='utf-8')


for label in labels:
    with open(labels_path + label, 'r') as f:
        img_id = os.path.splitext(label)[0]
        contents = f.readlines()
        labeldicts = []
        for content in contents:
            # !!!这里要看你的图片格式了,我这里是png,注意修改
            img = np.array(Image.open(img_path + label.strip('.txt') + '.jpg'))

            # 图片的高度和宽度
            sh, sw, sd = img.shape[0], img.shape[1], img.shape[2]
            content = content.strip('\n').split()
            x = float(content[1])*sw
            y = float(content[2])*sh
            w = float(content[3])*sw
            h = float(content[4])*sh

            # 坐标的转换,x_center y_center width height -> xmin ymin xmax ymax
            new_dict = {'name': classes[int(content[0])],
                        'difficult': '0',
                        'xmin': x+1-w/2,                     
                        'ymin': y+1-h/2,
                        'xmax': x+1+w/2,
                        'ymax': y+1+h/2
                        }
            labeldicts.append(new_dict)
        write_xml(img_id, sw, sh, sd, annotations_path + label.strip('.txt') + '.xml', labeldicts)

xml_txt

import os
import xml.etree.ElementTree as ET
from decimal import Decimal
 
dirpath = '/home/*/'  # 原来存放xml文件的目录

newdir = '/home/*/'  # 修改label后形成的txt目录
 
if not os.path.exists(newdir):
    os.makedirs(newdir)
 
for fp in os.listdir(dirpath):
 
    root = ET.parse(os.path.join(dirpath, fp)).getroot()
 
    xmin, ymin, xmax, ymax = 0, 0, 0, 0
    sz = root.find('size')
    width = float(sz[0].text)
    height = float(sz[1].text)
    filename = root.find('filename').text
    print(fp)
    with open(os.path.join(newdir, fp.split('.')[0] + '.txt'), 'a+') as f:
        for child in root.findall('object'):  # 找到图片中的所有框
 
            sub = child.find('bndbox')  # 找到框的标注值并进行读取
            sub_label = child.find('name')
            xmin = float(sub[0].text)
            ymin = float(sub[1].text)
            xmax = float(sub[2].text)
            ymax = float(sub[3].text)
            try:  # 转换成yolov的标签格式,需要归一化到(0-1)的范围内
                x_center = Decimal(str(round(float((xmin + xmax) / (2 * width)),6))).quantize(Decimal('0.000000'))
                y_center = Decimal(str(round(float((ymin + ymax) / (2 * height)),6))).quantize(Decimal('0.000000'))
                w = Decimal(str(round(float((xmax - xmin) / width),6))).quantize(Decimal('0.000000'))
                h = Decimal(str(round(float((ymax - ymin) / height),6))).quantize(Decimal('0.000000'))
                print(str(x_center) + ' ' + str(y_center)+ ' '+str(w)+ ' '+str(h))
                #读取需要的标签
                #if sub_label.text == 'armor':
                f.write(' '.join([str(0), str(x_center), str(y_center), str(w), str(h) + '\n']))

            except ZeroDivisionError:
                print(' width有问题')
            '''有其他标签选用
                            if sub_label.text == 'xxx':
                                f.write(' '.join([str(1), str(x_center), str(y_center), str(w), str(h) + '\n']))
                            if sub_label.text == 'xxx':
                                f.write(' '.join([str(2), str(x_center), str(y_center), str(w), str(h) + '\n']))'''
            # with open(os.path.join(newdir, fp.split('.')[0] + '.txt'), 'a+') as f:
            #     f.write(' '.join([str(2), str(x_center), str(y_center), str(w), str(h) + '\n']))

YOLOv5 是一个流行的开源目标检测框架,它通常处理的是图像数据,并非XML文件。如果你有包含物体位置信息的XML标注文件,比如PASCAL VOC或者COCO的数据集格式,想要转换YOLOv5所需的.txt格式,这个过程通常涉及两个步骤: 1. **XMLTXT转换**: - 使用专门的工具或脚本读取XML文件,解析出每个物体的位置、大小和类别标签等信息。 - 每行记录一个目标的坐标(如左上角x, y,宽度,高度),以及类别标签。 - 格式通常是每张图片一行,每一行包含像`class x_center y_center width height`这样的结构。 2. **批量转换**: - 对于批量的XML文件,可以编写一个Python脚本通过循环遍历目录下的所有XML文件,对每一个文件执行解析和转换操作。 - 可能需要利用`xml.etree.ElementTree`库来解析XML,或者使用现成的库如`xmltodict`。 以下是一个简单的示例Python脚本片段,用于转换单个XML文件: ```python import xml.etree.ElementTree as ET def convert_xml_to_txt(xml_file): tree = ET.parse(xml_file) root = tree.getroot() with open(xml_file.replace('.xml', '.txt'), 'w') as f: for obj in root.findall('object'): class_name = obj.find('name').text bbox = obj.find('bndbox') x_center = (int(bbox.find('xmin').text) + int(bbox.find('xmax').text)) / 2 y_center = (int(bbox.find('ymin').text) + int(bbox.find('ymax').text)) / 2 width = int(bbox.find('xmax').text) - int(bbox.find('xmin').text) height = int(bbox.find('ymax').text) - int(bbox.find('ymin').text) f.write(f"{class_name} {x_center} {y_center} {width} {height}\n") # 使用方法 convert_xml_to_txt('example.xml') ``` 记得根据实际情况修改路径和脚本细节。对于批量转换,你可以用os模块的list comprehension来处理整个目录下的所有文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值