UA-DETRAC数据集转YOLO格式

news2024/12/30 3:20:32

一: 数据集下载

链接:(后续添加)

二: 处理标注文件

先处理标注文件,UA-DETRAC提供的标注文件格式是VOC格式,需要先转为XML格式,然后再将每个XML文件转为YOLO文件。
下面提供两个代码,只需要修改文件放置目录

1. 将VOC转为XML格式

import xml.etree.ElementTree as ET
from xml.dom.minidom import Document
import os
import cv2
import time


def ConvertVOCXml(file_path="", file_name=""):
    tree = ET.parse(file_name)
    root = tree.getroot()
    # print(root.tag)

    num = 0  # 计数
    # 读xml操作

    frame_lists = []
    output_file_name = ""
    for child in root:

        if (child.tag == "frame"):
            # 创建dom文档
            doc = Document()
            # 创建根节点
            annotation = doc.createElement('annotation')
            # 根节点插入dom树
            doc.appendChild(annotation)

            # print(child.tag, child.attrib["num"])
            pic_id = child.attrib["num"].zfill(5)
            # print(pic_id)
            output_file_name = root.attrib["name"] + "__img" + pic_id + ".xml"
            #  print(output_file_name)

            folder = doc.createElement("folder")
            folder.appendChild(doc.createTextNode("VOC2007"))
            annotation.appendChild(folder)

            filename = doc.createElement("filename")
            pic_name = "img" + pic_id + ".jpg"
            filename.appendChild(doc.createTextNode(pic_name))
            annotation.appendChild(filename)

            sizeimage = doc.createElement("size")
            imagewidth = doc.createElement("width")
            imageheight = doc.createElement("height")
            imagedepth = doc.createElement("depth")

            imagewidth.appendChild(doc.createTextNode("960"))
            imageheight.appendChild(doc.createTextNode("540"))
            imagedepth.appendChild(doc.createTextNode("3"))

            sizeimage.appendChild(imagedepth)
            sizeimage.appendChild(imagewidth)
            sizeimage.appendChild(imageheight)
            annotation.appendChild(sizeimage)

            target_list = child.getchildren()[0]  # 获取target_list
            # print(target_list.tag)
            object = None
            for target in target_list:
                if (target.tag == "target"):
                    # print(target.tag)
                    object = doc.createElement('object')
                    bndbox = doc.createElement("bndbox")

                    for target_child in target:
                        if (target_child.tag == "box"):
                            xmin = doc.createElement("xmin")
                            ymin = doc.createElement("ymin")
                            xmax = doc.createElement("xmax")
                            ymax = doc.createElement("ymax")
                            xmin_value = int(float(target_child.attrib["left"]))
                            ymin_value = int(float(target_child.attrib["top"]))
                            box_width_value = int(float(target_child.attrib["width"]))
                            box_height_value = int(float(target_child.attrib["height"]))
                            xmin.appendChild(doc.createTextNode(str(xmin_value)))
                            ymin.appendChild(doc.createTextNode(str(ymin_value)))
                            if (xmin_value + box_width_value > 960):
                                xmax.appendChild(doc.createTextNode(str(960)))
                            else:
                                xmax.appendChild(doc.createTextNode(str(xmin_value + box_width_value)))
                            if (ymin_value + box_height_value > 540):
                                ymax.appendChild(doc.createTextNode(str(540)))
                            else:
                                ymax.appendChild(doc.createTextNode(str(ymin_value + box_height_value)))

                        if (target_child.tag == "attribute"):
                            vehicle_type = target_child.attrib["vehicle_type"]

                            name = doc.createElement('name')
                            pose = doc.createElement('pose')
                            truncated = doc.createElement('truncated')
                            difficult = doc.createElement('difficult')

                            name.appendChild(doc.createTextNode(str(vehicle_type)))
                            pose.appendChild(doc.createTextNode("Left"))  # 随意指定
                            truncated.appendChild(doc.createTextNode("0"))  # 随意指定
                            difficult.appendChild(doc.createTextNode("0"))  # 随意指定

                            object.appendChild(name)
                            object.appendChild(pose)
                            object.appendChild(truncated)
                            object.appendChild(difficult)

                    bndbox.appendChild(xmin)
                    bndbox.appendChild(ymin)
                    bndbox.appendChild(xmax)
                    bndbox.appendChild(ymax)
                    object.appendChild(bndbox)
                    annotation.appendChild(object)

            file_path_out = os.path.join(file_path, output_file_name)
            f = open(file_path_out, 'w')
            f.write(doc.toprettyxml(indent=' ' * 4))
            f.close()
            num = num + 1
    return num


