xml转txt

"""
作者: stark
日期: 2024年 国庆前夕
根据XML文件中的标签名自动找到相应的图像文件,并根据实际图像尺寸将XML格式转换为YOLO对应的txt格式。这个脚本假设XML文件中的图像文件名与实际图像文件名相对应,并且图像文件存储在指定的文件夹中。
直接运行就可以,运行后,输入一个主路径(存放有标签和图片)就可以。会自动在该路径下生成output_txt文件夹,里面就是转换好的txt文件。
"""
import xml.etree.ElementTree as ET
import os
from PIL import Image

def find_image(filename, base_dir):
    # 在整个base_dir路径下查找图像文件
    for root, dirs, files in os.walk(base_dir):
        if filename in files:
            return os.path.join(root, filename)
    return None

def convert_voc_to_yolo(xml_file, output_dir, class_mapping, img_dir):
    # 解析XML文件
    tree = ET.parse(xml_file)
    root = tree.getroot()

    # 获取图像的文件名
    filename = root.find('filename').text

    # 在指定的图像文件夹或整个目录中查找图像
    img_path = find_image(filename, img_dir)
    if not img_path:
        print(f"找不到图像文件:{filename}")
        return

    # 打开图像,获取宽度和高度
    try:
        with Image.open(img_path) as img:
            img_width, img_height = img.size
    except FileNotFoundError:
        print(f"找不到图像文件:{img_path}")
        return

    # 创建输出文件的TXT路径
    txt_file = os.path.join(output_dir, os.path.splitext(filename)[0] + '.txt')

    with open(txt_file, 'w') as f_out:
        # 遍历所有object节点
        for obj in root.findall('object'):
            class_name = obj.find('name').text

            # 跳过没有定义的类别
            if class_name not in class_mapping:
                continue

            class_id = class_mapping[class_name]
            bndbox = obj.find('bndbox')

            # 获取边界框的坐标 (xmin, ymin, xmax, ymax)
            xmin = int(bndbox.find('xmin').text)
            ymin = int(bndbox.find('ymin').text)
            xmax = int(bndbox.find('xmax').text)
            ymax = int(bndbox.find('ymax').text)

            # 计算 YOLO 格式中的 (center_x, center_y, width, height),并归一化
            center_x = (xmin + xmax) / 2.0 / img_width
            center_y = (ymin + ymax) / 2.0 / img_height
            width = (xmax - xmin) / img_width
            height = (ymax - ymin) / img_height

            # 写入YOLO格式的标签
            f_out.write(f"{class_id} {center_x:.6f} {center_y:.6f} {width:.6f} {height:.6f}\n")

    print(f"转换完成:{txt_file}")

if __name__ == "__main__":
    # 你的类别映射 (VOC类名: YOLO类ID)
    class_mapping = {
        'person': 0,
        'car': 1,
        'bicycle': 2,
        # 根据你的数据集添加更多类别
    }

    # 输入路径
    base_dir = input("请输入主目录路径:")

    output_dir = os.path.join(base_dir, "output_txt")
    img_dir = base_dir  # 假设图像文件和XML文件在同一个主目录或其子目录中

    os.makedirs(output_dir, exist_ok=True)

    # 递归查找所有XML文件
    for root, dirs, files in os.walk(base_dir):
        for file in files:
            if file.endswith(".xml"):
                xml_path = os.path.join(root, file)
                convert_voc_to_yolo(xml_path, output_dir, class_mapping, img_dir)

### XML文件换为TXT格式的方法 对于将XML文件换成TXT格式的任务,存在多种方法和工具可以选择。 #### 方法一:手动解析与编写脚本 通过编程语言如Python实现自定义的换逻辑是一种常见的方式。可以利用`xml.etree.ElementTree`库读取XML文档的内容,并按照特定需求将其写入到TXT文件中[^2]。例如: ```python import xml.etree.ElementTree as ET def convert_xml_to_txt(xml_path, txt_path): tree = ET.parse(xml_path) root = tree.getroot() with open(txt_path, 'w') as f: for child in root: line = ''.join([str(subchild.text) + '\t' for subchild in child])[:-1] f.write(line + "\n") ``` 此函数会遍历给定XML文件中的所有子节点并将它们按制表符分隔的形式逐行写入新的TXT文件里。 #### 方法二:使用第三方库或工具 除了自己动手编码外,还可以寻找现成的支持这两种格式之间互的软件或者在线服务。比如,在某些情况下可以直接调用命令行工具完成这项工作;另外一些专门针对特定领域(如图像识别)的数据预处理阶段可能已经包含了这样的功能模块[^3]。 #### 方法三:基于框架的具体应用案例 当涉及到具体应用场景时,可能会有更专业的解决方案被提供出来。以目标检测为例,如果要从VOC风格的标注数据迁移到YOLO所使用的简单矩形框坐标表示法,则不仅需要考虑基本的信息映射关系,还要注意不同模型间特有的参数差异[^4]。此时可以通过如下方式提取所需信息并保存至TXT文件: ```python from os import listdir from xml.etree.ElementTree import parse classes = [] for file_name in listdir('annotations'): if not file_name.endswith('.xml'): continue doc = parse(f'annotations/{file_name}') objects = doc.findall('object') for obj in objects: name = obj.findtext('name') if name not in classes: classes.append(name) with open('classes.txt', 'w') as class_file: for c in sorted(classes): class_file.write(c + '\n') print("Classes have been written to `classes.txt`.") ``` 上述代码片段展示了如何收集所有的类别名称并存储在一个单独的文本文件中以便后续训练过程使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值