☰
地铁监控人员检测数据集实战:VOC/YOLO双格式与YOLO训练调参
2026/10/2 12:38:53 网站建设 项目流程

地铁监控场景下的人员检测,是智能安防和轨道交通领域里落地最早、也最容易被低估难度的一类任务。很多人第一次拿到"监控视角地铁场景人员检测数据集"这种标题,第一反应是"不就是检测人吗,COCO上跑个YOLO不就行了",结果一上手就发现:地铁站台的光照忽明忽暗、人群密度高、遮挡严重、监控视角俯角大、目标尺度差异悬殊,通用模型直接迁移过去mAP能掉一大截。这次我拿到的是一份2189张、单类别(person)、同时提供VOC和YOLO两种标注格式的地铁监控人员检测数据集,正好可以借它把"监控视角+地铁场景+人员检测"这条链路从头到尾讲透。不管你是刚入门目标检测想找一个真实场景练手,还是已经在做安防项目需要快速验证方案,这篇内容都能让你少走弯路——我会把数据集的格式细节、两种标注的转换逻辑、监控场景特有的坑、训练参数怎么调、以及实测中那些文档里不会写的经验,全部摊开讲清楚。

1. 先搞清楚这份数据集到底"特殊"在哪

1.1 2189张、单类别,这个规模意味着什么

先看基本盘:2189张图像,1个类别(person),VOC和YOLO双格式。这个体量在目标检测数据集里属于"中小规模"。COCO有十几万张,VOC2007+2012加起来两万多张,而2189张大概是什么概念?如果你做的是单类别检测,这个量级其实够用了,尤其是场景高度聚焦(都是地铁监控视角)的情况下,数据分布的"密度"比"数量"更重要。

我一般会这样判断一个数据集够不够用:单类别检测,如果场景单一、目标形态相对固定,1500到3000张就能训出一个可用的baseline;如果是多类别、场景发散,那至少得5000张起步。这份数据集正好卡在"够用但不富裕"的区间,所以怎么用好它、怎么通过数据增强和迁移学习把它的价值榨干,比单纯堆数据更重要。

单类别还有个隐性好处:你不用处理类别不平衡问题。多类别数据集里最常见的头疼事就是某些类别样本极少,导致模型对它们几乎没学习能力。person这一类在地铁监控里天然就是主角,每张图里少则几个、多则几十个目标,样本量非常充足。

1.2 监控视角带来的三个"反常识"难点

普通的目标检测教程里,人都是正常站姿、平视角度、清晰完整。但地铁监控完全是另一回事,我总结了三个最容易被忽视的难点:

第一,俯角导致的形态畸变。监控摄像头通常装在天花板或高处,俯视角一般在30到60度之间。这个角度下,人的比例会被压缩,头肩占比变大、腿部变短,甚至只露出一个头顶。通用模型在COCO这种平视数据上学的"人体先验"在这里会部分失效。

第二,尺度极端分化。同一个画面里,近处的人可能占几百像素高,远处站台尽头的人可能只有十几个像素。这种尺度跨度对检测器的多尺度能力是硬考验,也是为什么FPN、PANet这类特征金字塔结构在监控场景里几乎是标配。

第三,遮挡与密集。早晚高峰的地铁站台,人群是"糊"在一起的。人与人之间互相遮挡,模型很容易把两个人检成一个,或者漏掉被挡住的那个。这个问题在单类别检测里尤其突出,因为没有其他类别帮你做上下文区分。

提示:如果你拿这份数据集直接套用COCO预训练模型,先别急着调参,第一步应该是可视化几十张标注图,亲眼看看目标尺度和遮挡的分布,这比看任何指标都直观。

1.3 VOC和YOLO双格式,到底该用哪个

数据集同时给了VOC和YOLO两种格式,这不是冗余,而是照顾不同的训练框架。简单说清楚区别:

维度VOC格式YOLO格式
标注文件XML(每张图一个)TXT(每张图一个)
坐标表示绝对像素值 xmin,ymin,xmax,ymax归一化中心点+宽高 cx,cy,w,h
坐标范围0 到 图像宽/高0 到 1
常用框架Faster R-CNN、SSD、MMDetectionYOLO系列、Darknet
可读性高,带类别名和图像尺寸低,纯数字

VOC格式的好处是信息全,XML里连图像宽高、类别名都写好了,人眼可读,调试时方便。YOLO格式的好处是训练时读取快,不用解析XML,而且归一化坐标天然适配不同输入尺寸的缩放。

我的建议是:用YOLO系列训练就直接用TXT,用MMDetection或PaddleDetection就用XML。但不管用哪个,都建议自己写个脚本把两种格式互相转换一遍,一来验证标注一致性,二来转换过程中能发现很多隐藏问题(比如坐标越界、宽高为负、类别名拼写不一致)。这个转换脚本后面我会给。

