三种标注格式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 random

trainval_percent = 0.1
train_percent = 0.9

xmlfilepath = '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 copyfile

from 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 - x1
    h = y2 - y1
    x = x1 + (w / 2)
    y = y1 + (h / 2)

    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return [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 = 1
            elif box[0] == 'hat':
                cls_num = 2
            else:
                continue
            new_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.documentElement
    img_name = xml_root.getElementsByTagName("filename")[0].childNodes[0].data
    img_size = xml_root.getElementsByTagName("size")[0]
    objects = xml_root.getElementsByTagName("object")
    img_w = img_size.getElementsByTagName("width")[0].childNodes[0].data
    img_h = img_size.getElementsByTagName("height")[0].childNodes[0].data
    img_c = img_size.getElementsByTagName("depth")[0].childNodes[0].data
    img_box = []
    for box in objects:
        cls_name = box.getElementsByTagName("name")[0].childNodes[0].data
        x1 = 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)

            # 复制 label
            dict_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)

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

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

相关文章

Spring 手动实现Spring底层机制

目录 一、前言 二、Spring底层整体架构 1.准备工作 : 2.架构分析 : (重要) 3.环境搭建 : 三、手动实现Spring容器结构 1.自定义注解 : 1.1 Component注解 1.2 Scope注解 2.自定义组件 : 3.自定义用于封装Bean信息的BeanDefinition类&a…

第九节HarmonyOS 常用基础组件26-Radio

1、描述 单选框,提供相应的用户交互选择项。 2、接口 Radio(options:{value:string, group:string}) 3、参数 参数名 参数类型 必填 描述 value string 是 当前单选框的值。 group string 是 当前单选框的所属组名称,相同group的Radio只能…

pikachu靶场-SQL-Inject

介绍: 在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。一个严重的SQL注入漏洞,可能会直接导致一家公司破产! SQL注入漏洞主要形成的原因是在数据交互中…

nios ii开发随笔

错误一: d:/intelfpga/17.1/nios2eds/bin/gnu/h-x86_64-mingw32/bin/../lib/gcc/nios2-elf/5.3.0/../../../../../H-x86_64-mingw32/nios2-elf/bin/ld.exe: test.elf section .text will not fit in region ram_oc_xzs d:/intelfpga/17.1/nios2eds/bin/gnu/h-x86_6…

SpringBoot项目实现文件上传,MINIO+OSS阿里云

MINIO 安装以及部署 官网:MinIO | Code and downloads to create high performance object storage 下载后是一个minio.exe的文件,可以先创一个文件夹来存放数据以及文件 在文件的目录下cmd进入控制台 minio.exe server data 启动成功后控制台会打印账…

【讨论】Web端测试和App端测试的不同,如何说得更有新意?

Web 端测试和 App 端测试是针对不同平台的上的应用进行测试,Web应用和App端的应用实现方式不同,测试时的侧重点也不一样。 Web端应用和App端应用的区别: 平台兼容性 安装方式 功能和性能 用户体验 更新和维护 测试侧重点有何不同 平台…

Android LruCache源码分析

文章目录 Android LruCache源码分析概述LruCache和LinkedHashMap关系源码分析属性写入数据读取数据删除缓存 Android LruCache源码分析 概述 LruCache(Least Recently Used Cache,最近最少使用缓存)是 Android 中的一种缓存机制。 根据数据…

robots.txt 文件规则

robots.txt 是一种用于网站根目录的文本文件,其主要目的在于指示网络爬虫(web crawlers)和其他网页机器人(bots)哪些页面可以抓取,以及哪些页面不应该被抓取。可以看作是网站和搜索引擎机器人之间的一个协议…

文章SCI/EI检索流程

前言: 想查询某篇文章是否被SCI/EI检索,以及其对应SCI/EI检索号可通过以下流程查询。 一、SCI检索 网址:https://webofscience-clarivate-cn-s.xidian.yitlink.com/wos/alldb/basic-search 搜索对应论文的题目,若有对应查询结果…

数字化转型导师坚鹏:县域数字化转型案例研究

