数据集生成 YOLOV5 可训练的数据目录、并且可视化

news2024/10/6 0:30:57

1、前言

YOLOV5 训练数据的目录结构如下:

如果有测试集的话,也按照下面目录摆放即可
 

注意:这里的图片和标签文件名要严格对应!!后缀除外

关于YOLOv5介绍或者yolo格式的介绍参考之前专栏,

2、划分数据+生成YOLOV5的训练目录+可视化

测试的数据目录结构如下:

2.1 划分数据保存成yolov5的目录

代码如下:

import os
import shutil
import random
from tqdm import tqdm


'''
--datasets--images--train       # 训练集图片
          --images--val         # 验证集图片

--datasets--labels--train       # 训练集标签
          --labels--val         # 验证集标签
'''


def mkdir():
    os.mkdir('datasets')
    os.mkdir('datasets/images')
    os.mkdir('datasets/labels')
    os.mkdir('datasets/images/train')
    os.mkdir('datasets/images/val')
    os.mkdir('datasets/labels/train')
    os.mkdir('datasets/labels/val')


def split_yolov5(floder,rate,img_f):
    mkdir()         # 创建 yolov5的目录,已有datasets文件夹,需要删除

    floder = os.path.join(floder,'images')
    image_path = [os.path.join(floder,i) for i in os.listdir(floder)]
    val_path = random.sample(image_path,k=int(len(image_path)*rate))        # 划分的 val数据

    train_num = 0
    val_num = 0
    for i in tqdm(image_path):
        label_path = i.replace(('.'+img_f),'.txt')      # 标签路径
        label_path = label_path.replace('images','labels')

        if i in val_path:       # 验证集
            val_num +=1
            shutil.copy(i,'./datasets/images/val')
            shutil.copy(label_path,'./datasets/labels/val')

        else:                   # 训练集
            train_num +=1
            shutil.copy(i,'./datasets/images/train')
            shutil.copy(label_path,'./datasets/labels/train')

    print('split over!!')
    print('data set number is: ',len(image_path))
    print('train set number is: ',train_num)
    print('val set number is: ',val_num)


if __name__ == '__main__':
    root = 'data'       # 待划分的数据目录
    split_rate = 0.2    # 划分验证集的比例
    image_format = 'jpg'        # 数据图片的格式

    split_yolov5(floder=root,rate=split_rate,img_f=image_format)

参数按照注释填即可

控制台输出:

 生成的数据:

2.2 可视化

根据之前的yolo可视化参考代码内容:关于目标检测任务中,YOLO(txt格式)标注文件的可视化_yolo格式的标签-CSDN博客

这里只是将目录更改:

需要提供txt的classes类别文本!!

import cv2
import os
import random


def txtShow(img, txt, save=True):
    image = cv2.imread(img)
    height, width = image.shape[:2]  # 获取原始图像的高和宽

    # 读取classes类别信息
    with open('datasets/classes.txt', 'r') as f:
        classes = f.read().splitlines()
    # ['Leconte', 'Boerner', 'linnaeus', 'armandi', 'coleoptera', 'acuminatus', 'Linnaeus']

    # 读取yolo格式标注的txt信息
    with open(txt, 'r') as f:
        labels = f.read().splitlines()
    # ['0 0.403646 0.485491 0.103423 0.110863', '1 0.658482 0.425595 0.09375 0.099702', '2 0.482515 0.603795 0.061756 0.045387', '3 0.594122 0.610863 0.063244 0.052083', '4 0.496652 0.387649 0.064732 0.049107']

    ob = []  # 存放目标信息
    for i in labels:
        cl, x_centre, y_centre, w, h = i.split(' ')

        # 需要将数据类型转换成数字型
        cl, x_centre, y_centre, w, h = int(cl), float(x_centre), float(y_centre), float(w), float(h)
        name = classes[cl]  # 根据classes文件获取真实目标
        xmin = int(x_centre * width - w * width / 2)  # 坐标转换
        ymin = int(y_centre * height - h * height / 2)
        xmax = int(x_centre * width + w * width / 2)
        ymax = int(y_centre * height + h * height / 2)

        tmp = [name, xmin, ymin, xmax, ymax]  # 单个检测框
        ob.append(tmp)

    # 绘制检测框
    for name, x1, y1, x2, y2 in ob:
        cv2.rectangle(image, (x1, y1), (x2, y2), color=(255, 0, 0), thickness=2)  # 绘制矩形框
        cv2.putText(image, name, (x1, y1 - 10), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=0.5, thickness=1, color=(0, 0, 255))

        # 保存图像
    if save:
        cv2.imwrite('result.png', image)

        # 展示图像
    cv2.imshow('test', image)
    cv2.waitKey()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    img_path = './datasets/images/train/'  # 传入图片
    image = [os.path.join(img_path, i) for i in os.listdir(img_path)]
    r = random.randint(0, len(image) - 1)  # 生成随机索引

    image_path = image[r]
    labels_path = image_path.replace('images', 'labels')  # 自动获取对应的 txt 标注文件
    labels_path = labels_path.replace('.jpg', '.txt')

    txtShow(img=image_path, txt=labels_path, save=True)

