【YOLO】基于YOLOv8实现自定义数据的自动标注(针对VOC格式的数据集)

2023-05-16

基于YOLOv8实现自定义数据的自动标注

  • 引言
  • VOC格式的数据集自标注实现

引言

利用yolov8的检测模型实现数据集的自标注,针对VOC数据集,.xml文件,labelimg标注工具

VOC格式的数据集自标注实现

yolov8模型的训练可以参考笔者的博客
【YOLO】YOLOv8实操:环境配置/自定义数据集准备/模型训练/预测
训练好自定义的模型,就可以执行下面的代码实现模型自标注数据集
修改下面三个参数即可:

weight_path = "/media/ll/L/llr/model/yolov8/weights/best.pt"  # 模型路径
imgdir = r'/media/ll/L/llr/DATASET/subwayDatasets/bjdt/images'  # 图片路径
xmldir = r'/media/ll/L/llr/DATASET/ZED_DATA/GZG/bjdt_daytime/xml'  # 标注文件保存路径

完整代码如下:

"""
Fuction:使用预训练模型权重对图像集进行识别后自动标注
Author: Alian
Create_Date:2023.03.30
Finishe_Date:2023.03.30
"""
import os
from os import getcwd
import glob
from xml.etree import ElementTree as ET
from utils.general import *
# from utils.datasets import *
from utils import torch_utils
from ultralytics import YOLO  # YOLOV8


# 定义一个创建一级分支object的函数
def create_object(root, xyxy, names,cls):  # 参数依次,树根,xmin,ymin,xmax,ymax
    # 创建一级分支object
    _object = ET.SubElement(root, 'object')
    # 创建二级分支
    name = ET.SubElement(_object, 'name')
    # print(obj_name)
    name.text = str(names[int(cls)])
    pose = ET.SubElement(_object, 'pose')
    pose.text = 'Unspecified'
    truncated = ET.SubElement(_object, 'truncated')
    truncated.text = '0'
    difficult = ET.SubElement(_object, 'difficult')
    difficult.text = '0'
    # 创建bndbox
    bndbox = ET.SubElement(_object, 'bndbox')
    xmin = ET.SubElement(bndbox, 'xmin')
    xmin.text = '%s' % int(xyxy[0])
    ymin = ET.SubElement(bndbox, 'ymin')
    ymin.text = '%s' % int(xyxy[1])
    xmax = ET.SubElement(bndbox, 'xmax')
    xmax.text = '%s' % int(xyxy[2])
    ymax = ET.SubElement(bndbox, 'ymax')
    ymax.text = '%s' % int(xyxy[3])


# 创建xml文件的函数
def create_tree(image_path, h, w):
    # 创建树根annotation
    annotation = ET.Element('annotation')
    # 创建一级分支folder
    folder = ET.SubElement(annotation, 'folder')
    # 添加folder标签内容
    folder.text = os.path.dirname(image_path)

    # 创建一级分支filename
    filename = ET.SubElement(annotation, 'filename')
    filename.text = os.path.basename(image_path)

    # 创建一级分支path
    path = ET.SubElement(annotation, 'path')

    path.text = image_path  # 用于返回当前工作目录getcwd() + '\{}'.format

    # 创建一级分支source
    source = ET.SubElement(annotation, 'source')
    # 创建source下的二级分支database
    database = ET.SubElement(source, 'database')
    database.text = 'Unknown'

    # 创建一级分支size
    size = ET.SubElement(annotation, 'size')
    # 创建size下的二级分支图像的宽、高及depth
    width = ET.SubElement(size, 'width')
    width.text = str(w)
    height = ET.SubElement(size, 'height')
    height.text = str(h)
    depth = ET.SubElement(size, 'depth')
    depth.text = '3'

    # 创建一级分支segmented
    segmented = ET.SubElement(annotation, 'segmented')
    segmented.text = '0'

    return annotation