'''
画方框
'''


def bboxes_draw_on_img(img, bbox, color=[255, 0, 0], thickness=2):
    # Draw bounding box...
    print(bbox)
    p1 = (int(float(bbox["xmin"])), int(float(bbox["ymin"])))
    p2 = (int(float(bbox["xmax"])), int(float(bbox["ymax"])))
    cv2.rectangle(img, p1, p2, color, thickness)


def visualization_image(image_name, xml_file_name):
    tree = ET.parse(xml_file_name)
    root = tree.getroot()

    object_lists = []
    for child in root:
        if (child.tag == "folder"):
            print(child.tag, child.text)
        elif (child.tag == "filename"):
            print(child.tag, child.text)
        elif (child.tag == "size"):  # 解析size
            for size_child in child:
                if (size_child.tag == "width"):
                    print(size_child.tag, size_child.text)
                elif (size_child.tag == "height"):
                    print(size_child.tag, size_child.text)
                elif (size_child.tag == "depth"):
                    print(size_child.tag, size_child.text)
        elif (child.tag == "object"):  # 解析object
            singleObject = {}
            for object_child in child:
                if (object_child.tag == "name"):
                    # print(object_child.tag,object_child.text)
                    singleObject["name"] = object_child.text
                elif (object_child.tag == "bndbox"):
                    for bndbox_child in object_child:
                        if (bndbox_child.tag == "xmin"):
                            singleObject["xmin"] = bndbox_child.text
                            # print(bndbox_child.tag, bndbox_child.text)
                        elif (bndbox_child.tag == "ymin"):
                            # print(bndbox_child.tag, bndbox_child.text)
                            singleObject["ymin"] = bndbox_child.text
                        elif (bndbox_child.tag == "xmax"):
                            singleObject["xmax"] = bndbox_child.text
                        elif (bndbox_child.tag == "ymax"):
                            singleObject["ymax"] = bndbox_child.text
            object_length = len(singleObject)
            if (object_length > 0):
                object_lists.append(singleObject)
    img = cv2.imread(image_name)
    for object_coordinate in object_lists:
        bboxes_draw_on_img(img, object_coordinate)
    cv2.imshow("capture", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if (__name__ == "__main__"):
    # print("main")
    basePath = r"E:\project\dataset\UA-DETRAC\DETRAC-Test-Annotations-XML"
    totalxml = os.listdir(basePath)
    total_num = 0
    flag = False
    print("正在转换")
    saveBasePath = r"E:\project\dataset\UA-DETRAC\test-labels-xml"
    if os.path.exists(saveBasePath) == False:  # 判断文件夹是否存在
        os.makedirs(saveBasePath)

    # ConvertVOCXml(file_path="samplexml",file_name="000009.xml")
    # Start time
    start = time.time()
    log = open("xml_statistical.txt", "w")  # 分析日志,进行排错
    for xml in totalxml:
        file_name = os.path.join(basePath, xml)
        print(file_name)
        num = ConvertVOCXml(file_path=saveBasePath, file_name=file_name)
        print(num)
        total_num = total_num + num
        log.write(file_name + " " + str(num) + "\n")
    # End time
    end = time.time()
    seconds = end - start
    print("Time taken : {0} seconds".format(seconds))
    print(total_num)

2. 将XML转为YOLO格式

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join


def convert(size, box):
    # size=(width, height)  b=(xmin, xmax, ymin, ymax)
    # x_center = (xmax+xmin)/2        y_center = (ymax+ymin)/2
    # x = x_center / width            y = y_center / height
    # w = (xmax-xmin) / width         h = (ymax-ymin) / height

    x_center = (box[0] + box[1]) / 2.0
    y_center = (box[2] + box[3]) / 2.0
    x = x_center / size[0]
    y = y_center / size[1]

    w = (box[1] - box[0]) / size[0]
    h = (box[3] - box[2]) / size[1]

    # print(x, y, w, h)
    return (x, y, w, h)


def convert_annotation(xml_files_path, save_txt_files_path, classes):
    xml_files = os.listdir(xml_files_path)
    # print(xml_files)
    for xml_name in xml_files:
        print(xml_name)
        xml_file = os.path.join(xml_files_path, xml_name)
        out_txt_path = os.path.join(save_txt_files_path, xml_name.split('.')[0] + '.txt')
        out_txt_f = open(out_txt_path, 'w')
        tree = ET.parse(xml_file)
        root = tree.getroot()

        size = root.find('size')
        w = int(size.find('width').text)
        h = int(size.find('height').text)


        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)
            xmlbox = obj.find('bndbox')
            b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
                 float(xmlbox.find('ymax').text))
            # b=(xmin, xmax, ymin, ymax)
            # print(w, h, b)
            bb = convert((w, h), b)
            out_txt_f.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


