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

news2024/11/18 18:37:50

文章目录

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


前言

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


一、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文件主要三个来源内容,其一类别,其二box框,其三图像尺寸。

1、yolov5的txt读取代码

过于通常,直接上代码:

def read_txt(path):
    txt_info_lst = []
    with open(path, "r", encoding='utf-8') as f:
        for line in f:
            txt_info_lst.append(list(line.strip('\n').split()))
    txt_info_lst = np.array(txt_info_lst)
    return txt_info_lst

2、生成xml代码

product_xml函数是一张图目标生成一个对应的xml文件函数,其中boxes与codes分别为一一对应框与类别,详细 代码如下:


def product_xml(name_img, boxes, codes, img=None, wh=None):
    '''
    :param img: 以读好的图片
    :param name_img: 图片名字
    :param boxes: box为列表
    :param codes: 为列表
    :return:
    '''
    if img is not None:
        width = img.shape[0]
        height = img.shape[1]
    else:
        assert wh is not None
        width = wh[0]
        height = wh[1]
    # print('xml w:{} h:{}'.format(width,height))

    node_root = Element('annotation')
    node_folder = SubElement(node_root, 'folder')
    node_folder.text = 'VOC2007'

    node_filename = SubElement(node_root, 'filename')
    node_filename.text = name_img  # 图片名字

    node_size = SubElement(node_root, 'size')
    node_width = SubElement(node_size, 'width')
    node_width.text = str(width)

    node_height = SubElement(node_size, 'height')
    node_height.text = str(height)

    node_depth = SubElement(node_size, 'depth')
    node_depth.text = '3'

    for i, code in enumerate(codes):
        box = [boxes[i][0], boxes[i][1], boxes[i][2], boxes[i][3]]
        node_object = SubElement(node_root, 'object')
        node_name = SubElement(node_object, 'name')
        node_name.text = code
        node_difficult = SubElement(node_object, 'difficult')
        node_difficult.text = '0'
        node_bndbox = SubElement(node_object, 'bndbox')
        node_xmin = SubElement(node_bndbox, 'xmin')
        node_xmin.text = str(int(box[0]))
        node_ymin = SubElement(node_bndbox, 'ymin')
        node_ymin.text = str(int(box[1]))
        node_xmax = SubElement(node_bndbox, 'xmax')
        node_xmax.text = str(int(box[2]))
        node_ymax = SubElement(node_bndbox, 'ymax')
        node_ymax.text = str(int(box[3]))

    xml = tostring(node_root, pretty_print=True)  # 格式化显示,该换行的换行
    dom = parseString(xml)

    name = name_img[:-4] + '.xml'

    tree = ElementTree(node_root)

    # print('name:{},dom:{}'.format(name, dom))
    return tree, name


三、yolov5的txt文件转xml文件步骤

步骤:
1、获得该txt对应图像的高与宽,读图获得
2、提取txt文件信息
3、提取txt文件信息进行类别转换,txt数字表示转对应标签名
4、提取box信息中心点x、y与宽高w、h转图像实际尺寸
5、生成xml文件并保存

大致读取一个txt文件转对应xml文件代码如下:

# 通过图像获得图像高与宽
img = cv2.imread(img_root)
height, width = img.shape[:2]
# 读取对应txt的信息
txt_info = read_txt(txt_root)
# 以下获得txt信息,并保存labels_lst与boxes_lst中,且一一对应
labels_lst, boxes_lst = [], []
for info in txt_info:
    label_str = str(info[0])
    x, y, w, h = float(info[1]) * width, float(info[2]) * height, float(info[3]) * width, float(
        info[4]) * height
    xmin, ymin, xmax, ymax = int(x - w / 2), int(y - h / 2), int(x + w / 2), int(y + h / 2)
    labels_lst.append(label_str)
    boxes_lst.append([xmin, ymin, xmax, ymax])
# 是否转换信息
if gt_labels: # gt_labels需要和txt类别对应
    labels_lst=[gt_labels[int(lb)] for lb in labels_lst]
# 构建xml文件
if len(labels_lst) > 0:
    tree, xml_name = product_xml('img_name.jpg', boxes_lst, labels_lst, wh=[w, h])
    tree.write(os.path.join('', xml_name))

四、完整代码

以下代码将txt文件夹中的*.txt转对应*.jpg格式,但需要提供对应图像文件夹,代码会自动匹配,其完整代码如下:

import os
import cv2
from tqdm import tqdm
from lxml.etree import Element, SubElement, tostring, ElementTree
from xml.dom.minidom import parseString
import numpy as np


def build_dir(out_dir):
    if not os.path.exists(out_dir):
        os.mkdir(out_dir)
    return out_dir