需要更改的就是图片后缀:

展示:

3、生成YOLOV5的训练目录

对于已经划分好的数据集,直接copy即可

待拷贝的目录:因为之前本人习惯用下面的目录结构,所以这里也是一样

完整代码:

import os
import shutil
import random
from tqdm import tqdm

'''
--datasets--images--train       # 训练集图片
          --images--val         # 验证集图片
--datasets--labels--train       # 训练集标签
          --labels--val         # 验证集标签
'''


def mkdir():
    os.mkdir('datasets')
    os.mkdir('datasets/images')
    os.mkdir('datasets/labels')
    os.mkdir('datasets/images/train')
    os.mkdir('datasets/images/val')
    os.mkdir('datasets/labels/train')
    os.mkdir('datasets/labels/val')


def split_yolov5(floder,img_f):
    mkdir()  # 创建 yolov5的目录,已有datasets文件夹,需要删除

    train_floder = os.path.join(floder, 'train/images')
    image_path = [os.path.join(train_floder, i) for i in os.listdir(train_floder)]

    train_num = 0
    for i in tqdm(image_path,desc='train set copy'):
        label_path = i.replace(('.' + img_f), '.txt')  # 标签路径
        label_path = label_path.replace('images', 'labels')

        train_num += 1
        shutil.copy(i, './datasets/images/train')
        shutil.copy(label_path, './datasets/labels/train')

    val_floder = os.path.join(floder, 'val/images')
    val_path = [os.path.join(val_floder, i) for i in os.listdir(val_floder)]

    val_num = 0
    for i in tqdm(val_path,desc='val set copy'):
        label_path = i.replace(('.' + img_f), '.txt')  # 标签路径
        label_path = label_path.replace('images', 'labels')

        val_num += 1
        shutil.copy(i, './datasets/images/val')
        shutil.copy(label_path, './datasets/labels/val')

    print('copy over!!')
    print('train set number is: ', train_num)
    print('val set number is: ', val_num)


if __name__ == '__main__':
    root = 'data'  # 划分好的数据目录
    image_format = 'jpg'  # 数据图片的格式

    split_yolov5(floder=root,img_f=image_format)

控制台输出:

4、其他

关于yolov5的可以参考专栏:目标检测_听风吹等浪起的博客-CSDN博客

关于其他目标检测的介绍:关于 object detection_听风吹等浪起的博客-CSDN博客

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

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

相关文章

指针篇章-(4)+qsort函数的模拟

学习目录 ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————…

第二十一天-NumPy

目录 什么是NumPy NumPy使用 1.数组的创建 2.类型转换 3.赠删改查 4.数组运算 5.矩阵运算 什么是NumPy 1.NumPy操作的是多维数组,什么是纬度? NumPy使用 1. 安装 pip install numpy import numpy as np 2.官网: 中文官网&#xff1a…

Vue3案例——通过指令实现下拉菜单效果

2.6 Vue3案例——通过指令实现下拉菜单效果 使用v-for指令可以对数组、对象进行循环,来获取其中的每一个值。 1. v-for指令遍历数组 使用v-for指令时,必须使用特定语法alias in expression,其中items是源数据数组,而item则是被…

java集合题库详解

1. Arraylist与LinkedList区别 可以从它们的底层数据结构、效率、开销进行阐述哈 ArrayList是数组的数据结构,LinkedList是链表的数据结构。 随机访问的时候,ArrayList的效率比较高,因为LinkedList要移动指针,而ArrayList是基于索…

宏工科技数智方案现先进陶瓷展,VR体验数字工厂引关注

3月6-8日,第十六届中国国际粉末冶金、硬质合金与先进陶瓷展览会在上海举行。本届展会,宏工科技股份有限公司携VR体验数字工厂和正负压气力输送系统惊艳亮相,“现实虚拟”的呈现方式收获众多行业客户及专业观众高度关注。 展会汇聚了来自粉末冶…

第十三届蓝桥杯嵌入式省赛程序设计详细题解

第十三届蓝桥杯嵌入式省赛题目相对于第十二届较为简单,没有那么多串口的数据处理以及判断! 第十三届省赛主要是制作一个可由串口设置密码的密码锁。本实验中,我们将用到LED模块、按键模块、串口模块、定时器的PWM模块以及官方会提供源码的LC…

[Linux_IMX6ULL应用开发]-hello程序的交叉编译

