使用labelimg标注的xml文件转化为yolov5所需的txt文件

该博客介绍了一个用于将COCO128数据集的XML标注转换为YoloV5所需格式的Python脚本。脚本遍历指定目录下的所有XML文件,读取每个对象的名称、边界框坐标,并进行归一化处理,然后将结果写入新的TXT文件中,同时将原始XML文件移动到备份目录。此过程对于训练目标检测模型如YoloV5至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

yolov5所需的格式如下图:
第一位是类别的索引,,,然后是归一化后的中心点x,y,宽高w,h。
coco
转化代码如下:
GT_PATH路径下放所有的xml文件

# -*- coding: utf-8 -*-
"""
Time    : 2022/5/14 17:18
Author  : cong
"""
import sys
import os
import glob
import xml.etree.ElementTree as ET

names = ['hatch', 'cargo', 'aeroplane']
GT_PATH = 'datasets/coco128/labels/train2017/'
#print(GT_PATH)
os.chdir(GT_PATH)
xml_list = glob.glob('*.xml')
if not os.path.exists("backup"):
    os.makedirs("backup")
for tmp_file in xml_list:
    #print(tmp_file)
    # 1. create new file (VOC format)

    with open(tmp_file.replace(".xml", ".txt"), "a") as new_f:

        root = ET.parse(tmp_file).getroot()
        size = root.find('size')
        for obj in root.findall('object'):
          obj_name = obj.find('name').text
          obj_index = names.index(obj_name)
          bndbox = obj.find('bndbox')
          image_w = int(size.find('width').text)
          image_h = int(size.find('height').text)
          x_min = int(bndbox.find('xmin').text)
          x_max = int(bndbox.find('xmax').text)
          y_min = int(bndbox.find('ymin').text)
          y_max = int(bndbox.find('ymax').text)
          x = ((x_min + x_max)/2)/image_w
          y = ((y_min + y_max)/2)/image_h
          w = (x_max - x_min) /image_w
          h = (y_max - y_min) /image_h
          new_f.write("%d %s %s %s %s\n" % (obj_index, x, y, w, h))
    # 2. move old file (xml format) to backup
    os.rename(tmp_file, os.path.join("backup", tmp_file))
print("Conversion completed!")


### 将XML文件转换为YOLOv5所需TXT格式 为了使YOLOv5能够读取由`labelimg`工具生成的`.xml`标注文件,这些文件需被转换成YOLOv5所支持的`.txt`格式。此过程涉及解析原始的XML文件,并按照特定结构重新组织数据以便于模型训练。 #### 解析XML文件内容 每个图像对应一个XML文件,其中包含了该图中所有对象的位置信息以及它们所属类别名称。对于每一个目标而言,在新的文本文件里应该记录其边界框坐标(相对于图片尺寸的比例值)和类别的索引号而非文字描述[^1]。 #### 创建类别列表 创建一个名为`classes.txt`的文档来保存所有的物体分类名。每一行代表一类物品;顺序决定了后续编写到其他位置时使用的编号——即第几行就对应着ID为多少的对象种类[^3]。 #### 转换逻辑实现 下面是一个Python脚本的例子,它实现了上述提到的功能: ```python import os from xml.etree import ElementTree as ET def convert(size, box): dw = 1./(size[0]) dh = 1./(size[1]) x = (box[0] + box[1])/2.0 - 1 y = (box[2] + box[3])/2.0 - 1 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 xml_to_txt(xml_file, classes_file, output_dir): tree = ET.parse(xml_file) root = tree.getroot() with open(classes_file, 'r') as f: classes = [line.strip() for line in f.readlines()] image_size = [ int(root.find('size').find('width').text), int(root.find('size').find('height').text) ] txt_filename = os.path.join(output_dir, os.path.splitext(os.path.basename(xml_file))[0]+'.txt') with open(txt_filename,'w') as out_file: 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) bndbox = obj.find('bndbox') bb = ( float(bndbox.find('xmin').text), float(bndbox.find('xmax').text), float(bndbox.find('ymin').text), float(bndbox.find('ymax').text) ) converted_bb = convert(image_size,bb) out_file.write(f"{cls_id} {' '.join([str(a) for a in converted_bb])}\n") # 假设当前工作路径下有annotations目录存放了所有的.xml文件, # 并且有一个classes.txt定义好了各个类别的名字。 for file_name in os.listdir('./annotations/'): if file_name.endswith('.xml'): xml_to_txt( './annotations/' + file_name, './classes.txt', './labels/' ) ``` 通过运行以上代码片段可以批量处理指定文件夹内的所有XML文件,并将其转化为适合YOLOv5框架使用的标签形式存储在另一个文件夹内。同时也会自动生成包含各类别名称映射关系的`classes.txt`文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值