yolov5的xml文件转txt文件格式(详细解释与完整代码供应)

news2024/12/25 12:15:58

文章目录

  • 前言
  • 一、yolov5训练数据格式介绍
    • 1、txt的类别对应说明
    • 2、txt的文件说明
    • 3、txt文件格式
    • 3、yolov5训练文件形式
  • 二、xml文件读取代码解读
  • 三、xml文件转txt文件
    • 1、xml转txt代码解读
    • 2、保存txt文件代码解读
  • 四、完整代码


前言

本文章实现xml数据格式转yolov5的txt格式,一方面共享读者直接使用,另一方面便于我能快速复制使用,以便yolov5模型快速训练。为此,我将写下本篇文章。主要内容包含yolov5训练数据格式介绍,xml代码解读及xml解读信息转为txt格式,并将所有内容附属整个源码。


提示:以下是本篇文章正文内容,下面案例可供参考

一、yolov5训练数据格式介绍

我以coco数据集转yolov5的txt格式说明。

1、txt的类别对应说明

coco数据集共有80个类别,yolov5将80个类别标签为0到79,其中0表示coco的第一个类别,即person,79表示coco对应的第80个类别,即toothbrush。

coco类别如下:

['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
        'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
        'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
        'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
        'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
        'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
        'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
        'hair drier', 'toothbrush']

2、txt的文件说明

一张图对应一个txt文件,其图片与txt名称相同,后缀不同。
假如一张图有7个目标需要检测,对应的txt文件有7行数据记录目标相应的信息。

3、txt文件格式

txt文件每行表示顺序为目标类别、目标中心点x、目标中心点y、目标宽、目标高,其中目标中心点与宽高需要归一化,也就是对应数据除以对应宽高。
假如一张图有2个目标,假设图像宽=1920,高=1080;
格式:类别,box中心点x坐标,中心点y坐标,box宽w,box高h;
目标信息如下:

bicycle,6080,20,40;
motorcycle,60100,80,240;

以coco类别对应转txt为:

1,60/192080/1080,20/1920,40/1080;
3,60/1920100/1080,80/1920,240/1080;

3、yolov5训练文件形式

一般是images和labels,当然你也可以自己取名字,但必须保证images与labels里面的文件名相同。
在这里插入图片描述
yolov5调用形式:

path: ../datasets/coco128  # dataset root dir
train: images/train  # train images (relative to 'path') 128 images
val: images/val  # val images (relative to 'path') 128 images
test:  # test images (optional)

以一张图转txt文件格式展示,如下:
在这里插入图片描述

二、xml文件读取代码解读

竟然是xml文件转yolov5的txt文件,最重要是xml文件信息读取,以下直接给代码读取xml信息。

代码如下:


def get_strfile(file_str, pos=-1):
    # 得到file_str / or \\ 的最后一个名称
    endstr_f_filestr = file_str.split('\\')[pos] if '\\' in file_str else file_str.split('/')[pos]
    return endstr_f_filestr


def read_xml(xml_root):
    '''
    :param xml_root: .xml文件
    :return: dict('cat':['cat1',...],'bboxes':[[x1,y1,x2,y2],...],'whd':[w ,h,d],'xml_name':xml_name)
    '''
    xml_name = get_strfile(xml_root)
    dict_info = {'cat': [], 'bboxes': [], 'box_wh': []}
    if os.path.splitext(xml_root)[-1] == '.xml':
        tree = ET.parse(xml_root)  # ET是一个xml文件解析库,ET.parse()打开xml文件。parse--"解析"
        root = tree.getroot()  # 获取根节点
        whd = root.find('size')
        whd = [float(whd.find('width').text), float(whd.find('height').text), float(whd.find('depth').text)]
        dict_info['xml_name'] = xml_name
        dict_info['whd'] = whd

        for obj in root.findall('object'):  # 找到根节点下所有“object”节点
            cat = str(obj.find('name').text)  # 找到object节点下name子节点的值(字符串)
            bbox = obj.find('bndbox')
            x1, y1, x2, y2 = [float(bbox.find('xmin').text),
                              float(bbox.find('ymin').text),
                              float(bbox.find('xmax').text),
                              float(bbox.find('ymax').text)]
            b_w = x2 - x1 + 1
            b_h = y2 - y1 + 1
            dict_info['cat'].append(cat)
            dict_info['bboxes'].append([x1, y1, x2, y2])
            dict_info['box_wh'].append([b_w, b_h])

    else:
        print('[inexistence]:{} suffix is not xml '.format(xml_root))
    return dict_info

