【将xml文件转yolov5训练数据txt标签文件】连classes.txt都可以生成

将xml文件转yolov5训练数据txt标签文件

  • 前言
  • 一、代码
    • 解析
  • 二、使用方法
  • 总结


前言

找遍全网,我觉得写得最详细的就是这个博文⇨将xml文件转yolov5训练数据txt标签文件
虽然我还是没有跑成功。那个正则表达式我不会改QWQ,但是不妨碍我会训练ai。
最终成功了,现在就把训练成功的代码贴上来,顺便加点注释,英雄不问出处吧!
在这里插入图片描述
-------2024/6/9


一、代码

# 实现xml格式转yolov5格式

import os
import xml.etree.ElementTree as ET

# 定义一个函数用于从XML文件中提取类别信息
def extract_classes_from_xml(xml_file, all_classes):
    global tree
    tree = ET.parse(xml_file)
    for obj in tree.findall('object'):
        class_name = obj.find('name').text
        if class_name not in all_classes:
            all_classes[class_name] = len(all_classes)
    return all_classes

def main():
    # 准备保存 classes 信息的文件
    classes_file_path = 'S:\\IMG\\PCB_DATASET_VOC\\VOCdevkit\\VOC2007\\labels\\classes.txt'

    # 遍历XML文件夹
    xml_folder = 'S:\\IMG\\PCB_DATASET_VOC\\VOCdevkit\\VOC2007\\Annotations'
    txt_folder = 'S:\\IMG\\PCB_DATASET_VOC\\VOCdevkit\\VOC2007\\labels'

    all_classes = {}

    # 准备保存类别信息的文件
    with open(classes_file_path, 'w') as classes_file:
        for xml_file in os.listdir(xml_folder):
            if not xml_file.endswith('.xml'):
                continue

            image_id = os.path.splitext(xml_file)[0]

            # 从XML文件中提取类别信息
            all_classes = extract_classes_from_xml(os.path.join(xml_folder, xml_file), all_classes)

            with open(os.path.join(txt_folder, f'{image_id}.txt'), 'w') as txt_file:
                for obj in ET.parse(os.path.join(xml_folder, xml_file)).findall('object'):
                    class_name = obj.find('name').text
                    class_id = all_classes[class_name]

                    bbox = obj.find('bndbox')
                    x_min = float(bbox.find('xmin').text)
                    y_min = float(bbox.find('ymin').text)
                    x_max = float(bbox.find('xmax').text)
                    y_max = float(bbox.find('ymax').text)

                    width = x_max - x_min
                    height = y_max - y_min
                    x_center = x_min + width / 2
                    y_center = y_min + height / 2

                    img_width = float(tree.find('size').find('width').text)
                    img_height = float(tree.find('size').find('height').text)

                    x_center /= img_width
                    y_center /= img_height
                    width /= img_width
                    height /= img_height

                    line = f"{class_id} {x_center} {y_center} {width} {height}\n"
                    txt_file.write(line)

            print(f" {image_id}.xml to {image_id}.txt 转换完成")

        for class_name, class_id in all_classes.items():
            classes_file.write(f"{class_name}\n")

    print("转换完成,祝愿您顺利")

if __name__ == "__main__":
    main()

解析

难点只有with open(classes_file_path, 'w') as classes_file这里的


从一个XML文件中读取标注信息,并将这些信息转换成用于训练图像识别模型的格式。
下面是对这段代码的逐行解释:

  • 打开文件用于写入类别信息
with open(classes_file_path, 'w') as classes_file:

这里打开了classes_file_path指向的文件用于写入。classes_file会用来保存所有的类别名称。

  • 这段代码遍历了xml_folder中的所有文件。os.listdir()返回一个包含指定目录中所有文件和目录名称的列表。
for xml_file in os.listdir(xml_folder):
  • 这个条件检查确保只处理以.xml结尾的文件。如果不是XML文件,则跳过当前循环迭代。
if not xml_file.endswith('.xml'): 
    continue
  • 这里使用os.path.splitext()函数将文件名和扩展名分离,并获取文件名部分。image_id现在包含了没有扩展名的文件名。
image_id = os.path.splitext(xml_file)[0]

