云计算百科
云计算领域专业知识百科平台

第3章 数据采集与标注—从零开始制作你的YOLO数据集

前言:Hello大家好,我是小哥谈。本章围绕YOLO数据集的制作展开,核心流程是采集标注划分三步。首先明确了数据标注的本质—为图片画边界框并指定类别,标注质量直接决定模型上限。接着介绍了三种采集途径:自己拍要注意多角度、多光照、背景多样;网上找可复用COCO、VOC等公开数据集或按需爬取;视频抽帧则适合监控、流水线等场景。随后对比了COCO、VOC、YOLO三种标注格式,以及LabelImg、Labelme、Roboflow三款工具的适用场景。最后讲解了训练集、验证集、测试集的划分原则与分层抽样技巧,强调测试集只在最终评估时使用一次。走完这一章,你就拥有了一个格式规范、划分合理的YOLO数据集。🌈

     目录

🚀1.什么是数据标注?

🚀2.数据从哪来:三种采集途径

🍀🍀2.1 自己拍:手机/相机拍摄的注意事项

🍀🍀2.2 网上找:公开数据集与图片爬取

🍀🍀2.3 视频抽帧:从现有视频中提取图像

🚀3.常见标注格式:COCO、VOC、YOLO

🚀4.标注工具选型:LabelImg、Labelme还是Roboflow?

🍀🍀4.1 LabelImg:最快上手,目标检测的“标配”

🍀🍀4.2 Labelme:支持多边形,但不只是“画框工具”

🍀🍀4.3 Roboflow:在线一站式,团队协作首选

🚀5.动手标注:用LabelImg完成第一张图

🍀🍀5.1 数据准备

🍀🍀5.2 进行标注

🚀6.数据集划分:训练集、验证集、测试集

🚀1.什么是数据标注?

简单来说,数据标注就是给原始数据“贴标签”。一张图片里有一只猫,你告诉模型“这里有一只猫,它的位置在左上角那个框里”——这个“告诉”的过程,就是标注。

对于YOLO目标检测来说,标注的核心任务是画边界框(Bounding Box)。每一张训练图片,你都需要用矩形框把目标物体框出来,并指定它属于哪个类别。比如一张街景图,你要框出所有的“人”“车”“交通灯”,每个框对应一个类别标签。模型通过学习这些“图片++类别”的对应关系,逐渐学会自己识别新图片中的目标。

为什么标注如此重要?因为YOLO是监督学习模型,它不会自己凭空理解什么是“猫”。你喂给它什么样的标注,它就学成什么样。标注质量直接决定模型上限:框画得歪歪扭扭,模型学到的位置就不准;类别标错,模型就会把猫认成狗;漏标了目标,模型会以为那里什么都没有。业内常说“数据决定上限,模型逼近上限”,而标注正是数据质量的关键一环。

一个完整的YOLO标注结果,通常包含两部分:图片文件和对应的txt标签文件。

txt里每一行代表一个目标,格式为:

text

类别索引 中心x 中心y 宽度 高度

其中坐标都是归一化后的值(0到1之间),而不是像素值。这样设计是为了让模型不受图片尺寸影响—无论原图是640×640还是1920×1080,标注格式都统一。

标注听起来简单,做起来却是个体力活。一张图可能有三五个目标,一个数据集动辄几百上千张,手动画框既耗时又容易出错。所以实际工作中,我们会借助标注工具来提高效率,比如LabelImg、Labelme、Roboflow等。这些工具支持快捷键、批量操作、自动保存,能让你画框的速度快上好几倍。

最后要强调一点:

标注不是越多越好,而是越准越好。一千张粗糙标注的图片,往往不如三百张精细标注的图片有用。宁可在少量数据上把框画准、类别标对,也不要为了凑数量而牺牲质量。理解了这一点,你就迈出了制作高质量YOLO数据集的第一步。


🚀2.数据从哪来:三种采集途径

🍀🍀2.1 自己拍:手机/相机拍摄的注意事项

自己拍数据,是制作YOLO数据集最直接的方式。你需要什么场景、什么目标,就拿着手机或相机去拍什么,针对性强,而且数据完全可控。但“随便拍”和“有目的地拍”之间,差别很大。以下几点,决定了你拍出来的图能不能用、好不好用。

