三种标注格式VOC、COCO、YOLO及其转换

最近在做基于深度学习的目标检测,数据标注软件选择的LabelImg。

常用的几种标注格式及目录安排

一、VOC(标注文件xml结尾)

首先看一下VOC格式的分布:

在VOC这些文件夹中,我们主要用到:

① JPEGImages文件夹:图片

② Annotations文件夹:与图片对应的xml文件

③ ImageSets/Main文件夹:将数据集分为训练集和验证集,因此产生的train.txt和val.txt。

1.1 建立VOC文件目录,创建train.txt和test.txt

preview

 原有的图片都放在JPEGImages目录下,标签文件放在Annotations下。

import os
import randomtrainval_percent = 0.1
train_percent = 0.9xmlfilepath = 'Annotations'txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')for i in list:name = total_xml[i][:-4] + '\n'if i in trainval:ftrainval.write(name)if i in train:ftest.write(name)else:fval.write(name)else:ftrain.write(name)ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

运行完在ImageSets/Main下生成了4个txt文件,文件的内容是对应图片名称。

1.2 根据txt中文件名,移动图片和label到指定文件夹

# -*- coding: utf-8 -*-# @Brief   : 生成测试、验证、训练的图片和标签import os
import shutil
from pathlib import Path
from shutil import copyfilefrom PIL import Image, ImageDraw
from xml.dom.minidom import parse
import numpy as np
from tqdm import tqdm# FILE_ROOT = Path(r"E:\AI_Project\AI_Learning\Dataset")
FILE_ROOT = Path(r"/media/yake/6AB604BAB6048931/AI_yake/Dataset_数据集/安全帽/VOCdevkit")# 原始数据集 E:\AI_Project\AI_Learning\Dataset\VOC2028\ImageSets\Main
# /media/yake/6AB604BAB6048931/AI_yake/Dataset_数据集/安全帽/VOCdevkit/VOC2028
IMAGE_SET_ROOT = FILE_ROOT.joinpath(r"VOC2028/ImageSets/Main")  # 图片区分文件的路径
IMAGE_PATH = FILE_ROOT.joinpath(r"VOC2028/JPEGImages")  # 图片的位置
ANNOTATIONS_PATH = FILE_ROOT.joinpath(r"VOC2028/Annotations")  # 数据集标签文件的位置
LABELS_ROOT = FILE_ROOT.joinpath(r"VOC2028/Labels")  # 进行归一化之后的标签位置# YOLO 需要的数据集形式的新数据集
DEST_IMAGES_PATH = Path(r"Safety_Helmet_Train_dataset/score/images")  # 区分训练集、测试集、验证集的图片目标路径
DEST_LABELS_PATH = Path(r"Safety_Helmet_Train_dataset/score/labels")  # 区分训练集、测试集、验证集的标签文件目标路径def cord_converter(size, box):"""将标注的 xml 文件标注转换为 darknet 形的坐标:param size: 图片的尺寸: [w,h]:param box: anchor box 的坐标 [左上角x,左上角y,右下角x,右下角y,]:return: 转换后的 [x,y,w,h]"""x1 = int(box[0])y1 = int(box[1])x2 = int(box[2])y2 = int(box[3])dw = np.float32(1. / int(size[0]))dh = np.float32(1. / int(size[1]))w = x2 - x1h = y2 - y1x = x1 + (w / 2)y = y1 + (h / 2)x = x * dww = w * dwy = y * dhh = h * dhreturn [x, y, w, h]def save_label_file(img_jpg_file_name, size, img_box):"""保存标签的解析文件:param img_jpg_file_name::param size::param img_box::return:"""save_file_name = LABELS_ROOT.joinpath(img_jpg_file_name).with_suffix('.txt')with open(save_file_name, "a+") as f:for box in img_box:if box[0] == 'person':  # 数据集 xml 中的 person 指的是头cls_num = 1elif box[0] == 'hat':cls_num = 2else:continuenew_box = cord_converter(size, box[1:])  # 转换坐标f.write(f"{cls_num} {new_box[0]} {new_box[1]} {new_box[2]} {new_box[3]}\n")def test_dataset_box_feature(file_name, point_array):"""使用样本数据测试数据集的建议框:param file_name: 图片文件名:param point_array: 全部的点 [建议框sx1,sy1,sx2,sy2]:return: None"""im = Image.open(IMAGE_PATH.joinpath(file_name).with_suffix(".jpg"))im_draw = ImageDraw.Draw(im)for box in point_array:x1 = box[1]y1 = box[2]x2 = box[3]y2 = box[4]im_draw.rectangle((x1, y1, x2, y2), outline='red')im.show()def get_xml_data(img_xml_file: Path):"""获取 xml 数据:param img_xml_file: 图片路径:return:"""dom = parse(str(img_xml_file))xml_root = dom.documentElementimg_name = xml_root.getElementsByTagName("filename")[0].childNodes[0].dataimg_size = xml_root.getElementsByTagName("size")[0]objects = xml_root.getElementsByTagName("object")img_w = img_size.getElementsByTagName("width")[0].childNodes[0].dataimg_h = img_size.getElementsByTagName("height")[0].childNodes[0].dataimg_c = img_size.getElementsByTagName("depth")[0].childNodes[0].dataimg_box = []for box in objects:cls_name = box.getElementsByTagName("name")[0].childNodes[0].datax1 = int(box.getElementsByTagName("xmin")[0].childNodes[0].data)y1 = int(box.getElementsByTagName("ymin")[0].childNodes[0].data)x2 = int(box.getElementsByTagName("xmax")[0].childNodes[0].data)y2 = int(box.getElementsByTagName("ymax")[0].childNodes[0].data)img_box.append([cls_name, x1, y1, x2, y2])# test_dataset_box_feature(img_xml_file.name, img_box)save_label_file(img_xml_file.name, [img_w, img_h], img_box)def copy_data(img_set_source, img_labels_root, imgs_source, dataset_type):"""将标签文件和图片复制到最终数据集文件夹中:param img_set_source: 原数据集图片总路径:param img_labels_root: 生成的 txt 标签总路径:param imgs_source::param dataset_type: 生成数据集的种类:return:"""file_name = img_set_source.joinpath(dataset_type).with_suffix(".txt")  # 获取对应数据集种类的图片# 判断目标图片文件夹和标签文件夹是否存在,不存在则创建os.makedirs(FILE_ROOT.joinpath(DEST_IMAGES_PATH, dataset_type), exist_ok=True)os.makedirs(FILE_ROOT.joinpath(DEST_LABELS_PATH, dataset_type), exist_ok=True)with open(file_name, encoding="UTF-8") as f:for img_name in tqdm(f.read().splitlines()):img_sor_file = imgs_source.joinpath(img_name).with_suffix('.jpg')label_sor_file = img_labels_root.joinpath(img_name).with_suffix('.txt')# 复制图片dict_file = FILE_ROOT.joinpath(DEST_IMAGES_PATH, dataset_type, img_name).with_suffix('.jpg')copyfile(img_sor_file, dict_file)# 复制 labeldict_file = FILE_ROOT.joinpath(DEST_LABELS_PATH, dataset_type, img_name).with_suffix('.txt')copyfile(label_sor_file, dict_file)if __name__ == '__main__':root = ANNOTATIONS_PATH  # 数据集 xml 标签的位置if LABELS_ROOT.exists():# 清空标签文件夹print("Cleaning Label dir for safety generating label, pls wait...")shutil.rmtree(LABELS_ROOT)print("Cleaning Label dir done!")LABELS_ROOT.mkdir(exist_ok=True)  # 建立 Label 文件夹# 生成标签print("Generating Label files...")with tqdm(total=len(os.listdir(root))) as p_bar:for file in root.iterdir():p_bar.update(1)get_xml_data(file)# 将文件进行 train、val、test 的区分for dataset_input_type in ["train", "val", "test"]:print(f"Copying data {dataset_input_type}, pls wait...")copy_data(IMAGE_SET_ROOT, LABELS_ROOT, IMAGE_PATH, dataset_input_type)

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

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