os.path.splitext()函数可以将文件路径分割成路径名和文件扩展名两部分,并以元组的形式返回。
这样做的原因是因为在很多操作系统中,文件名通常包含了文件的路径以及文件扩展名,如/path/to/file.xml。通过使用os.path.splitext(),我们可以方便地分离出文件名和扩展名部分,进而更方便地对它们进行处理。

例如,假设xml_file的值为"example.xml",那么os.path.splitext(xml_file)将返回(“example”, “.xml”),然后通过[0]索引取得文件名部分"example"。这样就实现了将文件名和扩展名分离的目的。

总的来说,os.path.splitext()函数在处理文件路径和文件名时非常实用,能够帮助我们轻松地获取文件名和扩展名,从而进行文件处理操作。

  • 从XML文件中提取类别信息
all_classes = extract_classes_from_xml(os.path.join(xml_folder, xml_file), all_classes)

这里调用了extract_classes_from_xml()函数,一个从XML文件中提取所有类别名称的函数,并将这些类别名称保存到一个字典中,其中类别名称是键,而类别ID是值。

函数extract_classes_from_xml接收两个参数:xml_file和all_classes。
1、xml_file是XML文件的路径,
2、all_classes是一个字典,用于存储已知的所有类别名称和它们的ID。

在这里插入图片描述

在函数内部,首先使用ET.parse(xml_file)解析XML文件,并将其存储在全局变量tree中。然后,使用tree.findall(‘object’)遍历所有 < object >标签。对于每个< object >标签,提取其name标签中的文本,即类别名称。如果这个类别名称之前没有在all_classes字典中出现过,那么就将其添加到字典中,并设置其ID为当前类别ID。这里的类别ID是字典中类别名称的数量,即len(all_classes)。
最后,函数返回更新后的类别字典all_classes。这个字典包含了所有在XML文件中出现的类别名称及其对应的ID。

在主代码中,每次调用extract_classes_from_xml时,都会更新all_classes字典,因为它包含了所有之前遇到过的类别名称。这样,最终all_classes将包含所有的类别名称和它们的ID,这些信息将被用于创建训练数据文件和类别文件。

  • 这段代码打开了一个文件用于写入,该文件位于txt_folder中,文件名是image_id加上.txt扩展名。
with open(os.path.join(txt_folder, f'{image_id}.txt'), 'w') as txt_file:
  • 这段代码遍历了XML文档中的所有< object >标签。ET是ElementTree的缩写,.parse()函数解析XML文件
for obj in ET.parse(os.path.join(xml_folder, xml_file)).findall('object'): 
  • 这段代码从每个< object >标签中提取类别的名称,并通过all_classes字典将类别名称映射到一个类别ID。
class_name = obj.find('name').text
class_id = all_classes[class_name]
  • 提取了边界框的四个坐标信息,即左上角和右下角的(x, y)值。
bbox = obj.find('bndbox')
x_min = float(bbox.find('xmin').text)
y_min = float(bbox.find('ymin').text)
x_max = float(bbox.find('xmax').text)
y_max = float(bbox.find('ymax').text)
  • 计算了边界框的宽度、高度以及中心点的位置。
width = x_max - x_min
height = y_max - y_min
x_center = x_min + width / 2
y_center = y_min + height / 2
  • 这里提取了图像的宽度和高度。
img_width = float(tree.find('size').find('width').text)
img_height = float(tree.find('size').find('height').text)
  • 将边界框的坐标和尺寸进行归一化,即将它们除以图像的宽度和高度,使它们落在0到1之间。
x_center /= img_width
y_center /= img_height
width /= img_width
height /= img_height
  • 生成了保存到文本文件的一行数据,其中包含了类别ID、归一化后的边界框中心坐标、宽度和高度。
line = f"{class_id} {x_center} {y_center} {width} {height}\n"
txt_file.write(line)

最后,将每个XML文件中的目标信息转换并写入一个对应的txt文件中,同时将类别信息写入classes_file中。整个过程将针对每个XML文件中的目标执行,最终完成目标检测训练数据的准备工作。

二、使用方法

网上下载的数据集有的是xml的,复制路径
在这里插入图片描述
创建一个目标位置的文件夹。
在这里插入图片描述