第一,明确目标类别,别拍一堆无关内容。拍之前先想清楚:我要检测什么?如果要做“安全帽检测”,那就只拍戴安全帽和没戴安全帽的工人,画面里尽量别混入大量无关的车辆、建筑。每张图的目标数量控制在3到10个之间比较理想——太少,信息量低;太多,标注起来累,而且目标互相遮挡严重。

第二,多角度、多距离、多光照。这是新手最容易忽略的一点。很多人拍一个物体,正面拍一张就完事了,结果模型只认识正面,侧面一出现就漏检。正确的做法是:同一个目标,从正面、侧面、背面、俯视、仰视都拍几张;距离上,近景、中景、远景都覆盖;光照上,白天、傍晚、阴天、室内灯光都要有。模型见得多,泛化能力才强。

第三,注意分辨率和画质。手机拍就够用,但尽量用原生相机而非美颜模式,避免过度压缩。分辨率建议不低于640×640,太小的图目标模糊,标注和训练都受影响。另外,拍摄时尽量保持画面稳定,模糊、抖动的图片直接删掉,不要舍不得。

第四,背景要多样,别只在一个地方拍。如果所有图片都在同一个房间、同一面墙前拍,模型会“偷懒”——它可能记住的是背景而不是目标。换个场景、换个角度、换个背景,哪怕目标一样,也能逼着模型去学真正的目标特征。

第五,注意隐私和合规。拍街道、拍人、拍车牌时,注意避开敏感信息,涉及人脸和车牌的数据集尽量做模糊处理或避免使用,尤其是要公开分享的数据集。

最后给个实用建议:拍的时候多拍一些,标注的时候再筛。现场拍摄成本低,但事后补拍很麻烦。宁可多拍两百张,回头慢慢挑,也别拍完发现某个角度一张都没有,又得跑一趟。

🍀🍀2.2 网上找:公开数据集与图片爬取

自己拍虽然可控,但遇到“想检测的东西身边没有”时,网上找就是更现实的选择。常见途径有两类:直接用公开数据集,或者自己爬取图片

公开数据集:省时省力的首选

目标检测领域有不少现成的公开数据集,覆盖了常见类别,拿来就能用。比如COCO,包含80个类别、20多万张标注图片,人、车、动物、家具应有尽有;Pascal VOC规模小一些,但经典、格式规范,适合入门练手;还有专门面向行人检测的Cityscapes、面向交通标志的TT100K、面向口罩检测的Mask Detection Dataset等。这些数据集大多提供YOLO格式或可转换的标注文件,下载后稍作处理就能直接训练。

用公开数据集的好处是省去了采集和标注的成本,缺点是类别固定。你想要的目标如果不在它的类别列表里,那就用不上。另外,公开数据集往往偏向特定场景(比如COCO多是生活场景),和你的实际应用场景可能有差距,直接用效果未必好。

图片爬取:按需定制,但标注得自己来

如果公开数据集没有你要的类别,可以自己爬图。最常见的方式是用Python写个爬虫,从百度图片、必应图片或特定网站批量下载。核心思路是:模拟搜索关键词,解析页面里的图片链接,然后批量下载。网上有不少现成的爬虫脚本,改一下关键词和保存路径就能跑。

但爬取有几个坑要注意:第一,图片质量参差不齐,很多是缩略图、带水印、重复的,下载后必须清洗;第二,标注要自己补,爬来的图没有标签,你得一张张画框,工作量不小;第三,版权和合规问题,爬来的图片如果用于商业项目,可能涉及侵权,公开分享也要谨慎。

实用建议:

优先用公开数据集,实在没有合适的再考虑爬取。如果选择爬取,关键词要尽量具体,比如搜“戴安全帽的工人”比搜“工地”精准得多。下载后先做一轮去重和筛选,再进入标注环节。另外,也可以把公开数据集和少量自拍图混合使用—公开数据打底,自拍图补场景,往往比单一来源效果更好。

🍀🍀2.3 视频抽帧:从现有视频中提取图像

除了拍照和爬图,还有一种被低估的采集方式:从视频里抽帧。一段几秒的视频,按每秒几帧切出来,就能得到几十上百张图片,而且这些图片天然带有连续性和多样性—目标在移动、角度在变化、光照在过渡,正好符合前面强调的“多角度、多场景”要求。