目录 【开发板、虚拟机和PC的三者联通】 使用串口连接到开发板 连接Ubuntu虚拟机 互ping测试 【交叉编译hello.c文件】 Ubuntu编译无法在板子运行问题 使用交叉编译链编译hello.c 【开发板、虚拟机和PC的三者联通】 在这里我们使用IMX6ULL-PRO开发板进行学习,…

python+requests接口自动化框架的实现

为什么要做接口自动化框架 1、业务与配置的分离 2、数据与程序的分离;数据的变更不影响程序 3、有日志功能,实现无人值守 4、自动发送测试报告 5、不懂编程的测试人员也可以进行测试 正常接口测试的流程是什么? 确定接口测试使用的工具…

内部应用解耦神器-Spring事件

大家好,我是程序员牛牛,《AI超级个体: ChatGPT与AIGC实战指南》的参与人,10年Java编程程序员。 1. 概述 在做业务开发过程中,有些复杂点的逻辑,可能代码逻辑会很冗长,举一个很简单的例子,如&am…

windows解决nodejs版本冲突:安装版本管理器nvm,可根据不同项目一键切换适配版本

windows解决nodejs版本冲突:安装版本管理器nvm,可根据不同项目一键切换适配版本 参考来源:在本机 Windows 上设置 NodeJS | Microsoft Learn 建议安装版本管理器 nvm-windows,再用它来安装 Node.js 和 npm,这样可以根据…

C++学习笔记:红黑树

红黑树 什么是红黑树红黑树的规则红黑树节点的定义红黑树的插入空树插入非空插入条件判断新插入的节点 cur 不为 root 且 parent->_col 为红就需要调整父节点为左 grandf->left parent当uncle节点为红色时,只需要进行颜色调整,即可当uncle为空 或 者存在但是为黑parent …

Midjourney能让角色保持一致了

Midjourney发布新功能,网友直呼“不可思议”! 现在你可以让生成的图像几乎保持角色一致,belike: 所有超级英雄长一个模样盯着你。 甚至动漫风、写实风等跨风格生成也同样适用: 保持同一风格,感jio配上文字…

【FPGA】DDR3学习笔记(一)丨SDRAM原理详解

本篇文章包含的内容 一、DDR3简介1.1 DDR3 SDRAM概述1.2 SDRAM的基础结构 二、 SDRAM操作时序2.1 SDRAM操作指令2.2 模式寄存器(LOAD MODE REGISTER)2.3 SDRAM操作时序示例2.3.1 SDRAM初始化时序2.3.2 突发读时序2.3.3 随机读时序2.3.4 突发写时序2.3.5 …

Java基础-接口

文章目录 1.快速入门代码:结果: 2.接口基本介绍1.语法注意:在jdk1.8以后接口才可以有静态方法,默认方法 2.代码实例 3.接口的应用场景1.场景介绍2.代码实例4.接口使用细节 5.接口课堂练习题目:答案:注意&am…

深入理解,java标识符?类型转换?

1、标识符 下面这张图是中国的一些姓氏 中国人起名字的规则都是以姓开头,名结尾。通过这个规则可以起:刘爱国、张三等,都是以汉字起的。但是不会起李ad、王123等名字,因为不符合规则。 所以,java在给变量、方法、类等…

【C++进阶】C++继承概念详解

C继承详解 一,继承的概念和定义1.1 继承的概念1.2 继承的定义1.3 继承关系和访问限定符 二,基类和派生类的对象赋值转移三,继承的作用域四,派生类的默认成员函数五,继承和友元&静态成员和继承六,菱形继…

Ansys Lumerical | 激光雷达天线仿真

附件下载 联系工作人员获取附件 在本文中,我们将了解如何根据激光雷达应用需求设计和优化相控阵光栅天线。 概述 激光雷达(LIDAR)是“light detection and ranging”的简称,近年来由于在机器人、自动驾驶汽车、高精度测绘等领域…

【AcWing】蓝桥杯集训每日一题Day2|前缀和|562.壁画(C++)

562. 壁画 562. 壁画 - AcWing题库难度:中等时/空限制:1s / 64MB总通过数:4154总尝试数:10197来源:Google Kickstart2018 Round H Problem B算法标签 思维题枚举前缀和 题目内容 Thanh 想在一面被均分为 N 段的墙上画…

[java——基础] 双亲委派机制

目录 核心思想: 双亲委派机制的好处: 三种类加载器 解析源代码 双亲委派思想面试总结: 核心思想: 向上搜索,向下加载。 双亲委派机制的好处: 防止Java核心类被篡改,防止类的重复加载。 三…

哈希表|15.三数之和

力扣题目链接 int cmp(const void *a,const void *b) {return *(int*)a - *(int*)b;} int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {*returnSize 0;if(numsSize < 3)return NULL;qsort(nums, numsSize, sizeof(int),cmp);int **…