2. 标注格式的转换与数据清洗实操

2.1 VOC转YOLO:归一化坐标的计算细节

VOC的XML里,一个目标长这样:

<object> <name>person</name> <bndbox> <xmin>312</xmin> <ymin>145</ymin> <xmax>398</xmax> <ymax>402</ymax> </bndbox> </object>

转成YOLO格式,需要四个归一化值:中心点x、中心点y、宽、高。计算逻辑是:

# 假设图像宽 w_img=1920, 高 h_img=1080 xmin, ymin, xmax, ymax = 312, 145, 398, 402 w_img, h_img = 1920, 1080 cx = (xmin + xmax) / 2.0 / w_img cy = (ymin + ymax) / 2.0 / h_img w = (xmax - xmin) / w_img h = (ymax - ymin) / h_img # 结果: cx≈0.1849, cy≈0.2532, w≈0.0448, h≈0.2380

这里有个极易踩的坑:图像宽高必须从对应的XML里读,不能想当然用固定值。地铁监控数据集里图像分辨率可能不统一,有的1920×1080,有的1280×720,如果你写死一个尺寸,归一化坐标全错,训练时loss会莫名其妙不下降。

我写转换脚本时习惯加一层校验:转换后检查所有值是否落在[0,1]区间,超出范围的就打印出来人工核对。实测中确实能揪出一些标注时手抖写错的框。

2.2 数据清洗:那些必须处理掉的"脏数据"

2189张里,几乎不可能全是干净标注。我拿到任何数据集,都会先跑一遍清洗流程,重点查这几类问题:

  • 零面积框:xmax等于xmin或ymax等于ymin,这种框训练时会产生NaN loss,必须删。
  • 越界框:坐标超出图像边界,比如xmax大于图像宽度。轻微越界可以裁剪到边界,严重越界直接删。
  • 极小框:宽或高小于3像素的,基本是误标,删掉。
  • 重复框:同一位置标了两个几乎重合的框,会导致模型学习混乱,用IoU大于0.9判断后去重。
  • 类别名不一致:有的写"person",有的写"Person"或"people",统一成"person"。
import os, xml.etree.ElementTree as ET def clean_voc(xml_dir, min_size=3): bad_files = [] for f in os.listdir(xml_dir): if not f.endswith('.xml'): continue tree = ET.parse(os.path.join(xml_dir, f)) root = tree.getroot() w = int(root.find('size/width').text) h = int(root.find('size/height').text) for obj in root.findall('object'): bbox = obj.find('bndbox') xmin = int(float(bbox.find('xmin').text)) ymin = int(float(bbox.find('ymin').text)) xmax = int(float(bbox.find('xmax').text)) ymax = int(float(bbox.find('ymax').text)) if xmax - xmin < min_size or ymax - ymin < min_size: bad_files.append((f, 'too small')) if xmin < 0 or ymin < 0 or xmax > w or ymax > h: bad_files.append((f, 'out of bound')) return bad_files

跑完这个清洗,我在这类数据集上通常能发现1%到3%的问题样本。别小看这个比例,脏数据对单类别检测的伤害是放大的,因为它会直接污染唯一类别的决策边界。

2.3 划分训练集、验证集、测试集的比例选择

2189张怎么分?常见做法是8:1:1或7:2:1。我的经验是:单类别、场景单一的数据集,验证集不用太大,但测试集要留够。

  • 训练集:1750张(约80%)
  • 验证集:220张(约10%)
  • 测试集:219张(约10%)

为什么验证集可以小?因为单类别任务的指标波动本来就小,验证集主要用来监控过拟合和调学习率,200张足够反映趋势。测试集留10%是为了最后给一个可信的泛化评估。

划分时必须随机打乱,而且要检查三个集合的目标数量分布是否均衡。如果某个集合里全是远景小人、另一个全是近景大人,那评估结果就不可信了。我一般会统计每个集合的平均目标数和平均目标面积,确保分布接近。

注意:如果你的数据是按视频帧连续抽的,相邻帧高度相似,随机划分会导致训练集和验证集"泄漏"。这种情况要按视频片段划分,而不是按帧随机分。这份数据集如果是抽帧来的,务必确认这一点。

3. 监控场景下的模型选型与训练策略

3.1 为什么YOLO系列是这类任务的首选

地铁监控人员检测,落地时最看重的往往不是极致精度,而是速度和精度的平衡,因为监控是实时流,要跑在多路视频上。这就决定了YOLO系列天然占优。