抽帧的核心工具是 OpenCV。基本思路很简单:打开视频,按固定间隔读取帧,保存成图片。

代码大致如下:

import cv2

cap = cv2.VideoCapture('video.mp4')
frame_interval = 10 # 每10帧取一张
count = 0
saved = 0

while True:
ret, frame = cap.read()
if not ret:
break
if count % frame_interval == 0:
cv2.imwrite(f'frames/frame_{saved:04d}.jpg', frame)
saved += 1
count += 1

cap.release()

关键参数是抽帧间隔。间隔太小,相邻帧几乎一样,数据冗余;间隔太大,目标动作跳跃,连续性丢失。一般视频按每秒25到30帧算,每10到15帧取一张比较合适,也就是每秒取2到3张。如果视频里目标移动很快,间隔可以再小一点;如果是静止场景,间隔可以放大。

抽帧时有几点要注意。第一,去掉模糊帧,视频压缩和运动会导致部分帧不清晰,可以用拉普拉斯算子简单筛一遍。第二,避免高度相似的帧,如果目标几乎没动,连续抽出来的图差别很小,建议手动或按哈希去重。第三,视频来源要合法,尽量用自己拍摄的视频或允许使用的公开视频素材。

抽帧特别适合行为检测、交通监控、工业流水线这类场景—现实中你很难举着相机一张张拍,但一段监控视频就能提供大量真实数据。抽完帧之后,这些图片和自拍图一样,都要经过筛选、清洗,再进入标注环节。


🚀3.常见标注格式:COCO、VOC、YOLO

你可能会问:为什么要有这么多格式?说白了,每个框架都有自己的「脾气」。我刚开始做项目时,经常在三种格式之间来回转换,踩了不少坑。

格式存储方式坐标格式典型应用
COCO JSON文件 左上角x, y + 宽w, 高h 检测、分割、关键点
VOC XML文件 左上角xmin, ymin + 右下角xmax, ymax 分类、检测
YOLO TXT文件 归一化的中心点x, y + 宽w, 高h YOLO系列

COCO格式

COCO是目前最流行的数据集格式之一。它用JSON文件组织所有信息,结构清晰但稍显复杂。我个人习惯用COCO做大型项目,因为它支持80个类别,而且有丰富的评估工具。

{
"images": [{"id": 1, "file_name": "001.jpg", "width": 640, "height": 480}],
"annotations": [{
"id": 1, "image_id": 1,
"bbox": [100, 200, 200, 150], // x, y, width, height
"category_id": 3
}],
"categories": [{"id": 3, "name": "car"}]
}

VOC格式

VOC格式用XML文件存储,每个图片对应一个XML。我记得早期做PASCAL VOC比赛时,大家都用这个格式。它很直观,但文件数量多,管理起来有点麻烦。

<annotation>
<filename>001.jpg</filename>
<size><width>640</width><height>480</height></size>
<object>
<name>car</name>
<bndbox>
<xmin>100</xmin><ymin>200</ymin>
<xmax>300</xmax><ymax>350</ymax>
</bndbox>
</object>
</annotation>

YOLO格式

YOLO格式最简洁,每个图片对应一个TXT文件。坐标是归一化的(0~1之间),这样不管图片多大,坐标都有效。你想想看,如果图片是1920×1080,坐标归一化后就不用担心分辨率问题了。

# 类别ID 中心x 中心y 宽度w 高度h
3 0.3125 0.5208 0.3125 0.3125

我的建议:做YOLO项目直接用YOLO格式。如果数据源是COCO或VOC,写个脚本转一下就好。


🚀4.标注工具选型:LabelImg、Labelme还是Roboflow?

工具没有绝对的好坏,只有适不适合你的场景。选错了工具,后面可能要多花几倍时间返工。这一节把三个主流选项摆在一起,帮你做出判断。

🍀🍀4.1 LabelImg:最快上手,目标检测的“标配”

如果你只做YOLO目标检测,标注的就是矩形框,LabelImg是最直接的选择。开源免费,pip install labelimg就能装,界面简单到几乎没有学习成本。按W画框、输入类别、按D切下一张,配合自动保存功能,标注速度非常快。它直接支持导出YOLO格式的txt文件,省去了格式转换的麻烦。

