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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值