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

news2024/11/24 3:39:54

将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都能识别出来!!!


总结

这篇文章依旧没有总结

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

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

相关文章

LangChain基础知识入门

LangChain的介绍和入门 1 什么是LangChain LangChain由 Harrison Chase 创建于2022年10月&#xff0c;它是围绕LLMs&#xff08;大语言模型&#xff09;建立的一个框架&#xff0c;LLMs使用机器学习算法和海量数据来分析和理解自然语言&#xff0c;GPT3.5、GPT4是LLMs最先进的代…

架构设计-用户信息及用户相关的密码信息设计

将用户的基本信息和用户密码存放在不同的数据库表中是一种常见的安全做法&#xff0c;这种做法旨在增强数据的安全性和管理的灵活性。以下是这种做法的几个关键原因&#xff1a; 安全性增强&#xff1a; 当用户密码被单独存放在一个表中时&#xff0c;可以使用更强大的加密和哈…

kafka集成SpringBoot api编写教程

1.新建项目 用的idea是20222.1.3版本&#xff0c;没有Spring Initializr 插件&#xff0c;不能直接创建springboot项目 可以在以下网址创建项目&#xff0c;下载后解压&#xff0c;然后用idea打开项目即可 1.1 在 https://start.spring.io/ 上创建项目 1.2上传到linux&#x…

C语言 | Leetcode C语言题解之第140题单词拆分II

题目&#xff1a; 题解&#xff1a; struct Trie {int ch[26];bool flag; } trie[10001];int size;void insert(char* s, int sSize) {int add 0;for (int i 0; i < sSize; i) {int x s[i] - a;if (trie[add].ch[x] 0) {trie[add].ch[x] size;memset(trie[size].ch, 0…

读AI未来进行式笔记07量子计算

1. AI审讯技术 1.1. 发明者最初的目的是发明一种能够替代精神药物&#xff0c;为人类带来终极快乐的技术 1.1.1. 遗憾的是&#xff0c;他找到的只是通往反方向的大门 1.2. 通过非侵入式的神经电磁干扰大脑边缘系统&#xff0c;诱发受审者最…

配置 JDK 和 Android SDK

目录 一、配置JDK 1. 安装 JDK 2. JDK 环境配置 3. JDK的配置验证 二、配置 adb 和Android SDK环境 1、下载 2、配置 Android SDK 环境 一、配置JDK 1. 安装 JDK 安装链接&#xff1a;Java Downloads | Oracle 我安装的是 .zip &#xff0c;直接在指定的文件夹下解压就…

[沉迷理论]进制链表树

往期文章推荐&#xff1a; 题解之最大子矩阵-CSDN博客 洛谷P1115最大子段和[神奇的题目]-CSDN博客 &#xff08;一条神奇的分割线&#xff09; 前言 好久没有更新的我总算在百忙之中抽出时间写了篇博客。 最近总算结束了动态规划的学习&#xff0c;真的是头昏脑涨啊。 最…

论文阅读——MIRNet

项目地址&#xff1a; GitHub - swz30/MIRNet: [ECCV 2020] Learning Enriched Features for Real Image Restoration and Enhancement. SOTA results for image denoising, super-resolution, and image enhancement.GitHub - soumik12345/MIRNet: Tensorflow implementation…

【云岚到家】-day02-1-区域服务后续开发及完善

【云岚到家】-day02-1-区域服务后续开发及完善 1 区域服务后续开发1.1 添加区域服务1.1.1 接口定义1.1.1.1 接口设计1.1.1.2 接口定义-json 1.1.2 接口开发1.1.2.1 mapper1.1.2.2 service1.1.2.3 controller 1.1.3 测试 1.2 修改价格1.2.1 接口定义1.2.1.1 接口设计1.2.1.2 接口…

【RAG入门教程01】Langchian框架 v0.2介绍

LangChain 是一个开源框架&#xff0c;旨在简化使用大型语言模型 (LLM) 创建应用程序的过程。可以将其想象成一套使用高级语言工具进行搭建的乐高积木。 它对于想要构建复杂的基于语言的应用程序而又不必管理直接与语言模型交互的复杂性的开发人员特别有用。它简化了将这些模型…

动态规划(多重背包+完全背包)