从YOLOv5到YOLOv8、YOLOv10,这个系列在单类别检测上的表现一直很稳。我实测下来,在2189张这个量级上:

  • YOLOv5s:训练快,收敛稳,mAP@0.5能到0.90左右,适合快速验证。
  • YOLOv8n/s:精度略高,尤其是小目标,因为它的解耦头和更强的特征融合。
  • YOLOv10:端到端无NMS,推理延迟更低,适合对速度极敏感的部署。

如果你只是想把这份数据集跑通、拿到一个能用的模型,YOLOv8s是我最推荐的起点——精度和速度平衡得最好,社区资源也最丰富。

3.2 针对小目标和遮挡的anchor与输入尺寸调整

监控场景最大的痛点是远处的小目标。默认的YOLO输入尺寸是640×640,但地铁监控原图往往是1920×1080,缩到640后,远处的人可能只剩几个像素,直接消失。

我的处理策略有两个:

第一,提高输入尺寸。把imgsz从640提到960甚至1280。代价是显存和推理时间增加,但小目标召回率提升明显。实测在960下,远景人员召回能比640高5到8个百分点。

第二,重新聚类anchor。虽然YOLOv8已经用了anchor-free,但如果你用的是YOLOv5这类anchor-based的,一定要用k-means在自己的数据集上重新聚类anchor。默认anchor是基于COCO的,跟监控视角的宽高比分布差很多。

# YOLOv5 重新聚类anchor python utils/autanchor.py --data data/metro.yaml --img-size 960 --thr 4.0 --n 9

聚类出来的anchor会明显偏向"瘦高"型,因为俯视角下人的宽高比跟平视不一样。

3.3 数据增强:哪些有用,哪些是坑

数据增强在监控场景里是把双刃剑。用对了能显著提升泛化,用错了会引入不真实的样本,反而伤害性能。

推荐用的增强:

  • Mosaic:YOLO的招牌增强,把4张图拼成1张,天然增加小目标和遮挡样本,非常适合监控场景。但要注意,训练后期建议关闭Mosaic,让模型在真实分布上收敛。
  • HSV色彩抖动:地铁站台光照变化大,色相、饱和度、明度抖动能提升光照鲁棒性。
  • 随机缩放:直接对应尺度变化,必开。
  • 随机平移:模拟目标出现在画面不同位置。

要谨慎用的增强:

  • 水平翻转:可以用,但要注意地铁场景里左右可能不对称(比如扶梯方向),翻转后可能产生不真实样本。单类别检测影响不大,可以开。
  • 垂直翻转:强烈不建议。监控是俯视,垂直翻转后人就"倒立"了,完全不符合真实分布。
  • 大角度旋转:同理,监控视角固定,大角度旋转不真实。小角度(±10度)可以。
# YOLOv8 数据增强配置示例 hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 10.0 translate: 0.1 scale: 0.5 shear: 2.0 perspective: 0.0 flipud: 0.0 # 垂直翻转关闭 fliplr: 0.5 mosaic: 1.0 mixup: 0.1

3.4 迁移学习:从COCO预训练到地铁场景

2189张从零训练,收敛慢且容易过拟合。用COCO预训练权重做迁移学习是标准操作。但这里有个细节:COCO里person类别的特征跟监控视角有差异,但底层特征(边缘、纹理、形状)是通用的。

我的做法是分阶段训练:

  1. 冻结主干:先冻结backbone,只训练检测头,学习率设大一点(0.01),跑20到30个epoch,让检测头快速适配新场景。
  2. 解冻微调:解冻全部层,学习率降到0.001,用余弦退火,跑100到150个epoch。
  3. 低学习率收尾:最后20个epoch把学习率降到0.0001,关闭Mosaic,让模型精细收敛。

这套流程在2189张上,通常能比直接端到端训练高出2到4个点的mAP。

4. 训练过程中的监控与调参经验

4.1 看loss曲线:哪些波动是正常的,哪些是危险信号

训练时盯着loss曲线,是判断训练是否健康的第一手段。但很多人不会看,看到loss抖动就慌。我总结几个判断标准:

  • box_loss和cls_loss整体下降,允许小幅震荡:正常。震荡幅度在10%以内不用管。
  • loss突然飙升到NaN:学习率太大,或者数据里有脏框(零面积、越界)。先查数据,再降学习率。
  • loss长时间不下降(平台期):可能是学习率太小,或者模型容量不够。试试warmup或者换更大的模型。
  • 训练loss降但验证loss升:典型过拟合。加数据增强、加dropout、或者早停。

单类别检测的cls_loss通常会降得很快,因为只有两类(person和背景),任务简单。如果cls_loss一直居高不下,八成是标注有问题。