def pretty_xml(element, indent, newline, level=0):  # elemnt为传进来的Elment类,参数indent用于缩进,newline用于换行
    if element:  # 判断element是否有子元素
        if (element.text is None) or element.text.isspace():  # 如果element的text没有内容
            element.text = newline + indent * (level + 1)
        else:
            element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * (level + 1)
            # else:  # 此处两行如果把注释去掉,Element的text也会另起一行
            # element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * level
    temp = list(element)  # 将element转成list
    for subelement in temp:
        if temp.index(subelement) < (len(temp) - 1):  # 如果不是list的最后一个元素,说明下一个行是同级别元素的起始,缩进应一致
            subelement.tail = newline + indent * (level + 1)
        else:  # 如果是list的最后一个元素, 说明下一行是母元素的结束,缩进应该少一个
            subelement.tail = newline + indent * level
        pretty_xml(subelement, indent, newline, level=level + 1)  # 对子元素进行递归操作


def Auto_label(weight,imgdir,xmldir):
    # load model
    model = YOLO(weight)
    img_list = glob.glob('%s/*.*' % imgdir)
    for img_path in img_list:
        results = model(img_path,show=False,save=False)[0]  # predict on an image
        # 创建xml文件
        annotation = create_tree(img_path, results.orig_shape[0], results.orig_shape[1])
        det = results.boxes
        names = results.names
        cls = det.cls
        for i in range(len(det)):
            create_object(annotation,det.xyxy[i],names,cls[i])
        # 将树模型写入xml文件
        tree = ET.ElementTree(annotation)
        root = tree.getroot()
        pretty_xml(root, '\t', '\n')
        # tree.write('.\{}\{}.xml'.format(outdir, image_name.strip('.jpg')), encoding='utf-8')
        tree.write(img_path.replace(imgdir,xmldir).replace('.jpg','.xml'), encoding='utf-8')




if __name__ == '__main__':
    # 加载模型
    weight_path = "/media/ll/L/llr/model/yolov8/weights/best.pt"  # 模型路径
    imgdir = r'/media/ll/L/llr/DATASET/subwayDatasets/bjdt/images'  # 图片路径
    xmldir = r'/media/ll/L/llr/DATASET/ZED_DATA/GZG/bjdt_daytime/xml'  # 标注文件保存路径
    Auto_label(weight_path,imgdir,xmldir)  # 调用自标注函数

综上,就实现了利用yolov8的检测模型实现数据集的自动标注,不过标注结果最好人工复查下,但是已经省下很多标注时间啦