get_strfile函数是将xml_root绝对路径转换,获得xml名称函数。
read_xml(xml_root)函数是直接输入单个xml的绝对路径,输出为dict_info。

dict_info = {'cat': [], 'bboxes': [], 'box_wh': []}

cat与bboxes为列表,一一对应目标,cat为类别名称(一般为英文命名);bboxes为对应box宽,分别表示左上点坐标x1,y1与右下点坐标x2,y2;box_wh记录该xml的size,为图像宽、高、通道。

三、xml文件转txt文件

1、xml转txt代码解读

在二中获得xml中的信息,这里将xml信息转yolov5的txt信息,其代码如下:

def xml_info2yolotxt(xml_info, classes_lst):
    cat_lst, bboxes_lst, whd, xml_name \
        = xml_info['cat'], xml_info['bboxes'], xml_info['whd'], xml_info['xml_name']
    txt_name = xml_name[:-3] + 'txt'
    txt_info = {'info': [], 'txt_name': txt_name}
    for i, cat in enumerate(cat_lst):
        if cat in classes_lst:  # 判断在classes_lst中才会保存该条信息
            cat_id = list(classes_lst).index(str(cat))
            x1, y1, x2, y2 = bboxes_lst[i]
            x, y, w, h = (x1 + x2) / 2, (y1 + y2) / 2, x2 - x1, y2 - y1
            dw = 1.0 / whd[0]
            dh = 1.0 / whd[1]
            x = x * dw
            w = w * dw
            y = y * dh
            h = h * dh
            txt_info['info'].append([cat_id, x, y, w, h])
    return txt_info

该函数xml_info2yolotxt(xml_info, classes_lst)的xml_info信息来自二中得到的结果,classes_lst表示类别的列表,若为coco128表示一中coco类别。输出为txt_info信息,实际已转为txt文件格式信息。

2、保存txt文件代码解读

保存实际来源上面转txt的输出信息,保存到本地,实现txt文件保存,其中txt格式很重要out_file.write(str(cls_id) + " " + " ".join([str(b) for b in box]) + '\n'),详情代码如下:

def save_txt(txt_info, out_dir):
    txt_name = txt_info['txt_name']
    info = txt_info['info']
    out_file = open(os.path.join(out_dir, txt_name), 'w')  # 转换后的txt文件存放路径
    for a in info:
        cls_id = a[0]
        box = a[1:]
        out_file.write(str(cls_id) + " " + " ".join([str(b) for b in box]) + '\n')

四、完整代码

以下代码读取一个xml转换为txt格式,并保存yolov5可直接使用的txt文件,完整代码如下:

import os
import xml.etree.ElementTree as ET

def get_strfile(file_str, pos=-1):
    # 得到file_str / or \\ 的最后一个名称
    endstr_f_filestr = file_str.split('\\')[pos] if '\\' in file_str else file_str.split('/')[pos]
    return endstr_f_filestr

def read_xml(xml_root):
    '''
    :param xml_root: .xml文件
    :return: dict('cat':['cat1',...],'bboxes':[[x1,y1,x2,y2],...],'whd':[w ,h,d],'xml_name':xml_name)
    '''
    xml_name = get_strfile(xml_root)
    dict_info = {'cat': [], 'bboxes': [], 'box_wh': []}
    if os.path.splitext(xml_root)[-1] == '.xml':
        tree = ET.parse(xml_root)  # ET是一个xml文件解析库,ET.parse()打开xml文件。parse--"解析"
        root = tree.getroot()  # 获取根节点
        whd = root.find('size')
        whd = [float(whd.find('width').text), float(whd.find('height').text), float(whd.find('depth').text)]
        dict_info['xml_name'] = xml_name
        dict_info['whd'] = whd
        for obj in root.findall('object'):  # 找到根节点下所有“object”节点
            cat = str(obj.find('name').text)  # 找到object节点下name子节点的值(字符串)
            bbox = obj.find('bndbox')
            x1, y1, x2, y2 = [float(bbox.find('xmin').text),
                              float(bbox.find('ymin').text),
                              float(bbox.find('xmax').text),
                              float(bbox.find('ymax').text)]
            b_w = x2 - x1 + 1
            b_h = y2 - y1 + 1
            dict_info['cat'].append(cat)
            dict_info['bboxes'].append([x1, y1, x2, y2])
            dict_info['box_wh'].append([b_w, b_h])

    else:
        print('[inexistence]:{} suffix is not xml '.format(xml_root))
    return dict_info