相关文章

Dapp的优势与前景,具唯一性公开可追溯

​小编介绍:10年专注商业模式设计及软件开发,擅长企业生态商业模式,商业零售会员增长裂变模式策划、商业闭环模式设计及方案落地;扶持10余个电商平台做到营收过千万,数百个平台达到百万会员,欢迎咨询。 在…

B3768 [语言月赛202305] 独行

传送门: https://www.luogu.com.cn/problem/B3768 直接手推模拟,找规律,照着遍就行。 以下是找规律部分: int sq, sh, sw, nt;1.sq v0 * T1;if (sq > s) {nt s / v0;break;}sh v1 * t1;sw sq - sh;sw max (sw, 0);nt …

216699-36-4,6-Rhodamine X NHS ester,具有良好的脂溶性

117491-83-5,1890922-83-4,216699-36-4,6-Rhodamine X NHS ester,ROX SE, 6-isomer,6-ROX NHS 活化酯 您好,欢迎来到新研之家 文章关键词:117491-83-5,1890922-83-4,21…

【知识整理】Git Commit Message 规范

一. 概述 前面咱们整理过 Code Review 一文,提到了 Review 的重要性,已经同过gitlab进行CodeReview 的方式,那么本文详细说明一下对CodeReivew非常重要的Git Commit Message 规范。 我们在每次提交代码时,都需要编写 Commit Mes…

【C语言】指针变量未初始化

我们知道:全局变量未赋初值,编译器会直接赋值为0;局部变量如果未赋初值,则会维持上一状态保存在该地址上的值,这个值是随机的。把这个值赋值给局部变量是没有意义的。 但是指针变量是如何解决不赋初值? 指…

备战蓝桥杯—— 双指针技巧巧答链表2