P2851 [USACO06DEC] 最少的硬币 G 题解&#xff1a;从题目上看到那个有n种不同的货币&#xff0c;对于买家来说每个货币有C[ i ]个&#xff0c;是有限个数的&#xff0c;但是对于卖家来说 每个货币都是无限的&#xff0c;题目中要我们求的是买到这个物品的最小交易的货币数&…

电子设计入门教程硬件篇之集成电路IC(二)

前言&#xff1a;本文为手把手教学的电子设计入门教程硬件类的博客&#xff0c;该博客侧重针对电子设计中的硬件电路进行介绍。本篇博客将根据电子设计实战中的情况去详细讲解集成电路IC&#xff0c;这些集成电路IC包括&#xff1a;逻辑门芯片、运算放大器与电子零件。电子设计…

燃料电池汽车践行者

前言 见《氢燃料电池技术综述》 见《燃料电池工作原理详解》 见《燃料电池发电系统详解》 见《燃料电池电动汽车详解》 见《氢燃料电池汽车行业发展》 现代汽车&#xff08;中国&#xff09; 现代汽车集团&#xff0c;自1998年成立氢燃料电池研发小组以来深耕氢燃料电池技术&am…

计算机操作系统基础知识:操作系统体系结构图,操作系统的内核,大内核与微内核的区别和优缺点,时钟管理,原语

1.操作系统体系结构图&#xff1a; 2.操作系统的内核&#xff1a; 时钟管理&#xff1a;利用时钟中断实现计时功能。 原语&#xff1a;原语是一种特殊的程序&#xff0c;具有原子性。也就是说&#xff0c;这段程序运行必须一气呵成&#xff0c;不能被中断。 ubuntu、centos的…

VUE3 学习笔记(13):VUE3 下的Element-Plus基本使用

UI是页面的门面&#xff0c;一个好的UI自然令人赏心悦目&#xff1b;国人团队开发的ElementUI在众多UI中较为常见&#xff0c;因此通过介绍它的使用让大家更好的了解第三方UI的使用。 安装 Npm install element-plus --save 或 Cnpm install element-plus --save 配置 全局配置…

Vitis HLS 学习笔记--循环边界包含变量

目录 1. 简介 2. 分析与详解 2.1 未优化 2.2 LOOP_TRIPCOUNT 优化指令 2.3 重写变量循环边界 3. 总结 1. 简介 在硬件设计中&#xff0c;循环的迭代次数通常需要是固定的&#xff0c;因为这有助于资源的预分配和时序分析。 循环边界包含变量意味着循环的迭代次数不是固…

MySQL之多表查询—表子查询

一、引言 上一篇博客学习了行子查询。&#xff08;看弹幕&#xff1a;同一张表用or,不同张表用union&#xff09; 下面接着学习子查询当中的最后一种——表子查询。 表子查询 1、概念 子查询返回的结果是多行多列&#xff0c;这种子查询称为表子查询。 2、常用的操作符 IN 3、…

2024海南省大数据教师培训-Hadoop集群部署

前言 本文将详细介绍Hadoop分布式计算框架的来源&#xff0c;架构和应用场景&#xff0c;并附上最详细的集群搭建教程&#xff0c;能更好的帮助各位老师和同学们迅速了解和部署Hadoop框架来进行生产力和学习方面的应用。 一、Hadoop介绍 Hadoop是一个开源的分布式计算框架&…

使用Nextjs学习(学习+项目完整版本)

创建项目 运行如下命令 npx create-next-app next-create创建项目中出现的各种提示直接走默认的就行,一直回车就行了 创建完成后进入到项目运行localhost:3000访问页面,如果和我下面页面一样就是创建项目成功了 整理项目 将app/globals.css里面的样式都删除,只留下最上面三…

盲盒抽卡机小程序的特点,互联网下市场发展前景

近几年&#xff0c;盲盒抽卡成为了年轻人的新宠&#xff0c;也受到了未成年人的喜爱&#xff0c;卡牌的内容更是丰富多样&#xff0c;涵盖了动漫、漫画、影视等&#xff0c;因此吸引了各类消费者和越来越多的创业者。 目前&#xff0c;随着市场的发展&#xff0c;抽卡机小程序…