def save_txt(txt_info, out_dir):
    txt_name = txt_info['txt_name']
    info = txt_info['info']
    out_file = open(os.path.join(out_dir, txt_name), 'w')  # 转换后的txt文件存放路径
    for a in info:
        cls_id = a[0]
        box = a[1:]
        out_file.write(str(cls_id) + " " + " ".join([str(b) for b in box]) + '\n')

def xml_info2yolotxt(xml_info, classes_lst):
    cat_lst, bboxes_lst, whd, xml_name \
        = xml_info['cat'], xml_info['bboxes'], xml_info['whd'], xml_info['xml_name']
    txt_name = xml_name[:-3] + 'txt'
    txt_info = {'info': [], 'txt_name': txt_name}
    for i, cat in enumerate(cat_lst):
        if cat in classes_lst:  # 判断在classes_lst中才会保存该条信息
            cat_id = list(classes_lst).index(str(cat))
            x1, y1, x2, y2 = bboxes_lst[i]
            x, y, w, h = (x1 + x2) / 2, (y1 + y2) / 2, x2 - x1, y2 - y1
            dw = 1.0 / whd[0]
            dh = 1.0 / whd[1]
            x = x * dw
            w = w * dw
            y = y * dh
            h = h * dh
            txt_info['info'].append([cat_id, x, y, w, h])
    return txt_info

def read_txt(file_path):
    with open(file_path, 'r') as f:
        content = f.read().splitlines()
    return content

if __name__ == '__main__':

    xml_root = r'E:\project\data\hncy_data\img_xml_ori\hw_data\images\train\19841.xml'
    classes_lst=['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
        'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
        'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
        'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
        'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
        'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
        'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
        'hair drier', 'toothbrush']  # class names
    xml_info = read_xml(xml_root)
    txt_info = xml_info2yolotxt(xml_info, classes_lst)
    save_txt(txt_info, '')



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/928755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

7、Idea下载安装与激活

1、下载 1.1 官网地址 官网地址 https://www.jetbrains.com/idea/ 点击访问 1.2 官网首页 1.3 点击右上角dowload进入以下页面选择版本 1.4 选择需要的版本进行下载 2、安装

日志系统——全局接口/宏函数优化

日志器模块完成后,我们的日志系统差不多就算完成了,但是在用户使用方面仍然需要优化 如上所示,当我们需要从日志器管理器中获取日志器时需要用上面一长串的方式获取,而我们写入日志时还需要让用户用宏表示文件和行号,这…

数据资产入表正式落地!企业如何进行数据资产管理

数字化时代,数据已经成为了个人、机构、企业乃至国家的重要战略资产。近日,财政部正式对外发布《企业数据资源相关会计处理暂行规定》,并自2024年1月1日开始施行。数据资产入表政策落地节奏超预期,标志着国家把数据作为生产要素的…

分发饼干【贪心算法】

分发饼干 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个…

Linux下的Shell基础——Shell概述和入门(一)

前言: Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。为了方便后续的学习,我们需要学习在Linux系统下的Shell编程 目录 一、Shell概述 1.Linux 提供的 Shell 解析器有 2. 默认的解析器是 bash 二、Shell 脚本入门 1.脚…

转置卷积的应用

目录 矩阵转置 一、转置卷积的背景 二、转置卷积的应用 三、转置卷积的区别 卷积 矩阵转置 矩阵的转置在信息处理中起到了重要的作用。在计算机科学领域,矩阵常用于表示图像、音频和视频等多媒体数据。当我们需要对这些数据进行处理时,常常需要进行…

前置微小信号放大器的作用是什么

