YOLO目标检测数据集精选与格式转换实践指南
1. 在下载数据集之前先决定你的任务形态和场景边界做YOLO项目这么久我见过太多人一上来就搜“数据集下载”然后看到一个打包好的、标注数量几十万的资源就兴奋地拖下来跑训练脚本结果loss不收敛或者mAP惨不忍睹最后才意识到自己连拿这个数据集去解决什么问题都没想清楚。所以我在这期盘点开始之前先花一点篇幅把选数据集的逻辑捋一遍。这个准备工作做得好后面十个数据集铺开的时候你才知道怎么选而不是照单全收、全部吃灰。1.1 先回答任务形态检测、分割还是姿态YOLO现在早已不是单纯的检测器YOLOv8、YOLOv9、YOLO11这些版本都区分了detect、segment、pose三条任务线。你的下游需求决定了你要找什么标注格式的数据集如果只是画框定位目标找普通目标检测数据集标注是x1、y1、x2、y2或者cx、cy、w、h。如果你要精确到目标的轮廓比如做钢材缺陷的缺陷区域抠图、农作物病斑的形态分析那你就需要实例分割标注也就是每个目标带一组多边形坐标。如果要做人体姿态估计比如动作识别、健身计数你需要的关键点标注数据常见的是COCO Keypoints这种每人17个关节点的格式。举一个实际例子你想做一个工地安全帽检测表面上看检测框就够了但如果你后续还想判断工人是否低头、是否摔倒那就要预留姿态估计的数据需求。这类需求在数据集选择阶段就决定了后面再换会非常痛苦因为标注成本是成倍增加的。1.2 再回答场景边界你的推理数据长什么样这个问题是很多新手最容易忽略的。YOLO模型是很“挑食”的它在什么数据上长大就对什么数据敏感。你需要认真想清楚模型部署后的真实输入是什么摄像头安装在无人机上俯拍还是固定在路侧平拍还是手持设备近景拍摄目标尺寸在画面里占多大比例是密集的小目标还是稀疏的大目标光照条件如何有夜间、逆光、雨雾这类恶劣天气吗背景是否复杂目标是否经常被遮挡这些问题的答案直接决定你要不要选无人机视角的数据集要不要寻找小目标占比高的数据集要不要额外收集特定光照条件的数据。我见过一个翻车案例有人用VisDrone这类俯拍数据集训练了一个车辆检测模型结果部署到路口平视的摄像头上检测率直线下降后来被迫重新采集了一大堆平视角度的道路数据才救回来。如果短期内找不到完全匹配的数据集我的建议是先选语义最接近的公开数据集把pipeline跑通然后采集少量真实场景数据补充进去。这个路径在后面第5节我会展开讲但你现在至少要有一个结论你选的第一个数据集只是一个合理的起点而不是终点。2. 十个精选数据集逐个拆解规模、标注特点和适用YOLO版本这份清单我尽量覆盖不同场景从通用目标检测起步再到无人机航拍、遥感小目标、自动驾驶、人脸检测、工业缺陷、安全施工和农业病害。每个数据集我都会把规模、类别、标注格式、典型坑点说明白并按我的实际经验给出适配建议。2.1 通用目标检测基础盘COCO 2017、Pascal VOC 2012COCO 2017全称Common Objects in Context目标检测圈子的“普通话”。训练集有118K张图片验证集5K张覆盖80个常见物体类别。它的价值在于类别范围足够广物体出现的场景足够杂是世界大赛和预训练模型的事实标准。YOLOv8官方权重几乎都在COCO上预训练过所以不管你的场景多垂直拿COCO预训练权重做迁移学习都比从零开始训收敛快得多。COCO的标注是JSON格式既包含检测框bbox也包含实例分割多边形segmentation还有人体关键点keypoints。这意味着同一个数据集你可以分别用来训练detect、segment、pose三种模型非常划算。下载地址在cocodataset.org标注文件不大但train2017图片压缩包大概18GB硬盘不够的要提前规划空间。COCO有一个必须注意的地方官方类别id不是从0开始连续编号的它沿用了WordNet的类别层级所以转成YOLO需要的txt格式时不能直接拿原始category_id当class id必须自己建立一张映射表把用到的80类重新映射成0-79的连续编号。我见过不少人在这里翻车训练时类别数超过了实际框数label文件里出现了一个奇怪的id导致训练直接崩掉。Pascal VOC 2012经典中的经典只有20类train/val加起来约11530张图片。它的标注是老式XML格式里面是xmin、ymin、xmax、ymax绝对值坐标。现在我更多把它作为pipeline验证集来用VOC体积小、类别少、格式简单写代码调试时跑VOC比跑COCO高效很多问题定位也更快。跑通了再上大体积数据集。从VOC转YOLO格式时核心逻辑是把绝对坐标除以图片宽高得到归一化坐标再换算成中心点加宽高的形式这部分在下一节我会给出可直接用的转换脚本。2.2 无人机与遥感视角VisDrone、DOTA v1.0、AI-TOD v2VisDrone 2019-DET是我做无人机目标检测的首选入门数据集。它采集自中国多个城市的无人机视角共8629张图片划分是train 6471张、val 548张、test-dev 1610张覆盖10类行人、人、自行车、小汽车、货车、三轮车、遮阳三轮车、公交车、摩托车等。目标普遍小且密集非常接近真实航拍场景。VisDrone的标注是txt格式每行是x1,y1,x2,y2,类别id等字段这种格式转YOLO很轻松。但有一个坑数据集从视频中抽取帧而来连续帧之间相似度极高如果直接全量随机划分train和val会形成严重的数据泄漏val里的图片和train里的图片很可能是同一段视频的相邻帧训练指标会虚高。我建议按视频片段做划分或者干脆用官方划分。DOTA v1.0是航拍旋转目标检测的标杆数据集2806张航拍图像覆盖15类遥感目标包括飞机、船舶、储罐、桥梁、港口、大型车辆、小型车辆、直升机、球场、泳池等总共约18.8万个实例。它的标注方式是四个角点的八个数坐标也就是旋转框OBB这跟YOLO默认的水平框完全不是一个路子。如果你用YOLOv8做水平检测需要把旋转框取外接矩形再转YOLO格式或者用官方提供的HBB转换工具。如果你想直接做旋转框检测YOLOv8有OBB任务分支但你要把DOTA的poly格式转换成YOLO-OBB格式通常是四个角点类别ID。用mmrotate这类专业旋转检测框架训练DOTA也是一个方向但学习成本明显高。新手上来直接做旋转检测会非常痛苦我建议先把水平检测跑通再说。AI-TOD v2是给“小目标检测极致难度”准备的数据集。800张航空图像28021个目标实例8类飞机、桥梁、储油罐、船舶、车辆、人、风力发电机、直升机。这个数据集最狠的地方在于目标平均尺寸只有12.8像素大量目标在16×16像素以下常规YOLO模型训练后漏检率会高得吓人。用小目标数据集训练YOLO有几个明显感受一是原图直接训练效果差往往需要切片成patch再训二是推理时保持训练时的输入尺寸很重要缩图会导致小目标直接消失三是数据增强里Mosaic这类会进一步把目标缩小要谨慎使用。如果你未来要处理无人机巡检、卫星遥感这类远距离检测需求AI-TOD v2是绝佳的“压力测试场”。2.3 自动驾驶与智能交通BDD100KBDD100K是伯克利发布的自动驾驶视频数据集包含10万张驾驶场景图像检测任务标注了车、行人、骑行者、交通标志、交通灯、公交车、卡车、火车、摩托车等10类交通目标。图像分辨率1280×720覆盖白天、夜晚、黄昏、雨天、雪天等极其丰富的天气和光照条件。这个数据集的一大价值就是“真实”。相比一些街景数据集中干净整齐的车流BDD100K里会出现常见的遮挡、曝光过度、夜间灯光干扰这些恰恰是实际部署时最头疼的问题。如果你做的是行车记录仪事件检测、智能交通监控或者想在模型里提前注入对恶劣环境的适应能力BDD100K很值得考虑。下载时有一个容易踩的坑BDD100K官网的分发方式比较复杂分为100K图像包、标注包等好几个子文件。如果你只拿来做目标检测只需要下载对应检测任务的标注JSON和图像子集不需要把分割、追踪、可行驶区域等所有标注全部拉下来不然会白白占几十GB空间。它的标注是JSON格式坐标是绝对像素值转换逻辑和COCO类似但字段名不同写脚本时注意要逐项核对。2.4 人体与人脸专项WIDER FACEWIDER FACE是人脸检测领域最有名的数据集32203张图片约39.7万个标注人脸来自真实生活场景脸的尺度变化极大从小到十几像素的远景人脸到占满画面的大脸都有。官方按检测难度把测试集分为Easy、Medium、Hard三档Hard档包含大量密集小人脸和极端遮挡是检验人脸检测器能力的试金石。用的是水平边界框标注格式是x1,y1,x2,y2没有类别区分因为全部都是人脸。如果你要做安全帽检测、口罩检测这类包含人脸属性的任务WIDER FACE不能直接给你完整的“佩戴状态”标注但可以用来做前置的人脸定位模块或者做难例补充。用YOLO训练WIDER FACE时Hard样本里的小人脸会让模型学到大量低置信度框。推理阶段如果你想提高小脸召回建议把推理时的conf阈值调低再配合NMS的iou阈值调整实际跑下来效果差异非常明显。另外如果只是判断“画面中有没有人脸”把大图切片成多个patch分别检测比单张图直接检测召回高不少。2.5 工业、安全施工与农业植保NEU-DET、SHWD、PlantDocNEU-DET是东北大学发布的钢材表面缺陷数据集1800张灰度图6类常见缺陷裂纹、夹杂、斑块、麻点、氧化铁皮、划痕每类300张。工业质检场景图像背景相对干净但缺陷类别之间的外观差异很小比如裂纹和划痕很容易混淆。1800张图对深度学习来说是很小的量直接训练容易过拟合。我的实际做法是先用ImageNet或者COCO预训练权重在NEU-DET上做迁移学习同时配合在线数据增强如随机旋转、裁剪、对比度变化。如果还想进一步提升小缺陷的检出把原始大图切成若干patch训练和推理通常mAP能涨好几个点。SHWD全称Safety Helmet Wearing Dataset是开源社区整理的安全帽佩戴检测数据集约7581张图来自真实施工场景标注了person和helmet两个类别。它本身是围绕着“人是否戴了安全帽”这个任务设计的所以人框和帽子框经常高度重叠。实际使用时你需要写后处理逻辑判断帽子框中心是否落在人框头部区域光靠两个类别的检测框直接输出是没法完成“佩戴状态判定”的这一点新手特别容易忽略。PlantDoc是植物病害检测数据集约2600张图13类常见植物叶部病害图像来自真实农田环境背景杂乱、光照不统一、病害尺度有大有小对农业场景来说非常贴近实战。它的原始标注是由分类图像改造而来框的精度相对粗糙有些框把整片叶子框住目标只占框内一小部分。用它训练模型之前我建议你先抽一批样本人工检查标注质量必要时用标注工具修正一遍否则模型会学到大量背景噪声。PlantDoc的规模和类别都不大适合做农业病害检测的入门验证也可以用来做预训练。如果你需要烟草病虫害、水稻稻瘟病这类更垂直的农业数据公开资源非常稀缺通常的选择是先拿PlantDoc这类数据集把检测流程跑通然后结合自采集数据和半自动标注来建专属数据集。2.6 一张表总结十个数据集的选型定位我把这十个数据集的核心信息整理成一张表方便你按项目需求快速定位。数据集任务方向规模类别数标注格式典型坑点COCO 2017通用检测/分割/姿态12.3万图80JSON类别id需要重建映射Pascal VOC 2012通用检测/分割1.15万图20XML数据量偏小VisDrone 2019无人机航拍检测8629图10txt视频抽取帧易数据泄漏DOTA v1.0遥感旋转框检测2806图15poly/OBB旋转标注需特殊处理AI-TOD v2遥感小目标检测800图8poly目标极小原图直训效果差BDD100K自动驾驶检测10万图10JSON下载分包繁琐WIDER FACE人脸检测3.2万图1txt小脸密集需调低置信度NEU-DET工业缺陷检测1800图6txt/XML样本量小易过拟合SHWD安全帽佩戴检测7581图2XML人框与帽框重叠需后处理PlantDoc农业病害检测约2600图13XML/分类改造标注框粗糙需清洗3. 把标注转成YOLO要的txt三种格式转换的思路与可直接用的脚本逻辑YOLO训练的标签格式非常固定一个txt文件对应一张图片每一行是“类别id cx cy w h”其中cx、cy是目标中心点的归一化坐标w、h是目标宽高的归一化值。公开数据集几乎没有原生就是这种格式的所以转换脚本是绕不开的基础功。我下面按COCO、VOC、旋转框三种情况给出思路和代码逻辑你可以直接拿来改造成自己的工具。3.1 COCO JSON转YOLO txtCOCO标注的核心是三个数组images、annotations、categories。转换的核心工作是两件事一是建立原始category_id到0-79连续编号的映射二是把bbox字段从“左上角x、左上角y、宽、高”换算成“中心点x、中心点y、宽、高”并分别除以图片宽高完成归一化。import json import os def coco_to_yolo(json_path, out_dir): with open(json_path, r, encodingutf-8) as f: data json.load(f) # 建立类别id重新映射表 cat_id_map {} for new_id, cat in enumerate(data[categories]): cat_id_map[cat[id]] new_id os.makedirs(out_dir, exist_okTrue) for img in data[images]: img_id img[id] img_w img[width] img_h img[height] base_name os.path.splitext(img[file_name])[0] label_path os.path.join(out_dir, base_name .txt) lines [] for ann in data[annotations]: if ann[image_id] ! img_id: continue if ann.get(iscrowd, 0) 1: continue x, y, bw, bh ann[bbox] cx (x bw / 2.0) / img_w cy (y bh / 2.0) / img_h nw bw / img_w nh bh / img_h cls_id cat_id_map[ann[category_id]] lines.append(f{cls_id} {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}) if lines: with open(label_path, w, encodingutf-8) as f: f.write(\n.join(lines))代码虽短但有三个细节我要强调。第一iscrowd为1的标注是群体目标边界不清晰YOLO格式也无法表达一定要跳过。第二bbox坐标偶尔会出现超出图像边界的情况转换后值可能大于1或小于0需要做截断或过滤否则训练时会产生无效loss。第三如果图片本身没有目标不生成txt文件即可不需要生成一个空文件。3.2 VOC XML转YOLO txtVOC格式用XML组织信息每个文件对应一张图。转换逻辑和COCO类似但坐标是左上角右下角的绝对值计算中心点时要注意除以2的操作。import xml.etree.ElementTree as ET from pathlib import Path def voc_to_yolo(xml_file, class_names): tree ET.parse(xml_file) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_names: continue cls_id class_names.index(name) bbox obj.find(bndbox) x1 float(bbox.find(xmin).text) y1 float(bbox.find(ymin).text) x2 float(bbox.find(xmax).text) y2 float(bbox.find(ymax).text) # 防止越界 x1 max(0, min(x1, img_w)) x2 max(0, min(x2, img_w)) y1 max(0, min(y1, img_h)) y2 max(0, min(y2, img_h)) cx (x1 x2) / 2.0 / img_w cy (y1 y2) / 2.0 / img_h bw (x2 - x1) / img_w bh (y2 - y1) / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) return linesclass_names列表的顺序非常重要它就是YOLO模型中的类别编号依据。比如你把class_names写成[person, helmet]那person就是类别0helmet就是类别1后面训练配置的names必须严格一致差一个顺序整个模型就废了。3.3 旋转框与多边形先确认你的任务到底需不需要DOTA、AI-TOD这类遥感数据集默认是四个角点的多边形坐标有时候甚至不是严格的矩形框。转YOLO之前先问自己一个问题你的任务真的需要旋转框吗如果下游业务不需要区分目标朝向比如只需要知道“图中有飞机在某个位置”那就直接把四个角点的外接矩形算出来再转YOLO格式。外接矩形的计算逻辑很简单取所有角点的最小x、最小y作为左上角最大x、最大y作为右下角然后套用上面的归一化流程。如果确实需要旋转框YOLOv8的OBB分支要求标签格式是“class_id cx cy w h angle”angle是旋转角。从DOTA的任意四边形转换成这个格式通常要借助OpenCV的minAreaRect先算出最小外接矩形再解析出中心点、宽高和角度。这一步比水平框复杂很多它需要处理的角度周期性和边界情况会让新手非常头疼。我的建议是除非你的项目确实要判断目标是否倾斜朝向否则先用水平框形态把整个检测系统跑起来。3.4 目录结构与dataset.yaml不管数据集来自哪里训练前我习惯把图片和标签统一整理成YOLO标准目录结构同时在项目里自带一份dataset.yaml。datasets/ myproject/ images/ train/ val/ labels/ train/ val/dataset.yaml直接照下面这个模板改就行path: ./datasets/myproject train: images/train val: images/val nc: 2 names: 0: person 1: helmet这里再提醒一个很容易犯的错误YOLO的标签文件路径是自动把images替换成labels所以images/train要对应labels/train图片文件名和标签文件名必须完全同名后缀一个.jpg一个.txt。如果图片和标签不匹配训练日志一般不会报错但你会发现跑完的模型怎么调都不涨。4. 我踩过的下载和清洗数据集的几个坑数据集的坑跟藏在地里的雷一样你不知道它在哪也不知道它什么时候爆但每次爆都是踩过的才懂。我把这几年被炸过的几个典型问题整理出来按严重程度排一下。4.1 下载到的“数据集”根本不是普通图片集很多竞赛数据集为了比赛公平原始文件是视频或者包含各种额外字段的完整包直接拿过来当图片训练压根跑不通。比如VisDrone官网里就有检测、单目标追踪、多目标追踪等好几个子任务包下错包以后解压出来会发现标注格式完全不同。应对办法是提前读README确认你要的是DET还是MOT。像BDD100K这种数据集官网会提供全标注包和独立子任务标注包只做检测就不要把语义分割、实例分割、可行驶区域等标注全部下载每一类标注文件都可能好几个GB。4.2 类别编号错位导致训练崩溃或者持续不涨YOLO预训练权重的输出层是根据类别数固定的COCO是80类你的自定义数据集如果是2类加载预训练权重时最后一层会初始化。这个机制本身没问题但很多人把COCO数据集的标注转成YOLO后直接用了原始的category_id比如bus的原始id是5但转换时没有重映射label文件里就出现了类别id 5而nc只改成了2训练过程不会立刻报错实际上那些框的类别全部越界了loss曲线异常精度一直上不去。这类问题排查起来非常隐蔽我现在的习惯是转换完以后写一个快速校验脚本打印每个label文件里的类别id最大值确认它小于配置文件里的nc。4.3 数据划分错误导致指标虚高视频抽帧型数据集的通病就是相邻帧太像了。很多人把图片随机按8:2划分成train和val但同一段视频的前一帧在train、后一帧在valval上看到的图像内容几乎完全重复mAP自然高得离谱。等你部署到全新的真实视频上精度断崖式下跌。正确做法是如果数据集里有视频ID、场景ID或者序列信息按这个维度划分如果没有宁可把划分比例变成9:1并且保证同一批次拍摄的图片尽量进同一个集合。小窍门是val集合选完以后手工抽查几十张图确认它们和train集合里的图片不是同一场景的连续帧。4.4 图片损坏和标签缺失要提前清洗从网上下载的数据集经常存在少量损坏图片比如jpg虽然能打开但解码出来是灰屏或者png文件实际是截断的。这种图片进入训练流程后轻则影响这一批样本的梯度重则导致训练中断。我写过一个简单的清洗脚本流程是遍历所有图片用OpenCV读一遍能读到非空数组且尺寸正常就保留然后检查每个图片是否匹配到同名label文件没有label的图片直接移到unlabeled文件夹再检查label文件里每行的class id是否越界、坐标是否在0-1之间。整个过程跑完一般能筛掉1%到5%的问题样本别小看这些样本它们往往是精度的隐形杀手。4.5 版权与使用边界要提前确认有些数据集只允许非商业学术研究比如很多竞赛数据集在许可协议里有明确限制。如果你做的是商业项目使用前一定要查看数据集license。COCO、Pascal VOC等公开许可较宽泛但DOTA、AI-TOD这类遥感数据集也各有明确条款。更关键的是如果你用来自采集的数据要确保图片本身不包含敏感个人信息特别是人脸、车牌这类数据该打码就提前打码。踩过这些坑之后我养成了一个习惯每拿到一个新数据集先花半小时做一次可视化和统计把每类图片数量、每类目标数量、图片尺寸分布、目标的宽高比分布全部打印出来。不要小看这一步它能帮你提前避开后面训练期很多莫名其妙的问题。5. 公开数据集不够用时如何半自动自举一个专属数据集很多场景注定了公开数据集永远不够用。你很难在公开资源里找到“自家车间传送带上的螺丝缺陷”也很难找到“本地小区里特定角度的车辆外观”更别说那些涉及商业机密的质检数据。这时候最务实的路径就是半自动自举。5.1 先用已有YOLO模型粗标第一步是跑一个效果还凑合的预训练模型或者你自己训练过的初始模型在目标数据上做推理生成候选框。YOLO推理时会把置信度阈值调低一点比如0.15让模型多出一些框宁可多给候选不要漏掉目标。生成的结果直接导出成YOLO格式的label文件这就是一个粗标版本。粗标质量跟你选的模型相关度很大如果预训练模型见过类似场景粗标准确率就能达到七八成如果完全没见过粗标只是帮你省掉画框前期的体力活。5.2 人工修正与难例挖掘粗标产物绝对不能直接训练必须人工过一遍。我用LabelImg或者LabelStudio打开图片和粗标文件逐张修正框的位置和类别这个过程叫“清洗式标注”。跟从零开始画框相比人工要做的只是拖动修正效率能提升三到五倍。清洗标注的过程中你会顺便发现模型的难例分布哪些场景总漏检、哪些目标形态总误检。把这些难例单独收集起来下一轮训练时适当增加它们的采样权重是提升模型短板最快的方式。纯靠堆数据量解决不了的问题往往靠难例挖掘解决。5.3 小规模迭代训练形成闭环自举数据集的正确打开方式是“小步快跑”而不是一次性囤积几千张图再开始训练。我的建议流程是先用几百张精标数据训练一版哪怕mAP还很差也没关系。把模型放到真实的现场视频上连续跑自动收集置信度低但可能是目标的bbox以及置信度很高的误检。把这两类样本抽样出来人工确认修正后加入训练集。用增量方式继续训练每次新增数据量控制在原有规模的20%以内避免灾难性遗忘。以我的经验经过三四轮这样的循环一个垂直场景的专属模型就能达到可用的精度。而且这个过程里积累的数据和标注规范才是你真正的项目资产公开数据集做得再好也只能替代一部分工作量。数据这个环节多花时间不算浪费。我自己每次着手一个新项目前两周基本都在跟数据打交道模型训练反而是后面的事。前期把数据集选对、转对、洗对后面所有环节都会顺畅很多。这也是我把“选型逻辑”和“常见坑点”放在十个数据集之前先讲完的原因。希望这份清单能帮你少走几步弯路。