将地址填入合适的地方
在这里插入图片描述
运行就行了
在这里插入图片描述
对应的文件也可以了
在这里插入图片描述
连classes都能识别出来!!!


总结

这篇文章依旧没有总结

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于从大平台跳转各个应用,更新应用前端包后,显示的仍是旧的内容,刷新应用页面后方才显示新的内容的问题的排查和解决

我们从绿洲物联平台跳转智能锁应用&#xff0c; 如下&#xff0c;我们可以看到&#xff0c;我们是通过a标签去跳转应用的。但是我们打开控制台的话&#xff0c;因为a标签是另外新开一个页面&#xff0c;我们看不到新页面的html文档的加载情况。 我们可以临时把_blank改成_sel…

WPF 上位机 Modbus 入门必备的信息 C# 开发对接

关于Modbus协议 Modbus协议是MODICON(莫迪康)(现施耐德品牌)在1979年开发的&#xff0c;是全球第一个真正用于现场的总线协议; Modbus协议是应用于电子控制器上的一种通用语言。通过此协议&#xff0c;可以实现控制器相互之间、控制器经由网络和其实设备之间的通 信。 Modbus特…

推荐 3 款小巧的文件压缩、投屏和快速启动软件,请收藏,避免找不到

Maya Maya是一款由博主25H开发的体积小巧、简单易用的快速启动工具。它的操作逻辑和界面设计几乎复刻了Rolan早期版本&#xff0c;功能上与Rolan几乎别无二致。Maya支持多文件拖拽添加启动、快捷键呼出、自动多列显示等功能。此外&#xff0c;Maya还具备lnk文件解析功能。 May…

分类模型:MATLAB判别分析

1. 判别分析简介 判别分析&#xff08;Discriminant Analysis&#xff09; 是一种统计方法&#xff0c;用于在已知分类的样本中构建分类器&#xff0c;并根据特征变量对未知类别的样本进行分类。常见的判别分析方法包括线性判别分析&#xff08;Linear Discriminant Analysis, …

在mybatis 中如何防止 IN里面的参数过多?

代码示例&#xff1a; select xsid from zhxg_gy_ssfp_cwfp where xsid in <foreach collection"list" item"item" open"(" close")" separator" " index"index"> <if test"(index % 999) 998&quo…

【kyuubi k8s】kyuubi发布k8s执行spark sql

背景 依据上一篇kyuubi与spark集成&#xff0c;并发布spark sql到k8s集群&#xff0c;上一篇的将kyuubi和spark环境放在本地某台服务器上的&#xff0c;为了高可用&#xff0c;本篇将其打包镜像&#xff0c;并发布到k8s。 其实就是将本地的kyuubi&#xff0c;spark&#xff0…

Nginx + KeepAlived高可用负载均衡集群

目录 一、Keepealived脑裂现象 1.现象 2.原因 3.解决 4.预防 二、实验部署 1.两台nginx做初始化操作并安装nginx 2.四层反向代理配置 3.配置高可用 4.准备检查nginx运行状态脚本 5.开启keepalived服务并测试 一、Keepealived脑裂现象 1.现象 主服务器和备服务器都同…

记录第一次edusrc挖掘

文章目录 一、前言二、漏洞说明截止目前已修复 一、前言 edusrc平台介绍 我们可以在关于页面看到edusrc的收录规则 现阶段&#xff0c;教育行业漏洞报告平台接收如下类别单位漏洞&#xff1a; 教育部 各省、自治区教育厅、直辖市教委、各级教育局 学校 教育相关软件 可以看到…

拉依达的嵌入式学习和秋招经验

拉依达的嵌入式学习和秋招经验 你好&#xff0c;我是拉依达。目前我已经结束了自己的学生生涯&#xff0c;开启了人生的下一个阶段。 从研二准备秋招开始&#xff0c;我就逐渐将自己的学习笔记陆续整理并到CSDN上发布。起初只是作为自己学习的备份记录&#xff0c;后续得到了越…

突然挣不到钱了?带货主播大降薪,有人收入“腰斩”!时薪低至20元,“不如街头发小广告”