4.2 mAP上不去时,按这个顺序排查

mAP卡在某个值上不去,是最常见的问题。我一般按这个顺序排查,从最可能的原因开始:

  1. 先看数据:可视化预测结果,看是漏检多还是误检多。漏检多说明小目标或遮挡没学好,误检多说明背景干扰大。
  2. 再看标注:抽查几十张,确认标注框是否准确。标注质量差,模型再强也白搭。
  3. 调输入尺寸:小目标漏检,优先提高imgsz。
  4. 调增强:遮挡严重,加强Mosaic和随机裁剪。
  5. 换模型:前面都试过还不行,换更大的模型或者更强的结构。
  6. 调学习率和epoch:最后才动这些,因为影响相对小。

这个顺序的核心逻辑是:数据问题永远优先于模型问题。我见过太多人一上来就换模型、调超参,结果发现是标注框偏了几个像素。

4.3 混淆矩阵和PR曲线怎么读

YOLO训练完会输出混淆矩阵和PR曲线。单类别检测的混淆矩阵很简单,就person和background两行两列,但信息量不小:

  • person被预测成background:漏检,看召回率。
  • background被预测成person:误检,看精确率。
  • 对角线越深越好:说明分类准确。

PR曲线看的是不同置信度阈值下精确率和召回率的权衡。曲线下的面积就是AP。如果曲线在低召回区就掉下来,说明高置信度预测里有误检;如果在高召回区才掉,说明漏检主要在低置信度区域。

我一般会找一个平衡点作为部署阈值:精确率和召回率都尽量高的那个置信度。监控场景通常更看重召回(宁可误检,不可漏检),所以阈值会设得偏低一些,比如0.25。

5. 部署前的验证与常见落地问题

5.1 用测试集做最终评估的正确姿势

训练时用的验证集,和最终评估用的测试集,必须严格分开。我见过有人拿验证集当测试集报指标,结果上线后性能暴跌。

最终评估时,我会做三件事:

  1. 在测试集上跑一遍,记录mAP@0.5、mAP@0.5:0.95、精确率、召回率。
  2. 按目标尺度分组评估:把测试集里的目标按面积分成小、中、大三组,分别看指标。监控场景里小目标指标往往最差,这是重点优化方向。
  3. 可视化失败案例:把漏检和误检的图挑出来看,找规律。是逆光?是密集遮挡?还是某个特定区域?

5.2 从PyTorch到部署格式的转换坑

模型训好了,要部署到实际监控系统里,通常需要转成ONNX或TensorRT。这一步坑不少:

  • 输入尺寸必须固定:ONNX导出时如果用了动态轴,部署端要对应支持。建议先固定成训练时的imgsz。
  • NMS要一起导出:YOLOv8可以端到端导出带NMS的模型,省去部署端实现NMS的麻烦。
  • 归一化要一致:训练时是除以255还是用mean/std,部署时必须一模一样,否则结果全错。
  • 类别数和类别名:导出后确认输出维度是1类还是80类,别把COCO的80类带进去了。
# YOLOv8 导出ONNX yolo export model=best.pt format=onnx imgsz=960 opset=12 simplify=True

5.3 实测中那些文档不会写的经验

最后分享几个我在实际项目里踩出来的经验,都是文档里找不到的:

第一,监控视频的帧间冗余要利用。单帧检测容易受瞬时遮挡影响,实际部署时可以对连续几帧的检测结果做跟踪和投票,能显著降低漏检和误检。ByteTrack这类轻量跟踪器配合检测器,效果提升很明显。

第二,光照突变要单独处理。地铁站台进出隧道、灯光切换时,画面会突然变亮或变暗,模型可能瞬间失效。可以在预处理里加自适应直方图均衡(CLAHE),提升光照鲁棒性。

第三,别迷信高mAP。我见过mAP 0.95的模型上线后效果很差,因为测试集和真实场景分布不一致。真正靠谱的做法是拿真实监控流做A/B测试,看实际业务指标(比如漏检率、误报率),而不是只看离线mAP。

第四,数据集要持续迭代。2189张只是起点。上线后把模型出错的样本收集起来,人工标注后加入训练集,迭代几轮,效果会有质的提升。这就是所谓的"数据飞轮",在监控场景里尤其有效,因为真实场景的长尾情况太多了。

关于这份地铁监控人员检测数据集,我个人最深的体会是:场景聚焦的数据集,价值不在数量,而在分布的真实性。2189张如果都是真实地铁监控抽帧,那它比一万张网上爬的通用行人图有用得多。用好它,关键是把格式转换、数据清洗、场景适配的增强、以及迁移学习这几步做扎实,剩下的就是耐心调参和持续迭代了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询