YOLO学习——数据集入门 “制作自己的数据集”
训练模型——数据集入门:
- 有没有现成的数据集?
- 如何获取图片?
- 如何获取标签?
- 怎么划分数据集?
- 怎么训练自己的模型?
- 训练好模型后的工作?
一、数据集来源
(1)roboflow

如想要预测车,直接用对应英文car搜索:

Project Type可以选择任务类型,Model Type可以选择模型类型:


如目标检测(Object Detection)和YOLOv11:

点击一个进入数据集主页,可以查看信息(有四种车辆类型):

点击左边工具栏中的Images可以预览数据集图片和标注:

点击左边工具栏中的Dataset可以进入数据集下载页面:

点击右上方的YOLOv11就是下载YOLOv11格式的数据集。需要注册登录后才能下载。

选择Download dataset点击Continue。

选择第一个 Download zip to computer 点击Continue下载。

将下载好的压缩包统一放在源码的datasets文件夹下并解压。

打开Pycharm查看数据集信息。data.yaml是数据集自带的配置文件:

可以复制一份配置文件,把要用的配置文件放在ultralytics-8.3.163\ultralytics\cfg\datasets下,并修配置文件car-lmfdq.yaml:

nc和roboflow部分都可以删除,增加path:
path: D:\deeplearning\ultralytics-8.3.163\datasets\car.v9i.yolov11
train: train/images
val: valid/images
test: test/images
names: ['sedan', 'suv', 'truck', 'van']
修改训练脚本mytrain.py,data替换为car-lmfdq.yaml:
from ultralytics import YOLO
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
if __name__ == '__main__':
model = YOLO(r"yolo11n.pt")
model.train(
data=r"car-lmfdq.yaml",
epochs=30,
imgsz=640,
batch=-1,
workers=2,
cache="ram",
)
这里把batch设置为-1,因为新数据集和原来的图片数量不同,批次要重新设置。
可以看到正常开始训练:

资源占用也比较合适:

(2)kaggle

相比robotflow,kaggle上的数据集内容更杂一些,有的需要收费。
同样,可以搜索car object detection,并选择一个YOLO格式的:

然后点击右上角的Download进行下载,后续操作和之前一样,这里就不再重复。
(3)其他来源
其他开源数据集、可以使用智能体帮助查找需要的数据集,如Deepseek,Chatgpt等等。也可以直接自己建立数据集。
二、数据集图片来源
图片来源
- 网上搜索关键词下载图片,或者在开源数据集里寻找需要图片。
- 如果有实物,可以进行实物拍摄采集图片。具体为先拍摄几段视频,然后从视频中提取图片。
(1)拍摄并保存视频
希望模型预测什么样的目标就拍摄什么样的视频,尽可能兼顾各种角度、光照、背景等情况。后续可以慢慢补充。
新建文件夹make_dataset/cs/videos,将拍摄好的视频统一放在电脑一个文件夹下。(记得重命名视频,不要带中文、括号、空格)

(2)从视频提取图片
在Pycharm中打开make_dataset文件夹

右下角选择解释器为yolo。

在cs文件夹下新建一个文件夹,命名为images:

在cs文件夹下新建一个Python文件,命名为extract:

可以使用AI帮你生成代码,提问词放下面了:
我需要一些Python代码
有一些.mp4视频文件存放在这里:
D:\deeplearning\make_dataset\cs\videos
帮我每隔固定几帧提取一张图片出来
一秒提取几帧作为一个可以调整的参数
图片统一命名为aaa_xxxxx.jpg格式
aaa代表视频的名字,xxxxx表示图片的序号
比如视频001.mp4生成的图片就是001_00001.jpg, 001_00002.jpg...
处理每个视频的上海给我进度条
所以图片统一保存到这个文件夹:
D:\deeplearning\make_dataset\cs\images
多写点注释,我是Python小白。
可以得到:
import os
import cv2
from tqdm import tqdm
def extract_frames_from_videos(video_folder, output_folder, frames_per_second):
"""
从视频文件夹中提取帧图片
Args:
video_folder: 视频文件夹路径
output_folder: 输出图片文件夹路径
frames_per_second: 每秒提取的帧数
"""
# 创建输出文件夹(如果不存在)
if not os.path.exists(output_folder):
os.makedirs(output_folder)
print(f"创建输出文件夹: {output_folder}")
# 获取所有.mp4文件
video_files = [f for f in os.listdir(video_folder) if f.lower().endswith('.mp4')]
if not video_files:
print("在指定文件夹中没有找到.mp4文件")
return
print(f"找到 {len(video_files)} 个视频文件")
# 处理每个视频文件
for video_file in video_files:
video_path = os.path.join(video_folder, video_file)
video_name = os.path.splitext(video_file)[0] # 获取视频名称(不含扩展名)
print(f"\n开始处理视频: {video_file}")
# 打开视频文件
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print(f"无法打开视频文件: {video_file}")
continue
# 获取视频信息
fps = cap.get(cv2.CAP_PROP_FPS) # 视频的原始帧率
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 总帧数
duration = total_frames / fps # 视频时长(秒)
print(f"视频信息: 帧率={fps:.2f}fps, 总帧数={total_frames}, 时长={duration:.2f}秒")
# 计算帧间隔(每隔多少帧提取一张)
frame_interval = int(fps / frames_per_second)
if frame_interval < 1:
frame_interval = 1
print(f"提取设置: 每秒{frames_per_second}帧, 帧间隔={frame_interval}")
# 初始化计数器
frame_count = 0
saved_count = 0
# 创建进度条
pbar = tqdm(total=total_frames, desc=f"处理 {video_name}")
while True:
ret, frame = cap.read()
if not ret:
break
# 检查是否达到提取间隔
if frame_count % frame_interval == 0:
# 生成文件名
image_filename = f"{video_name}_{saved_count + 1:05d}.jpg"
image_path = os.path.join(output_folder, image_filename)
# 保存图片
cv2.imwrite(image_path, frame)
saved_count += 1
frame_count += 1
pbar.update(1)
# 关闭资源
pbar.close()
cap.release()
print(f"完成! 从视频 {video_file} 中提取了 {saved_count} 张图片")
print(f"\n所有视频处理完成! 图片保存在: {output_folder}")
def main():
# 设置路径参数
video_folder = r"D:\deeplearning\make_dataset\cs\videos"
output_folder = r"D:\deeplearning\make_dataset\cs\images"
# 设置提取参数(每秒提取几帧)
frames_per_second = 2 # 可以调整这个参数
print("开始视频帧提取...")
print(f"视频文件夹: {video_folder}")
print(f"输出文件夹: {output_folder}")
print(f"提取频率: {frames_per_second} 帧/秒")
# 执行提取
extract_frames_from_videos(video_folder, output_folder, frames_per_second)
if __name__ == "__main__":
main()
点击运行,没有问题:
D:\anaconda3\envs\yolo\python.exe D:\deeplearning\make_dataset\cs\extract.py
开始视频帧提取...
视频文件夹: D:\deeplearning\make_dataset\cs\videos
输出文件夹: D:\deeplearning\make_dataset\cs\images
提取频率: 2 帧/秒
找到 6 个视频文件
开始处理视频: 001.mp4
视频信息: 帧率=30.00fps, 总帧数=328, 时长=10.93秒
提取设置: 每秒2帧, 帧间隔=15
处理 001: 100%|██████████| 328/328 [00:00<00:00, 666.05it/s]
处理 002: 0%| | 0/474 [00:00<?, ?it/s]完成! 从视频 001.mp4 中提取了 22 张图片
开始处理视频: 002.mp4
视频信息: 帧率=30.00fps, 总帧数=474, 时长=15.80秒
提取设置: 每秒2帧, 帧间隔=15
处理 002: 100%|██████████| 474/474 [00:00<00:00, 660.30it/s]
处理 003: 0%| | 0/183 [00:00<?, ?it/s]完成! 从视频 002.mp4 中提取了 32 张图片
开始处理视频: 003.mp4
视频信息: 帧率=29.00fps, 总帧数=183, 时长=6.31秒
提取设置: 每秒2帧, 帧间隔=14
处理 003: 100%|██████████| 183/183 [00:00<00:00, 651.30it/s]
处理 004: 0%| | 0/337 [00:00<?, ?it/s]完成! 从视频 003.mp4 中提取了 14 张图片
开始处理视频: 004.mp4
视频信息: 帧率=30.00fps, 总帧数=337, 时长=11.23秒
提取设置: 每秒2帧, 帧间隔=15
处理 004: 100%|██████████| 337/337 [00:00<00:00, 625.65it/s]
完成! 从视频 004.mp4 中提取了 23 张图片
开始处理视频: 005.mp4
视频信息: 帧率=30.00fps, 总帧数=324, 时长=10.80秒
提取设置: 每秒2帧, 帧间隔=15
处理 005: 100%|██████████| 324/324 [00:00<00:00, 684.72it/s]
完成! 从视频 005.mp4 中提取了 22 张图片
开始处理视频: 006.mp4
视频信息: 帧率=30.00fps, 总帧数=456, 时长=15.20秒
提取设置: 每秒2帧, 帧间隔=15
处理 006: 100%|██████████| 456/456 [00:00<00:00, 651.54it/s]
完成! 从视频 006.mp4 中提取了 31 张图片
所有视频处理完成! 图片保存在: D:\deeplearning\make_dataset\cs\images
进程已结束,退出代码为 0