对于单链表相关的问题,双指针技巧是一种非常广泛且有效的解决方法。以下是一些常见问题以及使用双指针技巧解决: 合并两个有序链表: 使用两个指针分别指向两个链表的头部,逐一比较节点的值,将较小的节点链接到结果链表…

基于STM32的宠物箱温度湿度监控系统

基于STM32的宠物箱温度湿度监控系统 一、引言 随着人们生活水平的提高,养宠物已经成为越来越多人的选择。宠物作为家庭的一员,其生活环境和健康状况受到了广泛关注。温度和湿度是影响宠物舒适度和健康的重要因素之一。因此,开发一款能够实时监控宠物箱温度和湿度的系统具有…

编程学习线上提问现场解答流程,零基础学编程从入门到精通

编程学习线上提问现场解答流程 一、前言 之前给大家分享的一款中文编程工具,越来越多的学员使用这个工具学习编程。 在学习中有疑难问题寻求解答流程 1、可以在本平台留言或发私信联系老师 2、可以在群提问及时解答问题 3、通过线上会议的方式,电脑…

Hudi程序导致集群RPC偏高问题分析

1、背景 Hudi程序中upsert操作频繁,过多的删除和回滚操作,导致集群RPC持续偏高 2、描述 hudi采用的是mvcc设计,提供了清理工具cleaner来把旧版本的文件分片删除,默认开启了清理功能,可以防止文件系统的存储空间和文件数量的无限…

企业计算机服务器中了crypt勒索病毒怎么办,crypt勒索病毒解密数据恢复

计算机服务器设备为企业的生产运营提供了极大便利,企业的重要核心数据大多都存储在计算机服务器中,保护企业计算机服务器免遭勒索病毒攻击,是一项艰巨的工作任务。但即便很多企业都做好的了安全运维工作,依旧免不了被勒索病毒攻击…

第1~8章 综合复习

1. 重置root密码 1. 重启服务器(虚拟机)2. 快速选择第二项,然后按 e 键3. 在linux这一行的最后加上一个空格,然后输入 rd.break,然后按 ctrl x 来重启服务4. 在提示符所在位置输入 mount -o remount,rw /sysroot5. 在…

C++内存管理 | new和delete使用与原理简单介绍

文章目录 1.new和delete操作符基本使用2.operator new与operator delete函数3.常见面试题 1.new和delete操作符基本使用 C使用new和delete操作符来管理堆上的动态资源。 对内置类型操作 对内置类型,不做初始化处理,使用new和delete和malloc和free申请内…

MYSQL-入门

一.安装和连接 1.1 安装 mysql安装教程: 2021MySql-8.0.26安装详细教程(保姆级)_2021mysql-8.0.26安装详细教程(保姆级)_mysql8.0.26_ylb呀的博客-cs-CSDN博客 workbench安装: MySQL Workbench 安装及使用-CSDN博客 1.2 配…

有哪些适合程序员的副业

如果你经常玩知乎、看公众号(软件、工具、互联网这几类的)你就会发现,好多资源连接都变成了夸克网盘、迅雷网盘的资源链接。 例如:天涯神贴,基本上全是夸克、UC、迅雷网盘的资源链接。 有资源的前提下,迅雷…

【leetcode刷题之路】面试经典150题(4)——栈+链表

文章目录 7 栈7.1 【哈希表】有效的括号7.2【栈】简化路径7.3 【栈】最小栈7.4 【栈】逆波兰表达式求值7.5 【栈】基本计算器 8 链表8.1 【双指针】环形链表8.2 【双指针】两数相加8.3 【双指针】合并两个有序链表8.4 【哈希表】随机链表的复制8.5 【链表】反转链表 II8.6 【链…

第二部分:准备工作

在开始AI视频生成项目之前,有两项关键的准备工作需要完成:数据收集与处理以及环境搭建与配置。这些步骤为成功运行和实施AI视频生成模型打下基础。 数据收集与处理 如何收集视频数据 AI模型的训练质量在很大程度上依赖于所用数据的质量和多样性。视频…

65-JQuery操作节点

1.JQuery创建节点$("标签") <script>//JQuery创建节点//$("标签")$("<p></p>");$("<p>这是p的内容</p>");</script> 2.父元素内部的末尾添加父.append(子元素),子.appendTo(父元素) <button…

LLM (Large language model)的指标参数

1. 背景介绍 我们训练大模型的时候&#xff0c;或者我们用RAG的时候&#xff0c;不知道我们的算法&#xff0c;或者我们的提示&#xff0c;或者我们的本地知识库是否已经整理得符合要求了。又或我们需要一个指标去评估我们目前的所有围绕大模型&#xff0c;向量数据库或外挂知…

git中将所有修改的文件上传到暂存区

案例&#xff1a; 我将本地的多个文件进行了修改&#xff0c;导致文件发生了变化。使用git status命令&#xff0c;查看文件的状态&#xff0c;发现有多个文件是modified&#xff0c;即被修改了。 本地文件发生了变化&#xff0c;需要将modified的文件添加到暂存区&#xff0c…

【计算机毕业设计】541鲜花商城系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…