LabelImg的定位很清晰:为矩形框目标检测而生。它不支持多边形,没有协作功能,也没有项目管理机制。数据集如果只有几百张图,一个人标注,LabelImg完全够用。但超过一两千张、需要多人分工时,它就开始吃力了。

🍀🍀4.2 Labelme:支持多边形,但不只是“画框工具”

Labelme同样是开源免费的,pip install labelme即可安装。它和LabelImg最大的区别在于:除了矩形框,还支持多边形、圆形、直线、点等多种标注形状。这意味着如果你的目标形状不规则(比如医学图像里的病灶区域、航拍图里的田地边界),Labelme是更合适的选择。

Labelme的标注结果默认保存为JSON格式,需要额外转换成YOLO的txt格式才能使用。它同样没有协作功能,多语言界面是加分项,但整体操作比LabelImg稍微复杂一些。

🍀🍀4.3 Roboflow:在线一站式,团队协作首选

Roboflow是一个在线平台,不用安装,打开浏览器就能标注。它的核心优势不在于“画框”本身,而在于完整的流程管理:上传图片、分配任务给队友、标注、审核、导出YOLO格式,全部在一个界面完成。它还内置了自动增强(旋转、裁剪、调亮度)和智能多边形工具,对新手比较友好。

但Roboflow的免费版有代价:数据集是公开的,且工作空间最多3个成员。如果你的数据涉及隐私或商业机密,免费版就不合适了。付费版起价约79美元/月,对个人学习来说成本偏高。

标注工具怎么选?看你的实际情况

个人学习、小规模目标检测:选LabelImg。装得快、用得快,和YOLO格式无缝对接。 目标形状不规则、需要精细标注:选Labelme。多边形的支持是硬需求时,没有替代品。 团队协作、想省去格式转换和项目管理:选Roboflow。但先确认数据能否接受公开,或是否有预算。

还有一个容易被忽略的点:工具可以混用。比如用LabelImg快速标完矩形框,遇到个别不规则目标再用Labelme补标。但混用会增加格式统一的麻烦,除非有明确需求,否则建议一个项目坚持用同一个工具。


🚀5.动手标注:用LabelImg完成第一张图

Labelimg 是一个可视化的图像标注工具。Faster R-CNN、YOLO、SSD等目标检测网络所需要的数据集,均需要借此工具标定图像中的目标。labelimg 是一款开源的图像标注的工具,主要用于标注两种数据格式,具体如下: 👇

  • voc 数据格式:xml文件
  • yolo数据格式:txt文件

说明:

安装包链接:https://pan.baidu.com/s/1ZNEgiC5wEh6Jh-beXIjezQ?pwd=qfre  提取码:qfre  也可以在官网进行下载,官网下载地址:https://github.com/tzutalin/labelImg

🍀🍀5.1 数据准备

首先我们需要准备打标注的数据集,这里我新建一个名为SafetyHelmetWearingDataset的文件夹(由于我要对安全帽进行标注,所以叫此名,所以具体叫什么名字,需要根据自己情况来,这里没要求)。在该文件夹里面创建一个名为images的文件夹存放我们需要打标签的图片文件,再创建一个名为labels存放标注的标签文件,最后创建一个名为 predefined_classes.txt 的txt文件来存放所要标注的类别名称。🐳🐳🐳

故总结就是:

  • images:存放需要打标签的图片文件
  • labels:存放经过标注后的标签文件
  • predefined_classes.txt: 定义自己要标注的所有类别(这个文件可有可无,但是在我们定义类别比较多的时候,最好有这个创建一个这样的txt文件来存放类别)

🍀🍀5.2 进行标注

打开软件,然后双击labelimg.exe应用程序,则所呈现界面如下所示:

单击软件界面左上角的“打开文件”,然后打开刚才我们在桌面建立的数据集文件SafetyHelmetWearingDataset,再选择images(需要标注的图片所存放的位置)。

注意:打开文件”表示打开一张照片,而“打开目录”表示打开该目录下的所有照片,此处需要注意区别。🍃🍃🍃

再单击软件界面左上角的“改变存放目录”,即选择SafetyHelmetWearingDataset-labels,将我们标注的文件存放在这个文件夹中。

注意:由于笔者是要标注yolo格式的标签,所以此处要确保为yolo。如果想标注其他格式的,可点击选择。🐯🐯🐯