前置微小信号放大器是一种电子设备,用于将弱信号放大到足够的水平以供后续处理。它在许多领域都有广泛的应用,如通信系统、无线电接收机、传感器接口等。 前置微小信号放大器的主要作用是增加信号的强度。当我们处理微弱信号时,如果不进行放大…

FMEA介绍以及在制造业中的应用

在现代制造业中,确保产品质量和流程稳定性是至关重要的任务。为了应对潜在的故障和风险,企业采用了多种方法和工具,其中之一便是故障模式和影响分析(FMEA)。FMEA是一种系统性、结构化的方法,用于识别潜在的…

【word密码】如何取消word限制?忘记密码?

Word文档设置了限制编辑,打开文件之后发现功能栏中都是灰色的,无法编辑文件,这种情况,我们点击审阅 – 限制编辑 然后在右侧会有弹框出现,我们点击底下的【停止保护】,输入word密码就可以取消限制编辑了 如…

2023高教社杯数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

app宿主环境

1.宿主环境的概念 2.宿主环境组成 2.1通信模型 2.2小程序的启动过程 2.3页面渲染过程

2023年高教社杯 国赛数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 算法介绍FP树表示法构建FP树实现代码 建模资料 ## 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法,就是频繁模式树算法&#xff0c…

在腾讯云服务器OpenCLoudOS系统中安装Jenkins(有图详解)

Jenkins介绍 Jenkins是一个开源软件项目,是基于java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。 将项目代码的svn地址配置在Jenkins,就可以直接在Je…

SPI2外设驱动-W25Q64 SPI接口初始化

前言 (1)本系列是基于STM32的项目笔记,内容涵盖了STM32各种外设的使用,由浅入深。 (2)小编使用的单片机是STM32F105RCT6,项目笔记基于小编的实际项目,但是博客中的内容适用于各种单片…

Vue实现父子组件相互传值

在Vue中,父组件可以通过以下几种方式获取子组件传递的值: 1.Props(属性):父组件通过在子组件上定义属性(props),将数据传递给子组件。子组件在使用props接收数据后,父组…

【C++】C++ 引用详解 ③ ( 函数返回值不能是 “ 局部变量 “ 的引用或指针 | 函数内的 “ 局部变量 “ 的引用或指针做函数返回值无意义 )

文章目录 一、函数返回值不能是 " 局部变量 " 的引用或指针1、引用通常做右值2、函数返回值特点3、函数内的 " 局部变量 " 的引用或指针做函数返回值无意义 二、代码示例 - " 局部变量 " 引用或指针做函数返回值测试 一、函数返回值不能是 "…

为什么要使用IP地址进行定位

IP地址定位是一种以互联网协议地址(IP地址)为基础的技术,它能够准确地确定一个设备在互联网上的位置。这种技术的应用范围非常广泛,从个人用户到企业机构甚至是国家安全和网络安全等领域都需要使用IP地址定位。 首先,I…

uniapp接入广告的问题总结

Uniapp官方解决方案 uni-app 支持接入uni-ad广告联盟,开发者可实现一次开发,多端变现。 uni-ad 支持开屏、信息流、激励视频、视频流、悬浮红包、推送等丰富的广告形式; uni-ad 聚合了全网所有主流广告源,包括腾讯优量汇、字节…

MIA文献阅读 ——医学图像处理在慢性肾脏疾病评估中的最新进展【2021】

目录 0 摘要1 引言2 磁共振成像(MRI)2.1 扩散磁共振成像2.1.1 扩散加权成像(DWI)2.1.2 扩散张量成像(DTI) 2.2 血氧水平依赖成像2.3 动脉自旋标记2.4 动态对比增强磁共振成像2.5 T1和T2映射2.6 磁化转移磁共振成像2.7 磁共振弹性成像2.8 其他磁共振成像技术 3 其他成像方式3.1 …

学习记录——FeatEnHancer

FeatEnHancer: Enhancing Hierarchical Features for Object Detection and Beyond Under Low-Light Vision 一种适用于任意低光照任务增强方法 ICCV 2023 提出了FeatEnHancer,一种用于低光照视觉任务的增强型多尺度层次特征的新方法。提议的解决方案重点增强相关特…