简介:目标检测是计算机视觉的核心任务,其落地效果高度依赖数据质量与场景匹配度。在安防监控、智慧社区等工程场景中,通用公开数据集往往因类别粒度粗、视角差异大而难以直接迁移。本文从数据工程视角出发,系统梳理了构建专用目标检测数据集的关键环节,包括数据采集、类别定义、YOLO格式标注规范及数据清洗策略,并基于1600余张自建电动车数据集,给出YOLOv8从训练调参、数据增强到业务评估的完整实践路径。该方案覆盖电梯梯控、园区违停等典型监控场景,有效解决电动车与小目标、夜间反光、遮挡等难题,为同类项目提供了可复用的数据资产与训练方法论。 做小区电动车禁入电梯那阵子,我踩过最大的坑不是算法选型,而是找不到能直接用的数据集。公开的目标检测数据集一大堆,但电动车通常被塞进“bicycle”或者“motorcycle”这种大类别里,类别粒度不够,场景也对不上。我要处理的是监控摄像头俯视角、晚上带反光、楼道里半遮挡的电动车,拿COCO里那些街拍自行车图去训练,模型到现场基本是懵的。后来我干脆自己整理了一份1600+张的电动车目标检测数据集,把电动自行车、电动三轮车、摩托车从“车”这个概念里单独拆出来,按YOLO格式标注,配YOLOv8训练,实测跑通了小区梯控、园区违停检测这些场景。这篇文章会把整个数据集的定位、标注规范、训练调参、问题排查完整写一遍,给正在做电动车检测、或者准备自建目标检测数据集的朋友一个可复用的参考。

1. 为什么需要一份专门的电动车目标检测数据集

1.1 电动车检测能解决哪些实际问题

先说场景,电动车目标检测不是实验室里的Demo,它扎在很具体的民生项目里。最常见的是小区电梯轿厢识别,摄像头装在电梯角落,一旦模型检测到电动车,联动梯控系统阻止电梯关门;然后是园区和写字楼地下车库的乱停乱放检测,电动车停进消防通道或者占用了普通车位,系统自动截图派单;还有楼道口电动车违停告警、非机动车道流量统计、充电桩区域安全监控。这些场景有个共同特点:摄像头位置固定,视角多为俯看或者斜俯看,画面里经常出现行人、婴儿车、轮椅、手推车这些“看起来有点像”的干扰目标。如果模型分不清电动自行车和普通自行车,分不清电动车和摩托车,整个业务逻辑就会崩掉。所以项目的第一步不是选模型,而是先把“电动车”这个类别定义清楚,把对应的高质量数据准备好。

实际做下来,我更加确定一件事:电动车检测本质上是个“长尾+场景强相关”的任务。你说它难,它并不需要识别几百类物体;你说它简单,同一个目标在不同角度、不同光照、不同遮挡程度下的特征差异非常大。没有一份贴合真实场景的数据集,再强的模型也发挥不出来。

1.2 通用公开数据集为什么不够用

我最早想省事,直接拿COCO数据集的bicycle和motorcycle类来训练。试过之后发现几个特别难受的地方:

  • 类别粒度太粗。COCO里只有bicycle和motorcycle,没有电动自行车和电动三轮车的细分类别,更别说区分踏板型电动自行车和跨骑型电动自行车;
  • 场景太单一。COCO以户外街景为主,很少见到电梯内、楼道口、地下车库这类室内或半室内监控画面;
  • 拍摄角度不匹配。公开数据集大多是平视略俯视,监控摄像头是正俯视或者大角度斜俯视,模型学到的特征会“水土不服”;
  • 目标尺度差异大。公开数据集里的自行车通常占画面比例较大,而真实监控中电动车经常是画面里的小目标,直接迁移过来后小目标检测能力很差。

我还试过一些车辆检测数据集,比如UA-DETRAC,但它以四轮汽车为主;也翻过遥感目标检测数据集DOTA、Aeroscapes这些,成像条件和监控场景差太多,参考价值有限。唯一有点用的是那些做园区安防的开源行人检测数据,但里面没有电动车标注,还是要自己补。

后来我决定不再纠结公开数据集,直接从真实监控视频里抽帧,做清洗和标注,攒一套属于自己的数据。这个过程听起来简单,实际操作下来有大量细节需要打磨。