点击左侧“创建区块”,则可进行标注了,需要命名所要标注的标签名(由于笔者要对安全帽进行标注,所以命名为helmet),然后点击OK即可。

注意:可使用快捷键W,这样就不要每次点击“创建区块”了。✌️✌️✌️

打好一张照片以后,快捷键D,就会进入下一张,这时候就会自动保存标签文件(voc格式会保存xml,yolo会保存txt格式)

快捷键: W:调出标注的十字架,开始标注 A:切换到上一张图片 D:切换到下一张图片 Ctrl+S:保存标注好的标签 del:删除标注的矩形框 Ctrl+鼠标滚轮:按住Ctrl,然后滚动鼠标滚轮,可以调整标注图片的显示大小 Ctrl+u:选择要标注图片的文件夹 Ctrl+r:选择标注好的label标签存放的文件夹 ↑→↓←:移动标注的矩形框的位置


🚀6.数据集划分:训练集、验证集、测试集

数据标注完了,别急着全部丢给模型训练。你需要先把数据集切成三块:训练集验证集测试集。这一步看似简单,却直接影响模型评估的可靠性。

三个集合,各司其职

训练集是模型真正“学习”用的数据。模型通过它调整权重,记住目标的特征。验证集不参与训练,而是在训练过程中用来评估模型当前的水平,帮你判断是否过拟合、该不该调参、什么时候停止训练。测试集则是在训练全部结束后,用来做最终评估的—它相当于“期末考试”,模型之前完全没见过这些数据,考出来的分数才真实。

如果只有训练集和测试集,没有验证集,你就只能在训练结束后才知道模型好坏,中间无法干预。如果只有训练集和验证集,没有测试集,那验证集既当“模拟考”又当“期末考”,评估结果会偏乐观。所以三者缺一不可。

常见比例:8:1:1还是7:2:1?

小规模数据集(几千张以内),常用 8:1:1:80%训练、10%验证、10%测试。数据量较大时(几万张以上),验证集和测试集的比例可以进一步压缩,比如 98:1:1,因为绝对数量已经足够评估。

7:2:1也常见,验证集给得多一点,适合训练中需要频繁评估、调参空间大的场景。没有绝对标准,但有个原则:测试集不能太小。如果测试集只有几十张,评估结果的波动会很大,一次运气好可能就让你误判模型性能。

随机划分的坑:类别不均衡

最简单的划分方式是随机抽,但随机有个隐患:某些类别可能集中跑到某一个集合里。比如你检测“猫”和“狗”,随机划分后训练集里猫很多狗很少,验证集里却几乎全是狗,那验证结果就不可信。

解决办法是分层抽样:按类别比例划分,保证每个集合里各类别的分布大致一致。YOLO训练本身对类别不均衡有一定容忍度,但如果某类目标特别少(比如只占5%),分层抽样就很有必要。

划分之后:生成train.txt和val.txt

YOLO训练不直接读文件夹,而是通过两个文本文件告诉它去哪里找图。train.txt 列出所有训练图片的路径,val.txt 列出验证图片的路径,每行一个路径。测试集可以单独生成 test.txt,也可以在训练结束后手动指定。

一个简单的划分脚本大致长这样:

import os, random, shutil

images = os.listdir('images')
random.shuffle(images)
n = len(images)
train = images[:int(n*0.8)]
val = images[int(n*0.8):int(n*0.9)]
test = images[int(n*0.9):]

for name, subset in [('train', train), ('val', val), ('test', test)]:
with open(f'{name}.txt', 'w') as f:
for img in subset:
f.write(f'images/{img}\\n')

注意:图片和标签必须同步划分。如果图片进了训练集,对应的txt标签也必须进训练集,否则训练时找不到标签会报错。实际项目中,通常先把图片和标签配对,再整体划分。

最后提醒一点

划分一旦确定,就不要再随意改动。如果你根据测试集的表现反复调参、重新划分,测试集就失去了“从未见过”的意义,评估结果会越来越乐观,最终上线时性能大打折扣。测试集只在最后用一次,这是铁律。


赞(0)
未经允许不得转载:网硕互联帮助中心 » 第3章 数据采集与标注—从零开始制作你的YOLO数据集
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!