后续会更新COCO数据格式的自动标注博客,即.json文件,labelme标注工具的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【YOLO】基于YOLOv8实现自定义数据的自动标注(针对VOC格式的数据集) 的相关文章

  • 分别在 visual studio 2022 和 visual studio code中配置opencv环境,并运行相关代码

    window10环境下 xff1a 一 在visual studio 2022中配置opencv环境 xff0c 并运行相关代码 1 安装visual studio 2022 xff0c 在官网下载社区版安装包 1 1 下载后双击运行安装包
  • 0.8 - GPIO的输入输出模式

    GPIO xff1a General purpose input output 从参考手册可知 xff0c GPIO可以配置成上图中的多种模式 xff0c 但是要理解这些名字的含义还是要具体分析GPIO功能框图 xff1a 结合GPIO的输
  • opencv基础-印度小哥

    基础课程 第一章 读取图片 视频和摄像头 Chapter 1 Read Images Videos and Webcams 图片放在程序所在文件夹下的Resources test png 1 1 opencv读取一张图片并显示 xff1a
  • 为ubuntu配置WiFi

    1 前提条件 ubuntu不论什么版本 xff0c 如果想要正常使用wifi xff0c 必须在电脑的bios中把secure boot设定为disable 2 快捷指令 xff08 WiFi相关的常用命令行指令 xff09 2 1查看电脑
  • 嵌入式C语言自我修养:从芯片、编译器到操作系统-习题、笔记

    前沿 C语言测试 1 基本概念考查 什么是标识符 关键字和预定义标识符 三者有何区别 标识符 xff08 Identifier xff09 由程序员定义 xff0c 用来表示变量 xff0c 包括了变量名 函数名 宏名 结构体名等 标识符的
  • smile@smile-X3-S:~/app_install/mapx/build$ sudo make

    smile 64 smile X3 S app install mapx build span class token function sudo span span class token function make span span
  • 两台ubuntu之间文件互传方法

    1 查找本机ip地址 终端输入 xff08 不是自己的电脑 xff0c 是服务其的IP xff09 xff1a ifconfig span class token operator span a 查看inet 192打头的地址 2 查找本机
  • 单片机通过串口发送浮点类型数据

    单片机通过串口向串口助手或者其他器件发送数据时是不能直接发送浮点类型数据的 xff0c 通过printf 34 f 34 1 28 发送浮点数据 在串口助手看似是小数 xff0c 其实是字符串类型 xff0c 它们是各符号对应的ASSCII
  • 制作系统启动盘和制作windows+Ubuntu双系统启动盘

    制作windows 43 Ubuntu双系统启动盘 前言1 准备软件和工具 xff1a 开始1 软件和系统镜像自行在网上下载 2 下载好系统镜像之后 xff0c 开始制作ubuntu系统盘 xff1a 3 制作好ubuntu启动盘之后 xf
  • 虚拟机分配的硬盘太大怎么办?

    虚拟机分配的硬盘太大怎么办 xff1f 虚拟机分配的硬盘太大怎么办 xff1f 文章来源说明 xff1a 开始1 首先需要将虚拟机中多余的硬盘空间删除 xff0c 在此电脑中右键管理 xff0c 然后在磁盘管理中右键有多余空间的磁盘进行压缩
  • QT界面窗口的显示和隐藏,关闭

    这里写目录标题 QT窗口的显示和隐藏 xff1a 1 隐藏窗口1 1 介绍 xff1a 2 显示窗口2 1 介绍 xff1a 3 关闭窗口常用函数有 xff1a QT窗口的显示和隐藏 xff1a 1 隐藏窗口 span class toke
  • QT的中文显示乱码问题解决

    QT的中文显示乱码问题解决 QT的中文显示乱码问题解决 xff1a 1 查看源文件的编码格式 xff0c 有必要的话转换源文件的编码格式再重新编译运行尝试汉字能否正常显示 2 在代码里面解决 xff1a 3 用法 xff1a QT的中文显示
  • 0.9 - GPIO寄存器的C语言映射与STM32库函数雏形构建思路

    首先 xff0c 从参考手册可知 xff0c 程序存储器 xff08 flash xff09 数据存储器 SRAM 寄存器 外设控制 和输入输出端口被组织在同一个4GB的线性地址空间内 数据字节以小端格式存放在存储器中 一个字里的最低地址字
  • Linux文件/文件夹建立软硬链接

    建立软连接 xff1a sudo ln s home spike Downloads redis src redis server usr local bin redis server 源文件 链接到 目标文件 xff0c 这两个文件目录都
  • Linux中记录终端(Terminal)输出到文本文件四种方法

    Linux中记录终端 xff08 Terminal xff09 输出到文本文件 Linux中记录终端 xff08 Terminal xff09 输出到文本文件 一 xff0c 如何把命令运行的结果保存到文件当中 二 command gt f
  • C++ 标准库头文件汇集:

    C 43 43 标准库头文件汇集 xff1a C 43 43 标准库的接口由下列头文件的汇集定义 C 43 43 标准库头文件汇集 xff1a 概念库协程库工具库动态内存管理数值极限错误处理字符串库容器库迭代器库范围库算法库数值库本地化库输
  • C++开源库列表总结记录

    开源 C 43 43 库列表 前言包管理器库音频 音频指纹格式标签CD 性能测试 通信 并发 配置 XMLJSONYAMLTOMLHOCONCSS容器 密码学 数据库 嵌入语言绑定 嵌入式 实时 文件元数据 金融计算 游戏引擎架构 通用多媒
  • C++转义序列和操作符优先级

    C 43 43 转义序列和操作符优先级 1 转义序列 xff1a 2 C 43 43 运算符优先级注解 1 转义序列 xff1a 转义序列 描述 表示 简单转义序列 39 单引号 ASCII 编码中为字节 0x27 34 双引号 ASCII
  • PX4:Policy “CMP0097“ is not known to this version of CMake.

    make px4 fmu v3 时报的错 CMake版本的问题 由https blog csdn net zhizhengguan article details 118380965推测 xff0c 删除cmake policy也没事 ma
  • 安装Anaconda3后再安装ROS(用于PX4)

    记录一下安装anaconda后再安装ROS xff0c 方便未来找错误 出现no module wstool 仔细观察报错信息发现调用的库都在anaconda3 lib python3 7里面了 随后按照https www cnblogs

随机推荐