def get_root_lst(root, suffix='jpg', suffix_n=3):
    root_lst, name_lst = [], []

    for dir, file, names in os.walk(root):
        root_lst = root_lst + [os.path.join(dir, name) for name in names if name[-suffix_n:] == suffix]
        name_lst = name_lst + [name for name in names if name[-suffix_n:] == suffix]

    return root_lst, name_lst
def read_txt(path):
    txt_info_lst = []
    with open(path, "r", encoding='utf-8') as f:
        for line in f:
            txt_info_lst.append(list(line.strip('\n').split()))
    txt_info_lst = np.array(txt_info_lst)
    return txt_info_lst

def product_xml(name_img, boxes, codes, img=None, wh=None):
    '''
    :param img: 以读好的图片
    :param name_img: 图片名字
    :param boxes: box为列表
    :param codes: 为列表
    :return:
    '''
    if img is not None:
        width = img.shape[0]
        height = img.shape[1]
    else:
        assert wh is not None
        width = wh[0]
        height = wh[1]
    # print('xml w:{} h:{}'.format(width,height))

    node_root = Element('annotation')
    node_folder = SubElement(node_root, 'folder')
    node_folder.text = 'VOC2007'

    node_filename = SubElement(node_root, 'filename')
    node_filename.text = name_img  # 图片名字

    node_size = SubElement(node_root, 'size')
    node_width = SubElement(node_size, 'width')
    node_width.text = str(width)

    node_height = SubElement(node_size, 'height')
    node_height.text = str(height)

    node_depth = SubElement(node_size, 'depth')
    node_depth.text = '3'

    for i, code in enumerate(codes):
        box = [boxes[i][0], boxes[i][1], boxes[i][2], boxes[i][3]]
        node_object = SubElement(node_root, 'object')
        node_name = SubElement(node_object, 'name')
        node_name.text = code
        node_difficult = SubElement(node_object, 'difficult')
        node_difficult.text = '0'
        node_bndbox = SubElement(node_object, 'bndbox')
        node_xmin = SubElement(node_bndbox, 'xmin')
        node_xmin.text = str(int(box[0]))
        node_ymin = SubElement(node_bndbox, 'ymin')
        node_ymin.text = str(int(box[1]))
        node_xmax = SubElement(node_bndbox, 'xmax')
        node_xmax.text = str(int(box[2]))
        node_ymax = SubElement(node_bndbox, 'ymax')
        node_ymax.text = str(int(box[3]))

    xml = tostring(node_root, pretty_print=True)  # 格式化显示,该换行的换行
    dom = parseString(xml)

    name = name_img[:-4] + '.xml'

    tree = ElementTree(node_root)

    # print('name:{},dom:{}'.format(name, dom))
    return tree, name

def yolov5txt2xml(root_data, txt_root, gt_labels=None,out_dir=None):

    # 获得图像与txt的路径与名称的列表
    img_roots_lst, img_names_lst = get_root_lst(root_data, suffix='jpg', suffix_n=3)
    txt_roots_lst, txt_names_lst = get_root_lst(txt_root, suffix='txt', suffix_n=3)
    # 创建保存xml的文件
    out_dir = build_dir(out_dir) if out_dir is not None else build_dir(os.path.join(txt_root, 'out_dir_xml'))

    label_str_lst = []
    # 通过图像遍历
    for i, img_root in tqdm(enumerate(img_roots_lst)):
        # 获得图像名称,并得到对应txt名称
        img_name = img_names_lst[i]
        txt_name = img_name[:-3] + 'txt'

        if txt_name in txt_names_lst:  # 通过图像获得txt名称是否存在,存在则继续,否则不继续
            txt_index = list(txt_names_lst).index(str(txt_name))  # 获得列表txt对应索引,以便后续获得路径
            # 通过图像获得图像高与宽
            img = cv2.imread(img_root)
            height, width = img.shape[:2]
            # 读取对应txt的信息
            txt_info = read_txt(txt_roots_lst[txt_index])

            # 以下获得txt信息,并保存labels_lst与boxes_lst中,且一一对应
            labels_lst, boxes_lst = [], []
            for info in txt_info:
                label_str = str(info[0])
                if label_str not in label_str_lst:
                    label_str_lst.append(label_str)

                x, y, w, h = float(info[1]) * width, float(info[2]) * height, float(info[3]) * width, float(
                    info[4]) * height
                xmin, ymin, xmax, ymax = int(x - w / 2), int(y - h / 2), int(x + w / 2), int(y + h / 2)
                labels_lst.append(label_str)
                boxes_lst.append([xmin, ymin, xmax, ymax])
            # 是否转换信息
            if gt_labels: # gt_labels需要和txt类别对应
                labels_lst=[gt_labels[int(lb)] for lb in labels_lst]
            # 构建xml文件
            if len(labels_lst) > 0:
                tree, xml_name = product_xml(img_name, boxes_lst, labels_lst, wh=[w, h])
                tree.write(os.path.join(out_dir, xml_name))

    print('gt label:', gt_labels)
    print('txt label:', label_str_lst)
    print('save root:',out_dir)