数据集 电动车覆盖 视角 场景 对监控电动车检测的适合度
COCO 只有bicycle/motorcycle 平视为主 户外街景 一般,需大量再标注
UA-DETRAC 无,以四轮车为主 俯视 道路 低
DOTA/Aeroscapes 无 遥感顶视 航拍 低
自建1600+电动车数据集 电动自行车/电动三轮车/摩托车/自行车 正俯视/斜俯视 电梯、楼道、园区、地库 高

1.3 1600+张到底够不够

很多人一听到“1600张”就开始打退堂鼓,觉得目标检测怎么也得几万张起步。我解释一下这个数量级的逻辑。决定模型效果的不是单纯的图片数,而是实例数和多样性。这份数据集虽然只有1600多张图,但大量是多目标图片,一张图里同时出现三四辆电动车很常见,总的标注框数在4500以上。对于少类别的目标检测来说,这个实例量完全可以启动训练。

再加上两个关键因素:第一,我们使用在COCO上预训练过的权重做迁移学习,模型底层的边缘、纹理、形状特征已经学好了,只需要在特定场景上做微调;第二,配合数据增强手段,相当于在训练时把数据规模放大了好几倍。我实际用YOLOv8s在这份数据集上训练,验证集mAP50能做到0.93左右,mAP50-95在0.76上下,足够支撑监控类业务。如果你追求更高精度,后面还可以通过难例挖掘扩充样本,性能还有明显提升空间。

2. 数据集构建思路与标注规范

2.1 数据来源与多维采集原则

数据集图片主要来源有三个:真实监控视频抽帧、合规渠道获取的公开监控视频片段、自己补拍的场景样本。不推荐直接去搜索引擎乱抓图,版权和许可问题先不说,网络图片的拍摄视角和成像质量参差不齐,反而容易污染数据集。

采集时要遵循一条核心原则:让每个环境变量都尽量有变化。我整理了一份采集覆盖矩阵,基本可以照着打钩:

  • 场景维度:电梯内、楼道口、地下车库、小区路面、园区门口、非机动车道、商场外广场;
  • 时间维度:白天、傍晚、夜间有灯光、夜间无灯光;
  • 天气维度:晴天、阴天、雨天,雨天地面反光对模型影响很大;
  • 机位维度:正俯视、斜俯视、低机位平视,每种至少要占一定比例;
  • 密度维度:单车、多车、人车混杂、电动车和自行车混停;
  • 姿态维度:正向、侧向、背面、斜停、正在骑行、推行。

这里要特别强调姿态维度。监控场景里电动车很多时候是停着的,但有时候也会出现在画面中移动,骑行状态下人的腿部和车身形成交叉遮挡,这个特征和静态停车差别很大。如果数据集里全是静态样本,模型对骑行状态的召回率会明显偏低。我当时就是从电梯监控视频里把进电梯、出电梯、停在轿厢中间这三个阶段的帧都抽了,模型才真正学会在各种状态下稳定识别。

2.2 标注类别设计决定模型上限

标注类别这块我踩过一次大坑。第一版只标了一个“电动车”类别,结果训练出来的模型把摩托车、电动三轮车、甚至部分自行车全算成电动车。后来我把类别拆成四个,模型的表现才稳定下来:

  • electric_bicycle:电动自行车,最常见的那种两轮踏板或跨骑样式,这是业务中的核心检测目标;
  • electric_tricycle:电动三轮车,常见于快递配送、老年人代步,外形和两轮车差异明显;
  • motorcycle:摩托车,虽然业务上不需要禁入电梯,但外形和电动车接近,必须单独分出来降低误检;
  • bicycle:普通自行车,作为负样本类,让模型学会区分“有电动感”和“没有电动感”。

你可能会问,为什么要把不需要检测的摩托车和自行车也标出来?这叫背景负类。模型在训练时如果只见过“电动车”这一个正类,所有外观接近的物体都会被往里归并;但把干扰类也标注出来,模型就多了一个选择,判断为干扰类比判断成电动车更好。实际部署时我只会取electric_bicycle和electric_tricycle的检出结果,其余的只参与训练、不参与业务触发。

2.3 标注工具与YOLO格式换算

