YOLO系列之数据集划分

该博客基于另一篇博客展开,介绍YOLO系列数据集划分,以YOLOv8为例。阐述了YOLO系列数据集格式,图像和对应YOLO格式txt标签文件存放要求,还给出代码实现,可直接复制运行,需修改4个参数,默认按一定比例划分数据集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

YOLO系列之数据集划分(以YOLOv8为例)

前言

本博客是在我的另一篇博客labelme标注的json格式与yolo格式的相互转换 的基础上进行的,有需要可以参考

YOLO系列数据集格式

在数据集中,图像文件存放于images目录下,对应的YOLO格式的txt标签文件要存放于labels目录下,而且要在imageslabels目录下分别建立train训练集、valid验证集、test
测试集(可选,但强烈建议要有!)子目录,如下展示:

dataset
	- images
		- train
			- 1.jpg
			- 5.jpg # 因为要随机划分,所以数字是随机写的,下面也一样
			-  ... 
		- valid
			- 2.jpg
			- 7.jpg
			-  ...
		- test
			- 3.jpg
			- 9.jpg
			- ...
	- labels
		- train
			- 1.txt
			- 5.txt
			-  ... 
		- valid
			- 2.txt
			- 7.txt
			-  ...
		- test
			- 3.txt
			- 9.txt
			- ...

代码实现

以下代码可以直接复制运行(只需要修改参数)

本代码需要自行修改4个参数,分别是:
img_dir:存放图像数据的目录;
label_dir:存放对应YOLO格式标签的txt文件的目录;
split_dir:要存放划分后数据集的目录;
TEST:True表示需要划分测试集,否则不。

"""
将数据集划分为训练集,验证集,测试集
"""
import os
import random
import shutil


# 创建保存数据的文件夹
def makedir(new_dir):
    if not os.path.exists(new_dir):
        os.makedirs(new_dir)

def split_data(img_dir, label_dir, split_dir, TEST=True):
    '''
    args:
        img_dir:原图片数据集路径
        label_dir:原yolog格式txt文件数据集路径
        split_dir:划分后数据集保存路径
        TEST:是否划分测试集
        用于将数据集划分为YOLO数据集格式的训练集,验证集,测试集
    '''
    random.seed(42)  # 随机种子
    # 1.确定原图片数据集路径
    datasetimg_dir = img_dir
    # 确定原label数据集路径
    datasetlabel_dir = label_dir

    images_dir = os.path.join(split_dir, 'images')
    labels_dir = os.path.join(split_dir, 'labels')
    dir_list = [images_dir, labels_dir]
    if TEST:
        type_label = ['train', 'valid', 'test']
    else:
        type_label = ['train', 'valid']

    for i in range(len(dir_list)):
        for j in range(len(type_label)):
            makedir(os.path.join(dir_list[i], type_label[j]))

    # 3.确定将数据集划分为训练集,验证集,测试集的比例
    train_pct = 0.8
    valid_pct = 0.1
    test_pct = 0.1
    # 4.划分
    labels = os.listdir(datasetlabel_dir)  # 展示目标文件夹下所有的文件名
    labels = list(filter(lambda x: x.endswith('.txt'), labels))  # 取到所有以.txt结尾的yolo格式文件
    random.shuffle(labels)  # 乱序路径
    label_count = len(labels)  # 计算图片数量
    train_point = int(label_count * train_pct)  # 0:train_pct
    valid_point = int(label_count * (train_pct + valid_pct))  # train_pct:valid_pct
    for i in range(label_count):
        if i < train_point:  # 保存0-train_point的图片和标签到训练集
            out_dir = os.path.join(images_dir, 'train')
            label_out_dir = os.path.join(labels_dir, 'train')

        elif train_point <= i < valid_point:  # 保存train_point-valid_point的图片和标签到验证集
            out_dir = os.path.join(images_dir, 'valid')
            label_out_dir = os.path.join(labels_dir, 'valid')
        else:  # 保存test_point-结束的图片和标签到测试集
            out_dir = os.path.join(images_dir, 'test')
            label_out_dir = os.path.join(labels_dir, 'test')

        label_target_path = os.path.join(label_out_dir, labels[i])  # 指定目标保存路径
        label_src_path = os.path.join(datasetlabel_dir, labels[i])  # 指定目标原文件路径
        img_target_path = os.path.join(out_dir, labels[i].split('.')[0] + '.JPG')  # 指定目标保存路径
        img_src_path = os.path.join(datasetimg_dir, labels[i].split('.')[0] + '.JPG')  # 指定目标原图像路径
        shutil.copy(label_src_path, label_target_path)  # 复制txt
        shutil.copy(img_src_path, img_target_path)  # 复制图片
        

    print('train:{}, valid:{}, test:{}'.format(train_point, valid_point - train_point,
                                               label_count - valid_point))