查看左边文件栏,可以看到处理好的文件:

打开文件夹,查看图片,发现每张图片差异不大,可以调整一下参数。我调整为1:
frames_per_second = 1 # 可以调整这个参数

三、数据集图片标注
(1)新建一个文件夹,命名为labels:

在labels文件夹下新建一个classes.txt文件。根据需要一行放一个类型,顺序不重要:

我这只要预测一种类型,所以只有一行。
(2)使用labelimg可视化标签
打开Anaconda Prompt,激活labelimg环境:

输入:
labelimg D:\deeplearning\make_dataset\cs\images D:\deeplearning\make_dataset\cs\labels\classes.txt D:\deeplearning\make_dataset\cs\labels
即:labelimg <你的图片文件夹路径> <你的classes.txt路径> <你的标签文件夹路径>

确保左边显示的是YOLO,这样保存的标签才是YOLO:

(3)开始标注图片
按键盘W,鼠标左边开始拉框,然后选择预测类型,点击OK,完成一个标注:

同样的,完成一张图片的所有标注:

按A和D可以快速切换上一张和下一张图片。第一次切换选择保存Yes:

点击上方工具栏view->勾选Auto Save mode:

完成所有图片标注!!!

当然是不可能的,所以下面引入半自动标注。
(4)半自动标注
半自动标注:
部分数据集
【手动标注部分图片】
|| 训练
V
所有图片 -预测-> 【粗模型】-预测-> 【所有图片的伪标注】---------> 得到所有图片的标注
在文件栏新建xz_dataset文件夹,并在下面新建几个文件夹,结构如下:

在cs文件夹下新建一个Python文件,命名为make_xz.py:

从cs/images提取一些图片放在cs/xz_dataset/images/train和cs/xz_dataset/images/val里。训练集多一些,验证集少一些。这个工作同样可以用AI编程完成。提示词如下:
给我一些Python代码
我有几百张图片放在这个文件夹里:
D:\deeplearning\make_dataset\cs\images
帮我随机提取80%的图片出来
其中的70%放到这个文件夹里:
D:\deeplearning\make_dataset\cs\xz_dataset\images\train
剩下的30%放在这个文件夹下:
D:\deeplearning\make_dataset\cs\xz_dataset\images\val
注意要把文件移动出来
根据图片数量调整随机提取的比例。
获得代码并复制到make_xz.py:
import os
import random
import shutil
# 设置路径
source_dir = r"D:\deeplearning\make_dataset\cs\images"
train_dir = r"D:\deeplearning\make_dataset\cs\xz_dataset\images\train"
val_dir = r"D:\deeplearning\make_dataset\cs\xz_dataset\images\val"
# 创建目标文件夹(如果不存在)
os.makedirs(train_dir, exist_ok=True)
os.makedirs(val_dir, exist_ok=True)
# 获取所有图片文件
image_extensions = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp']
image_files = [f for f in os.listdir(source_dir)
if os.path.isfile(os.path.join(source_dir, f)) and
os.path.splitext(f)[1].lower() in image_extensions]
print(f"找到 {len(image_files)} 张图片")
# 随机打乱图片列表
random.shuffle(image_files)
# 计算80%的图片数量
total_extract = int(len(image_files) * 0.8)
extracted_files = image_files[:total_extract]
print(f"提取 {len(extracted_files)} 张图片")
# 计算训练集和验证集的数量
train_count = int(len(extracted_files) * 0.7)
val_count = len(extracted_files) - train_count
train_files = extracted_files[:train_count]
val_files = extracted_files[train_count:]
print(f"训练集: {len(train_files)} 张图片")
print(f"验证集: {len(val_files)} 张图片")
# 移动文件到训练集文件夹
for filename in train_files:
src_path = os.path.join(source_dir, filename)
dst_path = os.path.join(train_dir, filename)
shutil.move(src_path, dst_path)
# 移动文件到验证集文件夹
for filename in val_files:
src_path = os.path.join(source_dir, filename)
dst_path = os.path.join(val_dir, filename)
shutil.move(src_path, dst_path)
print("文件移动完成!")
print(f"训练集文件已移动到: {train_dir}")
print(f"验证集文件已移动到: {val_dir}")
点击运行:

打开文件夹,发现成功完成任务。

然后再分别标注训练集和验证集图片。先复制classes.txt到labels的两个文件夹下,然后使用labelimg进行标注。

在Anaconda Prompt中激活labelimg环境后,输入:
labelimg D:\deeplearning\make_dataset\cs\xz_dataset\images\train D:\deeplearning\make_dataset\cs\xz_dataset\labels\train\classes.txt D:\deeplearning\make_dataset\cs\xz_dataset\labels\train
标注过程和之前一样。完成训练集所有图片标注。

标注好训练集后,进行验证集的图片标注。
labelimg D:\deeplearning\make_dataset\cs\xz_dataset\images\val D:\deeplearning\make_dataset\cs\xz_dataset\labels\val\classes.txt D:\deeplearning\make_dataset\cs\xz_dataset\labels\val
至此,图片标注完成。
(5)添加新建的数据集
在Pycharm中打开ultralytics-8.3.163项目,将前面准备好的xz_dataset数据集文件夹复制到ultralytics-8.3.163的datasets文件夹下:

在ultralytics/cfg/datasets下新建一个对应的配置文件xm_dataset.yaml,文件内容(可以复制其他配置文件,然后修改内容)为:
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: D:\deeplearning\ultralytics-8.3.163\datasets\xz_dataset # dataset root dir
train: images/train
val: images/val
# Classes
names:
0: bucket
(6)修改训练脚本文件
修改mytrain.py文件:
from ultralytics import YOLO
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
if __name__ == '__main__':
model = YOLO(r"yolo11n.pt")
model.train(
data=r"xz_dataset.yaml", # 修改
epochs=100, # 修改
imgsz=640,
batch=-1,
workers=1,
cache="ram",
)
点击运行,可以看到开始训练:

训练完成:

左边文件栏查看训练结果:

点击图片BoxPR_curve.png,all classes项越接近1训练效果越好:

图片上看起来训练结果(0.995)接近1,下面用这个模型对未标注的图片进行标注。
(7)图片预测并标注
复制刚刚训练好的模型路径:

修改mypredict.py文件,将模型路径替换为训练好的模型路径,将source的路径替换为未标注的图片文件夹路径:
from ultralytics import YOLO
model = YOLO(r"D:\deeplearning\ultralytics-8.3.163\runs\detect\train21\weights\best.pt")
model.predict(
source=r"D:\deeplearning\make_dataset\cs\images",
save=True,
show=False,
save_txt=True, # 新增
)
save_txt=True, 是把预测结果保存为.txt文件。
点击运行:

对应文件夹查看预测结果:

大部分图片效果还可以,小部分后面进行调整。将预测得到的标签复制到之前的D:\deeplearning\make_dataset\cs\labels文件夹下,同时把xz_dataset数据集里的图片和标签也分别放在D:\deeplearning\make_dataset\cs\labels和D:\deeplearning\make_dataset\cs\labels下:


注意文件数量一致。
(8)用labelimg调整标注
labelimg D:\deeplearning\make_dataset\cs\images D:\deeplearning\make_dataset\cs\labels\classes.txt D:\deeplearning\make_dataset\cs\labels

快速浏览,并对有瑕疵图片标注进行修改调整:

至此,完成了所有图片的标注。
四、划分数据集
(1)划分数据集
在PyCharm返回make_dataset项目,新建一个Python文件split.py:

同样可以用AI编写:
我现在需要一些Python代码随机划分一些数据集
images文件夹里存放.jpg文件
labels文件夹里存放.txt标签文件(YOLO格式)
比如imges/abc.jpg对应labels/abc.txt
划分结果统一保存到bucket_cs文件夹里
用这样的目录结构
bucket_cs\
images\
train\
val\
test\
labels\
train\
val\
test\
划分比例设置为可以调整的参数
只复制粘贴文件,不要乱动原本的图片和标签
不要用sklearn这个包
划分的时候用进度条提示一些进度
注释写清楚点,我是Python小白
代码内容为:
import os
import random
import shutil
import time
def split_dataset(images_dir, labels_dir, output_dir, train_ratio=0.7, val_ratio=0.2, test_ratio=0.1):
"""
随机划分数据集并复制文件到指定目录
参数:
images_dir: 原始图片文件夹路径
labels_dir: 原始标签文件夹路径
output_dir: 输出文件夹路径
train_ratio: 训练集比例 (默认0.7)
val_ratio: 验证集比例 (默认0.2)
test_ratio: 测试集比例 (默认0.1)
"""
# 检查比例之和是否为1
total_ratio = train_ratio + val_ratio + test_ratio
if abs(total_ratio - 1.0) > 0.001:
print(f"错误:比例之和应为1.0,当前为{total_ratio}")
return
# 创建输出目录结构
dirs_to_create = [
os.path.join(output_dir, 'images', 'train'),
os.path.join(output_dir, 'images', 'val'),
os.path.join(output_dir, 'images', 'test'),
os.path.join(output_dir, 'labels', 'train'),
os.path.join(output_dir, 'labels', 'val'),
os.path.join(output_dir, 'labels', 'test')
]
for dir_path in dirs_to_create:
os.makedirs(dir_path, exist_ok=True)
print(f"创建目录: {dir_path}")
# 获取所有图片文件(不包含子目录)
image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg')]
# 移除文件扩展名,获取基础文件名
base_names = [os.path.splitext(f)[0] for f in image_files]
print(f"找到 {len(base_names)} 个图片文件")
# 随机打乱文件列表
random.shuffle(base_names)
# 计算各集合的数量
total_files = len(base_names)
train_count = int(total_files * train_ratio)
val_count = int(total_files * val_ratio)
test_count = total_files - train_count - val_count
print(f"划分数量 - 训练集: {train_count}, 验证集: {val_count}, 测试集: {test_count}")
# 划分数据集
train_files = base_names[:train_count]
val_files = base_names[train_count:train_count + val_count]
test_files = base_names[train_count + val_count:]
# 复制文件的函数
def copy_files(file_list, split_type):
"""
复制指定文件列表到对应的训练/验证/测试目录
"""
total_files = len(file_list)
print(f"\n开始复制 {split_type} 集文件...")
for i, base_name in enumerate(file_list):
# 源文件路径
src_image = os.path.join(images_dir, base_name + '.jpg')
src_label = os.path.join(labels_dir, base_name + '.txt')
# 目标文件路径
dst_image = os.path.join(output_dir, 'images', split_type, base_name + '.jpg')
dst_label = os.path.join(output_dir, 'labels', split_type, base_name + '.txt')
# 复制图片文件
if os.path.exists(src_image):
shutil.copy2(src_image, dst_image)
else:
print(f"警告: 图片文件不存在 - {src_image}")
# 复制标签文件
if os.path.exists(src_label):
shutil.copy2(src_label, dst_label)
else:
print(f"警告: 标签文件不存在 - {src_label}")
# 显示进度条
progress = (i + 1) / total_files * 100
bar_length = 30
filled_length = int(bar_length * (i + 1) // total_files)
bar = '█' * filled_length + '-' * (bar_length - filled_length)
print(f'\r{split_type}进度: |{bar}| {i+1}/{total_files} ({progress:.1f}%)', end='', flush=True)
# 添加小延迟以便看清进度(可选)
time.sleep(0.01)
print(f"\n{split_type}集复制完成!")
# 复制各集合文件
copy_files(train_files, 'train')
copy_files(val_files, 'val')
copy_files(test_files, 'test')
print(f"\n数据集划分完成!")
print(f"输出目录: {output_dir}")
print(f"训练集: {len(train_files)} 个文件")
print(f"验证集: {len(val_files)} 个文件")
print(f"测试集: {len(test_files)} 个文件")
# 使用示例
if __name__ == "__main__":
# 设置路径和参数
IMAGES_DIR = "images" # 原始图片文件夹
LABELS_DIR = "labels" # 原始标签文件夹
OUTPUT_DIR = "bucket_cs" # 输出文件夹
# 设置划分比例 (训练集:验证集:测试集)
TRAIN_RATIO = 0.7 # 70% 训练集
VAL_RATIO = 0.2 # 20% 验证集
TEST_RATIO = 0.1 # 10% 测试集
# 检查原始目录是否存在
if not os.path.exists(IMAGES_DIR):
print(f"错误: 图片目录 '{IMAGES_DIR}' 不存在!")
elif not os.path.exists(LABELS_DIR):
print(f"错误: 标签目录 '{LABELS_DIR}' 不存在!")
else:
# 执行数据集划分
split_dataset(
images_dir=IMAGES_DIR,
labels_dir=LABELS_DIR,
output_dir=OUTPUT_DIR,
train_ratio=TRAIN_RATIO,
val_ratio=VAL_RATIO,
test_ratio=TEST_RATIO
)
点击运行:

左边文件栏中生成了对应文件夹和文件:

别忘了在labels文件夹下每个子文件夹下增加classes.txt文件:
bucket
(2)完成数据集配置
PyCharm切换为ultralytics-8.3.163项目,将完成的bucket_cs数据集复制到datasets文件夹下,并在ultralytics/cfg/datasets新建对应的配置文件bucket_cs.yaml:
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: D:\deeplearning\ultralytics-8.3.163\datasets\bucket_cs # dataset root dir
train: images/train
val: images/val
test: images/test
# Classes
names:
0: bucket
修改mytrain.py文件:
from ultralytics import YOLO
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
if __name__ == '__main__':
model = YOLO(r"yolo11n.pt")
model.train(
data=r"bucket_cs.yaml",
epochs=5,
imgsz=640,
batch=-1,
workers=1,
cache="ram",
)
点击运行:

完成训练并获得了训练结果。下面可以准备训练了。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)