标注工具我用过LabelImg和X-AnyLabeling。LabelImg老牌稳定,适合小批量精标;X-AnyLabeling交互体验更好,可以结合SAM模型做预标注,再人工修正,批量标注效率高不少。工具选择不是重点,重点是输出格式和标注规范。

为了后续训练方便,我把所有标注统一转成YOLO的txt格式。YOLO格式的核心是归一化后的中心点坐标和宽高:

class_id center_x center_y width height

举个例子,一张1280x720的图片中有一辆电动车,边界框左上角坐标是(200, 300),右下角坐标是(600, 700),那么归一化转换计算如下:

  • center_x = (200 + 600) / 2 / 1280 = 0.3125
  • center_y = (300 + 700) / 2 / 720 = 0.6944
  • width = (600 - 200) / 1280 = 0.3125
  • height = (700 - 300) / 720 = 0.5556

最终txt文件里对应的一行就是:

0 0.3125 0.6944 0.3125 0.5556

标注规范上有几条硬性要求,能帮你少走很多弯路:

  • 框必须贴合车身外轮廓,把后备箱、脚踏板都包进去,但不能把明显背景框进来;
  • 目标被遮挡超过40%时不标注,或者单独归档为遮挡样本,不进训练集;
  • 被图像边缘截断的目标,只要超过一半车身可见就继续标注;
  • 多目标密集场景必须把所有目标标完,不允许漏标;
  • 同一张图里出现的所有类别都要标,不能只标电动车。

2.4 数据清洗与质量审核

标注完不等于能直接训练,数据清洗这关必须过。原始采集大概2200张图,最后留下1600多张,中间去掉的都是模糊帧、严重遮挡帧、重复帧和误标注样本。

去重这一步是最容易被忽略但很重要的。监控视频抽帧很容易出现大量高度相似的连续帧,如果不去重,模型会对这些重复画面过拟合,泛化能力变得很差。我用感知哈希算法对图片做相似度比对,两张图相似度超过95%就只保留一张。清洗后剩下1600+张,图片之间的差异性明显提升。

标注质量审核我也做了两轮。第一轮是标注员之间交叉互查,重点看漏标和框偏移;第二轮我自己抽了20%的图逐张核对,发现框贴合度差、类别标错的,一律退回修改。这里有个小技巧:把训练集里标注框的宽高分布统计出来画个图,如果发现大量框全是正方形或者宽高比异常集中,大概率是标注时偷懒把框拉成了固定形状,这种数据对模型非常有害。

3. 基于该数据集的YOLOv8训练实操

3.1 数据集目录组织与配置文件

数据准备好之后,先按YOLO规范把目录组织起来。我习惯把数据集独立放在一个目录里,不跟训练代码混在一起,目录结构如下:

dataset/
├── images/
│   ├── train/    # 约1120张
│   ├── val/      # 约320张
│   └── test/     # 约160张
├── labels/
│   ├── train/
│   ├── val/
│   └── test/
└── dataset.yaml

train/val/test按7:2:1划分。这里有一个很容易被忽略的问题:来自同一段监控视频的连续帧要尽量分到同一个集合,不能一半在训练集一半在验证集,否则验证集里会出现和训练集几乎相同的画面,评估指标会虚高,部署到新场景时立刻露馅。

dataset.yaml配置文件内容如下:

path: /path/to/dataset
train: images/train
val: images/val
test: images/test

names:
  0: electric_bicycle
  1: electric_tricycle
  2: motorcycle
  3: bicycle

names的索引必须和标注txt里的class_id一一对应,顺序错了全军覆没。配置文件写好后,先写个小脚本检查所有txt文件里的class_id是否都在0到3范围内,再顺手统计一下每个类别的实例总数,对类别分布做到心中有数。

3.2 训练参数选择与命令

我用的是YOLOv8n和YOLOv8s两个模型做对比。训练命令如下:

yolo detect train \
  data=dataset/dataset.yaml \
  model=yolov8s.pt \
  epochs=150 \
  imgsz=640 \
  batch=16 \
  lr0=0.01 \
  augment=True \
  project=./runs \
  name=ebike_yolov8s