if __name__ == "__main__":
    img_dir = r'totrain\segmentdata_withlabel\jpg'
    label_dir = r'totrain\segmentdata_withlabel\txt'
    split_dir = r'totrain\segmentdata_withlabel\split'
    split_data(img_dir, label_dir, split_dir, TEST=True)
    # for dir in os.listdir(root):
    #     if not dir.endswith('.py') and not dir.endswith('txt'):
    #         split_data(dir, label_dir, root, split_dir)

同时,本代码默认按照8:1:1的比例划分训练集、验证集和测试集如果需要修改这个比例,请在代码如下部分进行修改:

    # 3.确定将数据集划分为训练集,验证集,测试集的比例
    train_pct = 0.8
    valid_pct = 0.1
    test_pct = 0.1

在我自己的数据集中,划分完成如下图所示:
在这里插入图片描述

### YOLOv8 数据集划分方法 对于YOLOv8的数据集划分,一种常见的方式是按照7:2:1的比例来分配训练集、验证集和测试集[^1]。具体操作如下: #### 准备工作 确保数据集中每张图片都有对应的标签文件,并且这些文件存放在同一目录结构内。 #### 创建配置文件 创建或编辑`.yaml`格式的配置文件用于定义各个子集的位置以及类别名称列表。例如,在`my_dataset.yaml`中指定路径: ```yaml path: ./datasets/mydataset/ train: images/train/ val: images/valid/ test: images/test/ nc: 3 # 类别数量 names: ['class1', 'class2', 'class3'] ``` #### 脚本实现自动划分 可以编写Python脚本来自动化完成这一过程。下面是一个简单的例子,该脚本会读取源图像文件夹并将它们随机分为三个部分: ```python import os from sklearn.model_selection import train_test_split import shutil def split_data(src_dir, dst_base_dir, ratio=(0.7, 0.2)): all_files = [f for f in os.listdir(src_dir) if not f.startswith('.')] labels = {os.path.splitext(f)[0]: src_dir+f for f in all_files} keys = list(labels.keys()) files_train_val, files_test = train_test_split(keys, test_size=ratio[1], random_state=42) files_train, files_valid = train_test_split(files_train_val, test_size=ratio[1]/(ratio[0]+ratio[1]), random_state=42) sets = [('train', files_train), ('valid', files_valid), ('test', files_test)] for set_name, file_list in sets: dest_path = os.path.join(dst_base_dir, set_name) if not os.path.exists(dest_path): os.makedirs(dest_path) for fname in file_list: try: shutil.copyfile(os.path.join(src_dir, '{}.jpg'.format(fname)), os.path.join(dest_path, '{}.jpg'.format(fname))) label_file = "{}.txt".format(fname) if os.path.isfile(label_file): shutil.copyfile(os.path.join(src_dir, label_file), os.path.join(dest_path, label_file)) except Exception as e: print(e) if __name__ == '__main__': source_directory = './source_images/' destination_base_directory = './splitted_datasets/' split_data(source_directory, destination_base_directory) ``` 此代码片段展示了如何通过编程手段将原始数据集划分为不同的集合并移动到相应的目标位置。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值