if __name__ == '__main__':
    root_path = r'E:\project\data\voc2012_verity\images\val'
    txt_root = r'E:\project\data\voc2012_verity\labels\val'
    gt_labels =['cow','horse',  'sheep','bird', 'dog', 'cat', 'person',
               'bicycle', 'car', 'train','aeroplane','bus', 'boat','motorbike',
               'bottle', 'sofa',  'chair',  'tvmonitor',  'pottedplant',    'diningtable']

    yolov5txt2xml(root_path, txt_root,gt_labels=gt_labels)



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

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

相关文章

Cesium 添加与原生按钮样式相同的按钮

Cesium 添加与原生按钮样式相同的按钮 原生的按钮自定义一个&#xff0c;仿生按钮 原生的按钮 自定义一个&#xff0c;仿生按钮 html <div id"cesiumContainer"><button class"btn" ref"newBtn" click"buttonClick()">&l…

python3高级编程

文章目录 1. Python网络编程1.1 服务器端代码(Server)1.2 客户端代码(Client) 2. 多线程2.1 线程模块2.2 使用 threading 模块创建线程2.3 线程同步2.4 线程优先级队列&#xff08; Queue&#xff09; 3. 日期和时间4. SMTP发送邮件4.1 使用Python发送HTML格式的邮件4.2 Python…

springboot服务注册到Eureka,端口总是默认8080,自己配置端口不生效

这段时间接手了一个公司的老项目&#xff0c;用的是SpringCloud&#xff0c;在我用的时候突然发现有一个服务&#xff0c;注册到Eureka后&#xff0c;界面显示的端口和实际Ribbon调用的实例端口是不一致的&#xff0c;后来我自己写了个端口获取了一下所有的实例信息&#xff0c…

UltralSO软碟通制作Linux系统盘

第一步&#xff1a; 下载镜像 阿里云下载地址&#xff1a;https://mirrors.aliyun.com/centos-vault/ 按照需求选择系统版本&#xff0c;我这要求安装CentOS7.5的系统&#xff0c;我以CentOS7.5为例 第二步&#xff1a; 下载UltralSO软件 官网下载地址&#xff1a;https://cn.…

山西电力市场日前价格预测【2023-08-26】

日前价格预测 预测明日&#xff08;2023-08-26&#xff09;山西电力市场全天平均日前电价为287.61元/MWh。其中&#xff0c;最高日前电价为318.26元/MWh&#xff0c;预计出现在19: 30。最低日前电价为246.18元/MWh&#xff0c;预计出现在05: 15。 价差方向预测 1&#xff1a; 实…

反向传播求变量导数

反向传播求变量导数 1. 相关习题2. 推导流程2.1 相关公式2.3 变量导数求解 3. 代码实现3.1 参数对应3.2 代码实现 以前只知道反向传播通过链式法则实现今天看书发现图片上求出来的值自己算不出来所以自己算了一下&#xff0c;记录一下&#xff0c;并运行了书中的代码相关书籍&a…

Ceph入门到精通-如何编译安装Quagga?

Quagga 1. 理论部分 1.1 软件简介 Quagga中文翻译斑驴&#xff0c;是一种先进的路由软件包&#xff0c;提供一套基于TCP/IP的路由协议。 1.2 斑驴的应用场景 – 使得操作系统变成专业的路由 – 使得操作系统具有与传统路由通过路由协议直接对接 1.3 斑驴支持的路由协议 …

linux篇---使用systemctl start xxx启动自己的程序|开机启动|守护进程

linux篇---使用systemctl start xxx启动自己的程序|开机启动|守护进程 1、创建服务2、修改权限3、启动服务4、测试 机器&#xff1a;Nvidia Jetson Xavier系统&#xff1a;ubuntu 18.04 最近在使用symfony的console组件&#xff0c;需要执行一个后台的php进程&#xff0c;并且…

DevOps之自动化测试

什么是自动化测试&#xff1f; 明确一下自动化测试不是什么。自动化测试不是指自动化生成测试代码&#xff0c;而是自动化地执行由开发人员或测试人员编写的测试代码。正如下面这句谚语&#xff1a;“绝不要手工去做任何可以被自动化处理的事情。——Curt Hibbs” 之前是由人…