几个关键参数我解释一下为什么这么定:

  • imgsz:监控原始画面通常是1280x720或1920x1080,但直接用大分辨率训练,显存压力大且训练速度慢。我实测640x640是性价比最高的选择,能覆盖监控场景里大部分电动车目标。如果后续发现远处小目标漏检严重,再考虑提升到960或者用tiling方式训练;
  • batch:根据显存调整,16G显存跑YOLOv8s用batch=16,8G显存建议降到8。batch太小会导致BN层统计不稳定,训练震荡;
  • epochs:150轮之后验证集指标基本趋于稳定,继续增加轮次收益不大,还容易过拟合;
  • pretrained权重:yolov8s.pt是在COCO上预训练的,虽然类别不完全匹配,但底层特征可迁移,一定要用,从零训练在1600张图上效果会差很多。

3.3 数据增强的取舍

YOLOv8默认开启mosaic增强,把四张图拼成一张训练,对小目标检测和提升模型鲁棒性有明显帮助。但我在实验中发现,mosaic对电动车检测有个负面影响:电动车外形细长,拼接时容易被从中间截断,导致标注框跨到两张图的分界线上,模型学到的是残破目标特征。

所以我把mosaic概率降到0.5,同时手动调低了随机旋转、平移和缩放的幅度,开启HSV颜色扰动。具体参数参考如下:

degrees: 10
translate: 0.1
scale: 0.5
fliplr: 0.5
hsv_h: 0.015
hsv_s: 0.7
hsv_v: 0.4

对于小目标场景,我还额外加入了copy-paste增强:把一辆电动车从一张图中裁剪出来,随机贴到另一张缺少目标的背景图上,同时生成对应的标注框。数据集有限的情况下,这个操作能有效增加小尺寸目标的实例数量,对提升recall很有帮助。

3.4 训练曲线怎么看

训练不是把命令丢进去干等,要在训练过程中盯着几条关键曲线。我主要看四条:

  • train/loss:训练集损失,整体应该持续下降;
  • val/loss:验证集损失,如果出现先降后升的拐点,说明开始过拟合了,需要加强数据增强或者提前停止;
  • precision和recall:precision高说明漏检少、误检多,recall高说明误检少、漏检多,具体调向取决于业务需求。电梯梯控场景我更看重recall,漏一次就可能导致电动车进电梯,误报一次顶多是问题工单;消防通道占用检测则更看重precision,频繁误报会让物业把系统关掉;
  • mAP50和mAP50-95:mAP50是IoU=0.5下的平均精度,是监控触发类业务的主要参考;mAP50-95条件更严格,能反映定位精度和小目标检测能力。

我最终训练出的YOLOv8s模型指标大致是:precision 0.91,recall 0.87,mAP50 0.93,mAP50-95 0.76。这个水平在业务中已经能跑。

4. 评估体系与常见问题排查

4.1 业务场景下的评估维度

技术指标只是第一步。我的习惯是在常规指标之外,单独建立一套“业务测试集”,也就是从实际场景中抽出200张具有代表性的图片,图片覆盖电梯、楼道、地库、园区路面,并且包含大量夜间、遮挡、人车混杂的极端情况。每次模型迭代后,都在这套测试集上回归一遍,防止优化A场景时把B场景搞坏。

业务测试集我关注四个核心维度:

  • 电梯内场景漏检率:这是最高优先级指标,漏检一辆进电梯的电动车意味着梯控失效,必须保持在极低水平;
  • 夜间场景召回率:夜间监控画质差,电动车大灯、反光条都会造成干扰,需要单独统计;
  • 人车混杂场景误检率:婴儿车、轮椅、广场玩具车很容易触发误报,误报多了物业会直接关系统;
  • 单帧推理耗时:边缘设备上必须控制延迟,尤其多路视频并发时。

4.2 训练和部署中的常见问题速查

整个过程中我踩过不少坑,整理成一张速查表,直接照着排查就行:

问题现象 可能原因 解决办法
夜间漏检严重 夜间样本占比不足 补充夜间/低照度样本,开启亮度增强
把公交车/卡车误检成电动车 目标宽高比特征混淆 检查标注框是否贴合车身,增加负样本裁剪
摩托车大量误报为电动自行车 摩托车类别未标注或样本太少 单独增加motorcycle类别并补样
远处小目标检测不到 下采样后目标像素过少 提高imgsz或增加copy-paste小目标增强
多目标场景loss异常、预测乱 训练标签里漏框 回查标注,重点审核密集场景
白天好夜间差 训练集光照分布不均 采集更多夜间数据,做光照归一化
雨天误检多 地面反光干扰 增加雨天地面反光样本