韭菜都想来割韭菜了&#xff0c;从00后到60后都在直播带货&#xff0c;部分业内人士认为不懂行的商家以及海量素人主播的加入&#xff0c;拉低了行业的平均薪酬。 2024年的电商年中大促接近尾声&#xff0c;电商直播市场再次成为广为关注的焦点。然而&#xff0c;与热闹的“618…

Linux系统部署Samba服务,共享文件夹给Windows

Samba服务是在Linux和UNIX系统上实现SMB协议的一个免费软件&#xff0c;由服务器及客户端程序构成。 Samba服务是连接Linux与Windows的桥梁&#xff0c;它通过实现SMB&#xff08;Server Message Block&#xff09;协议来允许跨平台的文件和打印机共享。该服务不仅支持Linux和…

Xlua三方库Android编译出错解决办法

Xlua三方库Android编译出错解决办法 最近听老师的热更教程&#xff0c;讲到xlua编译android平台会报错&#xff0c;也是看了老师的博客&#xff0c;按照方法去解决&#xff0c;然而问题并没有解决。应该是因为代码更新或者版本不一样&#xff0c;在此简单记录一下解决过程。 参…

Apple Intelligence:苹果大模型部署方案

摘要&#xff1a; 设备端LLM&#xff1a;iOS18版本将包含一个本地小型、低延迟的LLM模型&#xff08;30亿参数&#xff09;&#xff0c;它能够理解用户命令、当前屏幕并在应用程序上执行操作。该模型不仅能处理总结等简单任务&#xff0c;还可以为Siri的“AI智能体”功能提供支…

2024年10款最佳免费人声分离软件,分离人声很简单,只要选对软件!

随着音乐制作和音频编辑的日益普及&#xff0c;人声分离软件在音频处理中扮演着越来越重要的角色。这类软件能够有效地将音频中的人声和伴奏分离&#xff0c;从而帮助用户更好地进行音频编辑和混音。在2024年&#xff0c;市场上涌现出了众多优秀的人声分离软件&#xff0c;本文…

Part 4.2 背包动态规划

->背包模型模板(0/1,分组&#xff0c;完全&#xff0c;多重)<- [NOIP2018 提高组] 货币系统 题目背景 NOIP2018 提高组 D1T2 题目描述 在网友的国度中共有 n n n 种不同面额的货币&#xff0c;第 i i i 种货币的面额为 a [ i ] a[i] a[i]&#xff0c;你可以假设每…

用Python pillow 创建和保存GIF动画

使用pillow库来创建和保存gif GIFs:图形交换格式(gif)是一种位图图像格式&#xff0c;由美国计算机科学家Steve Wilhite于1987年6月15日领导的在线服务提供商CompuServe的一个团队开发。 一个GIF文件通常存储一个图像&#xff0c;但该格式允许在一个文件中存储多个图像。该格…

防止暴力破解,教你如何在登录失败后实施10分钟账户锁定策略!

最近&#xff0c;在服务器上发现了异常的登录尝试。尽管您的团队已经采取了强密码策略和其他安全措施来加固服务器&#xff0c;但恶意程序仍然通过暴力破解的方式试图多次尝试猜测正确的凭据以获取访问权限。为了增强系统的安全性&#xff0c;特别是防止此类暴力破解攻击&#…

YOLOV1-V3详细介绍(新手向、超详细)

本文主要是根据我自己的学习情况来进行讲解&#xff0c;以一个初学者的角度进行阐释&#xff0c;如果有更深层次的点没有涉及到&#xff0c;还请大家多多包涵。 目录 计算机视觉 主流算法 Two-stage&#xff08;双阶段&#xff09; One-stage&#xff08;单阶段&#xff09; …

【计算机网络】TCP报文详解

认识TCP报头 其实协议的形式都是一个结构化的数据&#xff0c;TCP协议也不例外。一起来看看TCP协议的报头是怎么样的。 以上就是TCP报头&#xff0c;实际上是一个结构化的数据&#xff0c;也就是一个结构体。例如&#xff1a; struct tcp_hdr {unsigned int stc_port : 16;un…

【NLP项目-01】手把手教你基于TF-IDF提取向量+贝叶斯或者随机森林进行文本分类

【NLP项目-01】手把手教你基于TF-IDF提取向量贝叶斯或者随机森林进行文本分类 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 相关内容文…