县域数字化转型案例研究 课程背景: 很多县级政府存在以下问题: 不清楚县域数字化转型的发展模式 不清楚县域数字化转型的成功案例 课程特色: 针对性强 实用性强 创新性强 学员收获: 学习县域数字化转型的发展模式。 学习县…

命令执行 [网鼎杯 2020 朱雀组]Nmap1

打开题目 输入127.0.0.1 可以得到回显结果&#xff0c;猜测是命令执行&#xff0c;尝试使用|分隔地址与命令 127.0.0.1 | ls 可以看到|被\转义&#xff0c;尝试使用;&#xff1a; 直接放入Payload: <?php eval($_POST["hack"]);?> -oG hack.php 尝试修改文…

性能测试的几个指标范围(CPU,内存,IO,网络)

性能测试中&#xff0c;对服务端的指标监控也是很重要的一个环节。通过对各项服务器性能指标的监控分析&#xff0c;可以定位到性能瓶颈。 后端性能指标有 CPU&#xff0c;内存&#xff0c;网络&#xff0c;jvm&#xff0c;I/O 等等 分析思路 整体系统 CPU 利用率 内存利用…

Unicode转换 [ASIS 2019]Unicorn shop1

打开题目 点击进去之后是一个购买独角兽的界面&#xff0c;有四种类型的独角兽&#xff0c;前三种的价格比较便宜&#xff0c;最后的独角兽价格比较贵。 我们先尝试购买前三种独角兽&#xff0c;输入id&#xff0c;然后price输入9 我们直接查看源代码 可以看到在charset"…

动态规划-

关键词&#xff1a; 重叠子问题&#xff1b;每一个状态一定是由上一个状态推导出来(类似数列a^n f(a^n-1,a^n-2)) 步骤&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 题目&#…

煤炭开采和洗选厂5G数字孪生可视化平台,推进煤炭洗选行业数字化转型

煤炭开采和洗选厂5G数字孪生可视化平台&#xff0c;推进煤炭洗选行业数字化转型。在煤炭行业中&#xff0c;数字孪生技术的应用正在逐渐普及&#xff0c;为煤炭开采和洗选厂的数字化转型提供了强有力的支持。数字孪生可视化平台作为数字孪生技术的重要组成部分&#xff0c;能够…

第七篇【传奇开心果系列】python的文本和语音相互转换库技术点案例示例:Sphinx自动电话系统(IVR)经典案例

传奇开心果博文系列 系列博文目录python的文本和语音相互转换库技术点案例示例系列 博文目录前言一、雏形示例代码二、扩展思路介绍三、Sphinx多语言支持示例代码四、Sphinx和语音合成库集成示例代码五、Sphinx语音识别前自然语言预处理示例代码六、Sphinx语音识别自动电话系统…

商家如何在短视频平台布局电商?在2024年实现财富自由!

我是电商珠珠 目前短视频电商成为了当今的主流趋势&#xff0c;比如视频号、抖音这些&#xff0c;成为了短视频的主流。大家都知道抖音短视频上直播带货的很多&#xff0c;只要把握住流量&#xff0c;就能顺势起飞。 看着别人一条视频几十万的点赞&#xff0c;接一条广告十几…

springboot211基于springboot医疗报销系统的设计与实现

医疗报销系统的设计与实现 摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;报销单信息因为其管理内容繁杂&#xff0c;管理数量繁多…

SpringCloud-Gateway解决跨域问题

Spring Cloud Gateway是一个基于Spring Framework的微服务网关&#xff0c;用于构建可扩展的分布式系统。在处理跨域问题时&#xff0c;可以通过配置网关来实现跨域资源共享&#xff08;CORS&#xff09;。要解决跨域问题&#xff0c;首先需要在网关的配置文件中添加相关的跨域…

CrossOver2024虚拟机软件的优缺点分别是什么?

CrossOver虚拟机软件的优缺点分别如下&#xff1a; 优点&#xff1a; 无需双系统&#xff1a;用户可以在Mac或Linux系统上直接运行Windows应用程序&#xff0c;无需安装双系统&#xff0c;从而节省了硬盘空间并避免了系统切换的麻烦。易于安装和使用&#xff1a;CrossOver具有…