排查问题时有个思路:不要一上来就调模型参数,先看数据和标签。很多“模型效果差”的问题,最终都指向标注错误、类别不均衡、场景覆盖不足这些数据层面的问题。

4.3 难例挖掘让数据持续增值

数据集不是一次性建完就完事,它应该跟着模型一起迭代。我常用的迭代流程是“难例挖掘”:

  • 用当前模型跑一遍所有未标注的监控视频抽帧;
  • 把模型预测置信度较低的样本挑出来,比如置信度在0.3到0.6之间,这些是模型“拿不准”的目标;
  • 人工对这些样本进行标注,凡是真实电动车的都补进训练集;
  • 把模型高置信度但预测错误的目标也挑出来,分析是类别分错还是框位置偏;
  • 下一轮训练前,给这些难例样本更高的采样权重。

这套流程跑三四个循环后,模型在业务场景上的表现会明显上一个台阶。难例挖掘的本质是让模型把注意力集中到它最不确定的地方,比单纯增加随机数据更有效。我后面几次模型精度提升,靠的基本都是这个方法。

5. 部署落地与后续扩展方向

5.1 边缘设备部署要点

项目最终要部署到边缘设备上,我用的是NVIDIA Jetson Orin Nano。流程是先用YOLO导出TensorRT引擎,再在设备上做推理。几个部署要点很关键:

  • 导出时开启FP16精度,显存占用和延迟基本能砍半,精度损失很小;
  • 动态batch要根据实际路数设定,不要盲目开大,否则会撑爆显存;
  • 输入分辨率固定为训练时的640x640,不要随意改动,部署端和训练端输入不一致会导致精度明显下降;
  • 多路视频可以使用批处理优化,但要注意RTSP拉流本身的延迟,算端到端延迟时不能只算模型推理时间。

实测在Jetson Orin Nano上,YOLOv8s加TensorRT FP16,单路1080p视频推理耗时大约12到18毫秒,加上解码和梯控联动逻辑,整体端到端延迟能控制在200毫秒以内,满足现场要求。

5.2 从单框检测到多模态和旋转框

这份数据集目前的版本以水平框检测为主,但后续扩展方向很明确。第一,增加头盔检测能力,从“车”延伸到“人加车”,一个模型同时输出电动车位置和骑行人员是否戴头盔;第二,引入多模态数据,同时采集可见光和红外图像,红外图像对夜间检测的提升非常明显;第三,尝试旋转目标检测,监控俯视视角下斜停的电动车,水平框会框进大量背景,旋转框拟合得更贴近车身。MMRotate这类框架已经比较成熟,等数据量再扩大一些,可以考虑升级为旋转检测方案;第四,可以接入语义分割能力,把充电桩区域、消防通道区域先分割出来,再和检测框叠加,做区域占用判断。

5.3 把数据集当成长期资产来管理

最后说一个特别重要的建议:数据集才是项目里最珍贵的资产,不要把它当成一次性消耗品。模型可以换、框架可以换,但一份高质量、场景贴合、标注规范统一的数据集能陪着你迭代十几个版本。我从一开始就给数据集建立了版本管理,每次增删样本都记录下数量、时间、来源和标注变更。这些元信息在复盘模型问题时非常有用,比如“为什么最近模型误检变多了”,翻一下数据变更记录就能定位到是不是加了某批质量不高的图片。

我个人的习惯是,每次训练完都把模型的错误案例截图保存下来,按错误类型分类归档。等积累到一定数量后,这些案例本身就是下一轮数据扩充的“靶向清单”。用这个思路去扩充数据集,比随机在网上抓图要精准得多。

电动车目标检测这个方向现在还在快速增长,新场景、新需求层出不穷。数据集的构建没有终点,只有不断迭代。希望这份1600+电动车目标检测数据集的构建和训练经验,能帮你少踩几个坑,把更多精力放在真正有价值的业务逻辑上。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