if __name__ == "__main__":
    # 把forklift_pallet的voc的xml标签文件转化为yolo的txt标签文件
    # 1、需要转化的类别
    classes = ['car',  'bus',  'van', 'others']  # 注意:这里根据自己的类别名称及种类自行更改
    # 2、voc格式的xml标签文件路径
    xml_files1 = r'E:\project\dataset\UA-DETRAC\test-labels-xml'
    # 3、转化为yolo格式的txt标签文件存储路径
    save_txt_files1 = r'E:\project\dataset\UA-DETRAC\test-labels-yolo'

    convert_annotation(xml_files1, save_txt_files1, classes)

3 处理完毕后我们会得到以下内容

在这里插入图片描述
在这里插入图片描述

其中输出YOLO格式的标注文件名为MVI_20011__img00001.txt,相比图片的文件名多了一个 MVI_20011__ 的前缀。 (其实就是存放图片文件夹的文件名)

所以后面我们需要对图像的文件名进行下处理,将其修改为和标注文件相同的名字!

三: 修改图像名称

一个代码搞定

import os

# 获取要修改的文件地址
path = r'E:\project\dataset\UA-DETRAC\test'
# 获取文件名列表
file_list = os.listdir(path)
print('文件列表如下:')
print(file_list)

# # 遍历文件名,获取文件名和扩展名
for file in file_list:
    path_2 = path + '/' + file
    file_list_inner = os.listdir(path_2)
    for filename in file_list_inner:
        pos = filename.rfind('.') - 8
        newname = file + '__' + filename[pos:-4] + '.jpg'
        #重新命名文件
        os.rename(path_2+'/'+filename,path_2+'/'+newname)

在这里插入图片描述

处理完成!接下来按照yolo训练文件格式调整下文件顺序就好了。

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

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

相关文章

git 本地新建分支并进行合并

由于新的要求 不允许在线上直接clone下的git分支进行开发,只能本地新建分支再往线上分支合并远程库clone到本地库 git clone 需要下载的git地址注意我下载下来的是dev分支 根据实际情况进行分析git clone https://gitee.com/hello.git本地创建新的分支 git checkout…

Keil编译头文件iec_std_functions.h错误解决

Keil 编译IEC61131-3库,头文件,大量出现以下错误; cast to type ? is not allowed compiling resource1.c... ..\PLC\rts\matiec\lib\C\iec_std_functions.h(192): error: #119: cast to type "TIME" is not allowed…

公派访问学者的申请条件

知识人网海外访问学者申请老师为大家分享公派访问学者申请的基本条件以及哪些人员的申请是暂不受理的,供大家参考:一、 申请人基本条件:1.热爱社会主义祖国,具有良好的思想品德和政治素质,无违法违纪记录。2.具有良好专…

Java常见问题总结五

1、垃圾回收方式 SerialGC(串行垃圾回收):为单线程环境设计且使用一个线程进行垃圾回收,会暂停所有的用户线程。 ParalleGC(并行垃圾回收):对过GC线程并行工作,此时用户线程是停止的。 ConcMarkSweep(CMS):用户线程和GC线程同时执…

Tatuk GIS Developer Kernel for .NET 最新Crack

Tatuk GIS Developer Kernel for .NET 是一个地理SDK,它是受控代码和 .NET GIS SDK,用于为用户 Windows 操作系统创建 GIS 专业软件的过程。它被认为是一个完全用于 Win Forms 的 .NET CIL,WPF 的框架是为 C# 以及 VB.NET、VC、oxygen 以及最…

StarRocks携手零洞科技,助力碧桂园物业企业微信数字化项目

作者:零洞科技大数据部零洞科技有限公司(以下简称“零洞”),是碧桂园集团的核心联盟企业,致力于成为国内领先的数智空间解决方案服务商,业务场景覆盖户内及户外,在智慧家居板块,打造…

【C语言】字符分类函数+内存函数

