Bootstrap

xml 转 txt ,轻松转变(亲测有效)

import os
import xml.etree.ElementTree as ET

//只需要改这三项
input_dir = r'H:/PYTHON_Proj/basketball/Annotations'
out_dir = r'H:/PYTHON_Proj/basketball/txt'
class_list = ["basketball"]


def file_name(input_dir):
    """列出输入目录下所有的XML文件名(不带扩展名)"""
    files = [os.path.splitext(f)[0] for f in os.listdir(input_dir) if f.endswith('.xml')]
    return files


def convert_coordinate(imgshape, bbox):
    """将边界框坐标从像素转换为归一化坐标"""
    xmin, ymin, xmax, ymax = bbox
    width, height = imgshape
    dw, dh = 1. / width, 1. / height
    x, y = (xmin + xmax) / 2.0, (ymin + ymax) / 2.0
    w, h = xmax - xmin, ymax - ymin
    x, y, w, h = x * dw, y * dh, w * dw, h * dh
    return x, y, w, h


def read_xml(file_name):
    """读取XML文件并转换为TXT格式"""
    xml_path = os.path.join(input_dir, f"{file_name}.xml")
    tree = ET.parse(xml_path)
    root = tree.getroot()

    size = root.find('size')
    width = int(size.find('width').text)
    height = int(size.find('height').text)
    imgshape = (width, height)

    txt_result = ''
    for obj in root.findall('object'):
        obj_name = obj.find('name').text
        if obj_name in class_list:
            obj_id = class_list.index(obj_name)
            bbox = obj.find('bndbox')
            xmin, ymin, xmax, ymax = map(float, [bbox.find(x).text for x in ['xmin', 'ymin', 'xmax', 'ymax']])
            x, y, w, h = convert_coordinate(imgshape, (xmin, ymin, xmax, ymax))
            txt = f"{obj_id} {x} {y} {w} {h}\n"
            txt_result += txt

    txt_path = os.path.join(out_dir, f"{file_name}.txt")
    with open(txt_path, 'w') as f:
        f.write(txt_result)


def main():
    filelist = file_name(input_dir)
    print(class_list)
    for n, i in enumerate(filelist, start=1):
        print(f"第{n}个xml成功转换\n")
        read_xml(i)

        # 写入类别文件
    with open(os.path.join(out_dir, "classes.txt"), 'w') as f:
        for cls in class_list:
            f.write(f"{cls}\n")


if __name__ == "__main__":
    main()
;