Windows 桌面运维及安全管理

什么是桌面运维 桌面运维是IT管理的重要部分&#xff0c;是一种系统管理的技术&#xff0c;它的主要目的是通过管理用户、计算机和其他设备来提高组织的效率。它不仅能够降低维护成本&#xff0c;而且还能够提高系统的可用性。 如今随着企业设备越来越丰富&#xff0c;桌面运…

前端需要理解的数据治理与异常监控知识

1 数据治理 前端数据治理的重要指标是准确性和数据&#xff0c;一个数据对象包括数据值和其他元数据。 2 数据上报方式 2.1 Image 通过将采集的数据拼接在图片请求的后面&#xff0c;向服务端请求一个 1*1 px 大小的图片&#xff08;gif&#xff09;实现的&#xff0c;设置…

与活力四射的 {Agorians} 化身一起拥抱自我超越

准备好通过新的化身转换来探索新的自己吧&#xff01; 我们与法国多学科艺术家和 DJ Agoria 达成合作&#xff0c;自豪地宣布推出 {Agorians} 化身系列&#xff0c;这是有史以来第一个实现自动外观变换以反映一天中真实时间的 Web3 化身系列。在一天里&#xff0c;你们的化身…

跨地区、跨平台、跨网络,如何解决远程IT运维集中管理难题

面对日益激增的IT复杂性和业务需求的快速变化&#xff0c;IT应用在运行过程中发生性能下降或者服务不可用等故障的可能性大大增加&#xff0c;如何更高效、更智能地开展IT运维&#xff0c;保证业务的连续性和IT系统的稳定性&#xff0c;成为企业业务发展的迫切需要。IT运维作为…

BGP路径劫持攻击实验

一、实验目的&#xff1a; 1&#xff09;BGP实验环境搭建 2&#xff09;BGP路径劫持验证 二、预备知识&#xff1a; BGP(Border Gateway Protocol)边界网关协议&#xff0c;也就是不同自治系统autonomous system之间进行路由交换的协议 三、实验环境&#xff1a; 四、…

X2000 Linux PWM

一、硬件设计 PC04 ------------PWM4 二、通过shell开启PWM 配置参数 cmd_pwm config pc04 freq1000 max_level100 active_level1 accuracy_priorityfreq 启动 cmd_pwm set_level pc04 10 三、通过写程序控制 先用IConfigTool工具&#xff0c;使能libhardware2--->pwm…

Kafka生产者原理 kafka生产者发送流程 kafka消息发送到集群步骤 kafka如何发送消息 kafka详解

kafka尚硅谷视频&#xff1a; 10_尚硅谷_Kafka_生产者_原理_哔哩哔哩_bilibili ​ 1. producer初始化&#xff1a;加载默认配置&#xff0c;以及配置的参数&#xff0c;开启网络线程 2. 拦截器拦截 3. 序列化器进行消息key, value序列化 4. 进行分区 5. kafka broker集群 获取…

3D模型转换工具HOOPS Exchange助力打造虚拟现实应用程序

挑战&#xff1a; 支持使用各种 CAD 系统和 CAD 文件格式的客户群向可视化硬件提供快速、准确的数据加载提供对详细模型信息的访问&#xff0c;同时确保高帧率性能 解决方案&#xff1a; HOOPS Exchange领先的CAD数据转换工具包 结果&#xff1a; 确保支持来自领先工程软件…

【Python编程】将同一种图片分类到同一文件夹下,并且将其分类的路径信息写成txt文件进行保存

注&#xff1a;数据结构同上一篇博文类似 一、代码 import os import cv2 import shutilpath0os.getcwd()\\apple\\RGB path1os.getcwd()\\apple\\tof_confidence # path2os.getcwd()\\apple\\tof_depth # path3os.getcwd()\\apple\\tof_depthRGB # path4os.getcwd()\\apple\…

云计算为中小企业带来的 10 大好处

云计算的迅速采用并非巧合。中小型企业 (SMB) 现在有机会摆脱传统 IT 基础设施的限制&#xff0c;享受云提供的众多优势。它的发展使公司能够更智能、更快速、更安全地工作。 因此&#xff0c;如果您发现自己质疑是否需要进行这种转变&#xff0c;请不要害怕&#xff01;让我们…

1.1 VMware Workstation与Kali的安装和配置1

资源见专栏第一篇文章https://blog.csdn.net/algorithmyyds/article/details/132457258 安装VMware 不多加赘述&#xff0c;直接按顺序安装即可。 有以下需注意的地方&#xff1a; 1.建议选择增强型服务&#xff1b; 2.不要加入体验改进计划。是否开启提示更新看你的想法&…