目录 1.字符函数 1.1字符分类函数 1.2.字符转换函数 //统一字符串中的大小写 2.内存处理函数 2.1内存拷贝函数memcpy //模拟实现memcpy 2.2内存移动函数memmove //模拟实现memmove 2.3内存比较函数memcmp 2.4内存设置函数memset 1.字符函数 1.1字符分类函数 头文…

【微信小程序】-- 宿主环境 通信模型 运行机制介绍(五)

💌 所属专栏:【微信小程序开发教程】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &#…

NFTScan x TiDB丨一栈式 HTAP 数据库为 Web3 数据服务提供毫秒级多维查询

导读 NFTScan 是一家多链 NFT 数据基础设施服务商,为 Web3 用户提供高效简洁的 NFT 资产搜索查询服务,为 Web3 开发者和新一代金融科技公司提供专业的 NFT API 数据服务。 TiDB 作为一种分布式 HTAP 数据库,可以同时满足海量数据存储和高并…

I2C实验

目录 一、I2C简介 二、硬件原理 1、看原理图,找到I2C 2、查看使用设备 3、查看使用的IO 4、查数据手册看复用位 三、查看寄存器 1、I2C Address Register (I2Cx_IADR) 2、I2C Frequency Divider Register (I2Cx_IFDR) 3、I2C Control Register (I2Cx_I2CR) …

【C++】哈希表

1. unordered系列关联式容器 在C98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 ,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行…

TCP/IP网络协议介绍及原理分析

一.应用层协议对于应用层而言,协议是开发者自己进行定义的,开发者根据自定义的格式规范对数据进行编码和解析。但是从原理上进行分析,其核心主要包括两点内容:①确定客户端和服务端交互的内容(协议的内容)②…

记一次docker虚拟机横向移动渗透测试

本次渗透在几个docker虚拟机间多次横向移动,最终找到了一个可以进行docker逃逸的出口,拿下服务器。渗透过程曲折但充满了乐趣,入口是172.17.0.6的docker虚拟机,然后一路横向移动,最终在172.17.0.2出实现了docker逃逸&a…

【免费教程】地下水环境监测技术规范HJ/T164-2020解读使用教程

地下水环境监测技术规范依据《中华人民共和国环境保护法》第十一条“国务院环境保护行政主管部门建立监测制度、制订监测规范”和《中华人民共和国水污染防治法》的要求,积极开展地下水环境监测,掌握地下水环境质量,保护地下水水质&#xff0…

常青科技冲刺A股上市:研发费用率较低,关联方曾拆出资金达1亿元

近日,江苏常青树新材料科技股份有限公司(下称“常青科技”或“常青树科技”)递交招股书,准备在上海证券交易所主板上市。本次冲刺上市,常青科技计划募资8.50亿元,光大证券为其保荐机构。 据招股书介绍&…

我的 System Verilog 学习记录(4)

引言 本文简单介绍 System Verilog 语言的 数据类型。 前文链接: 我的 System Verilog 学习记录(1) 我的 System Verilog 学习记录(2) 我的 System Verilog 学习记录(3) 数据类型简介 Sys…

Linux:共享内存api使用

代码&#xff1a; #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <arpa/inet.h> #include <sys/un.h> #include <sys/ipc.h…

Codeforces Round #849 (Div. 4)(E~G)

A~D比较简单就不写了&#xff0c;哎嘿E. Negatives and Positives给出一个数组a&#xff0c;可以对数组进行若干次操作&#xff0c;每次操作可以将相邻的两个数换为它们的相反数&#xff0c;求进行若干次操作之后能得到数组和的最大值是多少。思路&#xff1a;最大的肯定是把负…

VSCode+Qt+MinGW开发环境搭建

VSCodeQtMinGW开发环境搭建 概述 VSCode扩展性很强&#xff0c;插件机制让其具备不断演进的潜力&#xff0c;适合作为稳定的开发工具。 VSCodeQt开发环境的搭建需要依赖于以下工具&#xff1a; VSCode、Qt&#xff0c;其中Qt需要安装MinGW编译工具&#xff1b;VSCode插件&a…

常年霸榜TK彩妆类目,看Focallure菲鹿儿如何玩转出海市场

据市场调研机构弗若斯特沙利文数据报告&#xff0c;2017年至2021年&#xff0c;中国化妆品市场规模由6305亿元增长至9468亿元&#xff0c;年均复合增长率为10.7%&#xff0c;报告预计2023年中国化妆品市场规模将达11414亿元&#xff0c;今后几年的增速将逐渐放缓。随着国内市场…