ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

地铁监控人员检测数据集:VOC+YOLO双格式2189张实战指南

地铁监控人员检测数据集:VOC+YOLO双格式2189张实战指南 1. 地铁监控场景下的人员检测数据集拆解与选型思路1.1 为什么地铁场景的人员检测值得单独做一个数据集做过安防监控项目的人都有一个共识通用数据集上跑出来的指标放到真实地铁监控画面里往往要打个七折。原因不复杂——地铁场景有几个非常鲜明的视觉特征是COCO、VOC这些通用数据集覆盖不足的。第一是俯视与斜俯视视角。地铁站台的摄像机大多吊装在3米以上的高度向下倾斜拍摄行人在画面里呈现的是“头肩占比大、腿部被压缩”的形态跟通用数据集里大量平视拍摄的行人差异明显。第二是密集遮挡。早晚高峰时段站台候车区人员密度极高前后遮挡、相互重叠是常态这对检测框的回归和NMS后处理都是考验。第三是光照极端化。地下站厅靠人工照明光线偏黄偏暗高架站台又有强烈的逆光和阴影交替。第四是背景干扰强。广告灯箱、屏蔽门反光、列车车体、立柱都会产生类似人形的纹理。所以当我看到“监控视角地铁场景下的人员检测数据集VOCYOLO格式2189张1类别”这个标题时第一反应是这是一个垂直场景、单一类别、双格式标注的实用型数据集。2189张的规模不算大但胜在场景聚焦、标注统一非常适合做地铁安防场景下的模型微调或者算法验证。它解决的核心问题就是——让你不用从零标注直接拿来做迁移学习的起点。这个数据集适合谁我梳理了三类人一是做智慧交通、轨道交通安防的算法工程师需要快速验证人员检测方案二是高校里做目标检测课题的学生想找一个场景明确、格式规范的数据集练手三是已经有一套YOLO训练流程想补充地铁场景数据做增量训练的朋友。如果你属于这三类那接下来的内容会对你有直接帮助。1.2 VOC与YOLO双格式到底意味着什么很多人看到“VOCYOLO格式”就一带而过其实这两个格式的差异直接决定了你拿到数据后第一步该做什么。VOC格式的核心是XML文件每张图片对应一个同名的.xml里面用object标签逐个记录目标的类别和边界框边界框用xmin、ymin、xmax、ymax四个值表示是绝对像素坐标。这种格式的好处是可读性强、信息完整还能带difficult、truncated等标记缺点是文件体积大、解析慢训练时通常需要先转成其他格式。YOLO格式的核心是TXT文件每张图片对应一个.txt每行代表一个目标格式是类别索引 x_center y_center width height后四个值都是归一化到0到1之间的相对值。这种格式解析极快是YOLO系列训练的标配但可读性差而且类别是靠索引对应的必须配合一个classes.txt或者data.yaml才能知道索引0代表什么。这个数据集是1类别也就是只有“person”这一类。这意味着在YOLO格式里所有标注行的第一个数字都是0。别小看这一点——单类别任务省去了类别不平衡的烦恼但也意味着你的模型只需要学“是不是人”不需要区分“是哪种人”训练收敛会快很多。提示拿到双格式数据集后不要两个格式都用。建议以YOLO格式为主进行训练VOC格式作为备份和校验。因为VOC的XML可以用来交叉验证YOLO的TXT有没有转换错误这是一个很实用的质检手段。1.3 2189张这个规模该怎么定位2189张在目标检测数据集里属于中小规模。作为参照VOC2007训练集约5000张COCO是十几万张。但数据集的价值从来不只看数量更要看场景密度和标注质量。如果这2189张覆盖了不同时段早高峰、平峰、晚高峰、不同站点类型地下站、高架站、换乘站、不同光照条件那它的有效信息量可能比一万张随机采集的图片还高。反过来如果2189张都是同一个摄像头、同一时段截取的连续帧那冗余度就很高实际有效样本可能只有几百张。我的经验是拿到数据集先做去冗余分析。具体做法是计算图片的感知哈希pHash把相似度超过阈值的图片聚类看看有多少是近似重复帧。如果重复率高训练时要做采样控制否则模型会过拟合到某些特定背景。从训练角度2189张单类别数据配合预训练权重做微调通常能在几十个epoch内收敛到一个可用的水平。但如果你想从零训练这个量级偏少容易欠拟合。所以我的建议很明确必须用预训练模型这一点后面会详细讲。2. 数据集的核心细节与实操前的关键检查2.1 目录结构应该长什么样一个规范的双格式数据集目录结构通常是这样组织的。我把自己常用的结构列出来你可以对照手里的数据集检查是否一致dataset/ ├── images/ # 所有图片 │ ├── 000001.jpg │ ├── 000002.jpg │ └── ... ├── labels_yolo/ # YOLO格式标签 │ ├── 000001.txt │ ├── 000002.txt │ └── ... ├── annotations_voc/ # VOC格式标签 │ ├── 000001.xml │ ├── 000002.xml │ └── ... ├── classes.txt # 类别列表内容为 person └── data.yaml # YOLO训练配置这里有几个容易踩坑的地方。第一图片和标签必须同名扩展名不同否则训练时会找不到标签。第二classes.txt里类别的顺序必须和标注文件里的索引一致单类别的话就是第0行是person。第三如果数据集把图片和标签混在一个文件夹里训练前一定要先分离否则数据加载器会把TXT也当图片读直接报错。注意有些数据集打包时用的是中文路径或者带空格的路径在Linux服务器上训练时极易出问题。拿到数据第一件事就是把路径改成纯英文、无空格。2.2 标注质量的自查方法标注质量是数据集的生命线。2189张里如果混入了大量漏标、错标模型学出来的就是错的。我总结了几个快速自查的方法不需要写复杂脚本就能做。方法一可视化抽查。随机抽50到100张把YOLO的TXT标注画成框叠加到图片上肉眼检查。重点看三类问题框是否把整个人包住了有没有切头切脚、密集区域有没有漏标、有没有把广告牌上的人像误标成真人。这一步用Python的OpenCV或者PIL十几行代码就能搞定。方法二坐标越界检查。YOLO格式的坐标必须在0到1之间。写个脚本遍历所有TXT统计有没有小于0或大于1的值。如果有说明标注时出了问题需要修正或剔除。方法三宽高异常检查。统计所有框的宽高分布如果出现宽或高接近0的极小框或者宽高比极端异常的框比如宽是高的10倍大概率是误标。地铁场景里正常行人的宽高比通常在0.2到0.6之间俯视视角下偏瘦长。方法四VOC与YOLO交叉验证。这是双格式数据集独有的优势。写脚本把VOC的XML和YOLO的TXT都解析出来逐张对比框的数量和位置。如果某张图两个格式的框数量对不上说明转换过程有丢失需要重点排查。我实测下来一个2000张级别的数据集用这四个方法过一遍大概两三个小时能完成质检。这个时间投入绝对值得因为带着脏数据训练后面调参调到怀疑人生都救不回来。2.3 类别定义与标注边界的一致性单类别数据集看似简单其实“什么算person”这个边界如果标注时不统一照样出问题。地铁场景里几个典型的模糊地带被严重遮挡的人只露出一个头或者半个身子算不算如果算框怎么画我的建议是遮挡超过70%的目标可以标记为difficult或者直接不标避免给模型引入噪声。玻璃反光里的人影屏蔽门、车窗上的倒影算不算通常不算因为那不是真实的人标了会让模型学到错误的特征。远处极小的人画面边缘只有十几个像素高的人算不算这取决于你的应用需求。如果检测目的是客流统计远处的人也要算如果只关心近处可以设一个最小尺寸阈值。广告牌、海报上的人像坚决不标这是最常见的误标来源。提示如果数据集没有附带标注规范文档建议你自己根据抽查结果反推标注规则并在训练前统一处理。一致性比“绝对正确”更重要。3. 从数据到模型完整实操流程3.1 环境搭建与依赖安装训练YOLO系列模型环境搭建是第一步。我以目前最主流的Ultralytics YOLOv8为例把完整流程走一遍。这套流程在Ubuntu 20.04/22.04和Windows上都能跑显卡建议8GB显存起步6GB也能勉强跑小batch。先创建独立的Python环境避免和系统环境冲突conda create -n metro_det python3.10 -y conda activate metro_det然后安装PyTorch。这里要注意CUDA版本和显卡驱动的匹配。如果你不确定自己的CUDA版本用nvidia-smi命令查看右上角的CUDA Version。以CUDA 11.8为例pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118接着安装Ultralyticspip install ultralytics验证安装是否成功yolo checks这个命令会输出环境信息包括PyTorch版本、CUDA是否可用、显卡型号等。如果CUDA显示不可用说明PyTorch装成了CPU版本需要卸载重装。注意不要用pip install ultralytics之外的方式装YOLO比如从GitHub克隆源码再装容易遇到依赖冲突。Ultralytics的pip包已经把依赖处理得很好了。3.2 数据配置文件编写YOLOv8训练需要一个data.yaml文件来指定数据路径和类别。针对这个数据集配置如下path: /home/user/metro_dataset train: images/train val: images/val test: images/test nc: 1 names: 0: person这里有几个关键点要说明。path是数据集根目录train/val/test是相对于path的子路径。nc是类别数量单类别就是1。names是类别名称字典索引必须从0开始。训练集、验证集、测试集的划分是个容易被忽视的环节。2189张的规模我建议按7:2:1划分即训练集约1532张验证集约438张测试集约219张。划分时要注意同一摄像头、同一时段的图片不能跨集否则验证集里的图片和训练集高度相似验证指标会虚高失去参考意义。划分脚本的核心逻辑是先按图片的采集来源如果文件名或元数据里有站点、时段信息分组再按组划分。如果拿不到来源信息退而求其次用感知哈希聚类后再划分。import os import shutil import random from sklearn.model_selection import train_test_split random.seed(42) img_dir images all_imgs [f for f in os.listdir(img_dir) if f.endswith((.jpg, .png))] train_val, test train_test_split(all_imgs, test_size0.1, random_state42) train, val train_test_split(train_val, test_size0.22, random_state42) for split, files in [(train, train), (val, val), (test, test)]: os.makedirs(fimages/{split}, exist_okTrue) os.makedirs(flabels/{split}, exist_okTrue) for f in files: shutil.copy(os.path.join(img_dir, f), fimages/{split}/{f}) label_f os.path.splitext(f)[0] .txt shutil.copy(os.path.join(labels_yolo, label_f), flabels/{split}/{label_f})3.3 预训练模型的选择与下载前面说过2189张必须用预训练模型。YOLOv8提供了n、s、m、l、x五个尺度的预训练权重参数量从300万到6800万不等。怎么选我的经验是按部署硬件倒推。如果是边缘设备部署比如地铁站里的AI盒子、Jetson系列选yolov8n.pt或yolov8s.pt模型小、推理快精度损失在可接受范围内。如果是服务器端部署有独立显卡可以上yolov8m.pt甚至yolov8l.pt精度更高。下载预训练权重很简单Ultralytics会在训练时自动下载。但如果你在离线环境需要提前下好放到指定目录。权重文件从Ultralytics官方发布页获取文件名类似yolov8s.pt。这里有个细节预训练权重是在COCO上训练的COCO里person类别的特征和地铁场景有差异但底层特征边缘、纹理、形状是通用的。所以微调时主干网络的学习率要设小一点让底层特征少变检测头的学习率可以大一点让它快速适应新场景。3.4 训练参数配置与启动YOLOv8的训练命令很简洁但参数配置决定了成败。我给出一个针对这个数据集的推荐配置yolo detect train \ datadata.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ momentum0.937 \ weight_decay0.0005 \ warmup_epochs3 \ patience20 \ device0 \ workers8 \ projectmetro_runs \ nameexp1逐个解释关键参数。epochs100是训练轮数配合patience20早停机制如果20轮验证指标没提升就自动停避免过拟合。imgsz640是输入分辨率地铁监控画面通常宽高比是16:9640是YOLO的默认值如果显存够可以上到960或1280对小目标更友好。batch16是批大小8GB显存跑yolov8s加640分辨率16是安全的。lr00.01是初始学习率微调任务可以降到0.001。lrf0.01是最终学习率系数配合余弦退火策略。数据增强是提升小数据集泛化能力的关键。YOLOv8默认开启了Mosaic、HSV抖动、随机翻转等增强。针对地铁场景我建议额外关注几个参数hsv_h、hsv_s、hsv_v控制色调、饱和度、明度抖动地铁光照变化大可以适当调高degrees控制旋转角度监控视角固定旋转增强不宜过大设0到5度即可translate和scale控制平移和缩放可以保持默认。提示第一次训练先用默认增强跑一遍看验证集指标。如果过拟合明显训练loss降但验证loss升再加大增强力度。不要一上来就堆一堆增强参数那样反而看不清哪个参数起了作用。3.5 训练过程的监控与指标解读训练启动后Ultralytics会在metro_runs/exp1/目录下生成一系列文件包括权重、日志、可视化图表。重点看这几个results.csv记录了每个epoch的各项指标包括训练loss、验证loss、mAP50、mAP50-95、precision、recall。用pandas读出来画个曲线图一眼就能看出训练是否健康。混淆矩阵confusion_matrix.png对单类别任务来说就是看person被正确检测、被误检为背景、背景被误检为person的比例。如果背景误检率高说明模型把一些背景纹理当成了人需要检查标注里有没有漏标。PR曲线PR_curve.png反映了不同置信度阈值下的precision和recall权衡。曲线下的面积就是AP单类别任务的mAP就等于AP。训练批次可视化train_batch*.jpg展示了实际喂给模型的图片和标注框可以用来确认数据增强有没有把框搞乱、图片有没有读错。我通常关注三个信号mAP50在多少epoch趋于稳定、训练loss和验证loss的差距有多大、recall和precision是否均衡。如果recall明显低于precision说明漏检多可以降低置信度阈值或者增加正样本反之则误检多。4. 常见问题排查与实战避坑经验4.1 训练不收敛或loss震荡这是新手最常遇到的问题。表现是训练loss忽高忽低mAP长期在低位徘徊。原因通常有四个学习率过大。微调任务用0.01的初始学习率对某些数据集来说偏大。解决办法是降到0.001甚至0.0005或者用lr00.01配合更长的warmup。标注格式错误。如果TXT里的坐标没有归一化或者类别索引写成了1而不是0模型学到的就是错的。用前面说的自查方法过一遍。数据划分不合理。如果训练集和验证集分布差异太大验证指标会很难看。检查划分时有没有把同一场景的图片分到不同集合。batch size太小。batch过小会导致BN层的统计量不稳定loss震荡。如果显存不够可以用梯度累积模拟大batch。4.2 密集遮挡场景漏检严重地铁高峰期的密集人群是这个数据集的核心难点。如果训练完发现密集区域漏检多可以从几个方向优化提高输入分辨率。640分辨率下远处的小目标只有几个像素模型很难分辨。上到960或1280小目标特征更清晰。代价是显存占用和推理时间增加。调整NMS的IoU阈值。密集场景下两个真实目标的框可能重叠度很高标准NMSIoU阈值0.45会把其中一个误删。可以适当调高到0.5到0.6或者改用Soft-NMS。增加正样本匹配。YOLOv8用的是TaskAlignedAssigner对密集小目标可以调整topk参数让更多anchor参与正样本匹配。补充困难样本。如果数据集里密集场景的图片偏少可以针对性采集或合成一些加入训练集。4.3 误检把背景当成人误检的典型来源是广告牌人像、玻璃反光、立柱纹理。排查方法是把误检的图片挑出来看模型在哪些区域给出了高置信度。如果集中在某类背景说明训练集里这类负样本不足。解决办法有两个一是增加纯背景图片作为负样本让模型学会“这里没有人”二是在标注时把误检区域显式标出来但这不是标准做法更推荐前者。YOLOv8支持把没有标注的图片作为背景图参与训练只要图片对应的TXT是空文件即可。4.4 常见问题速查表问题现象可能原因排查方法解决方向训练loss不降学习率过大、标注错误检查TXT格式、降低lr降lr到0.001、修正标注验证mAP远低于训练mAP过拟合、数据划分不合理看loss曲线、检查划分加增强、重新划分密集区域漏检分辨率低、NMS过严可视化检测结果提高imgsz、调NMS阈值背景误检多负样本不足统计误检区域加背景图、补充负样本训练中途崩溃显存不足、数据损坏看报错信息降batch、检查图片推理速度慢模型过大、分辨率高测FPS换小模型、降分辨率4.5 我踩过的几个坑坑一直接拿VOC格式训练。早期我用YOLO训练时图省事想直接用VOC的XML结果发现YOLO的数据加载器只认TXT。后来写了个转换脚本但转换时忘了归一化坐标全是像素值训练loss直接爆炸。教训是格式转换后一定要可视化验证。坑二忽略了图片的EXIF方向。有些手机或相机拍的图片带EXIF旋转信息用PIL读取时如果不处理图片是横的但标注是按竖的画的框全错位。解决办法是用ImageOps.exif_transpose统一处理。坑三验证集里混入了训练集的近似帧。有一次mAP高得离谱达到0.95我还以为模型特别强。后来发现验证集里有好几张和训练集几乎一样的连续帧等于开卷考试。重新按摄像头分组划分后mAP回落到0.82这才是真实水平。坑四忘了设置随机种子。第一次跑和第二次跑结果差很多排查半天才发现是数据划分和增强的随机性导致的。后来固定了seed42结果才可复现。5. 模型评估、导出与部署衔接5.1 在测试集上做最终评估训练完成后用验证集选出的最佳权重在测试集上跑一次评估这才是模型的真实水平。命令如下yolo detect val \ modelmetro_runs/exp1/weights/best.pt \ datadata.yaml \ splittest \ imgsz640 \ batch16输出会给出mAP50、mAP50-95、precision、recall等指标。对单类别人员检测我通常关注mAP50能否到0.85以上recall能否到0.8以上。如果达不到说明还有优化空间。评估完别忘了可视化一些检测结果特别是密集场景和困难场景。指标好看不代表实际好用肉眼看过才放心。5.2 模型导出为部署格式训练出的.pt权重是PyTorch格式部署时通常要转成更高效的格式。常见的有ONNX、TensorRT、OpenVINO等。以ONNX为例yolo export modelmetro_runs/exp1/weights/best.pt formatonnx imgsz640如果部署在NVIDIA显卡上TensorRT能带来数倍加速yolo export modelmetro_runs/exp1/weights/best.pt formatengine imgsz640 halfTruehalfTrue表示用FP16精度速度更快精度损失很小。导出后建议用同样的测试图片对比一下导出前后的检测结果确保没有精度损失。5.3 部署时的预处理对齐这是最容易被忽视的环节。训练时的预处理包括resize、归一化、通道顺序转换部署时的预处理必须完全一致否则精度会掉。YOLOv8的预处理是letterbox缩放到640x640保持宽高比灰边填充、BGR转RGB、归一化到0到1、HWC转CHW。如果你用ONNX Runtime部署这些都要自己实现。我见过太多人因为预处理没对齐导致部署后mAP掉了十几个点还以为是模型问题。提示部署前用同一张图片分别跑PyTorch模型和部署模型对比输出的检测框。如果框的位置和置信度基本一致说明预处理对齐了。6. 数据集扩展与持续优化思路6.1 主动学习让模型帮你找难样本2189张只是起点。实际项目中数据是持续积累的。与其盲目采集不如用主动学习的思路先用当前模型跑一遍未标注的监控视频把置信度在0.3到0.6之间的检测结果挑出来这些就是模型“拿不准”的样本人工标注后加入训练集收益最大。这个流程可以循环迭代训练模型、推理新数据、挑难样本、标注、再训练。通常两三轮下来模型在目标场景的表现会有明显提升。6.2 针对地铁场景的增强策略除了通用增强地铁场景可以做一些针对性增强。比如模拟不同光照用Gamma校正模拟暗光用亮度调整模拟逆光。模拟遮挡随机在图片上贴一些矩形块模拟立柱、广告牌的遮挡。模拟运动模糊对图片做轻微的运动模糊模拟行人走动时的拖影。这些增强可以用Albumentations库实现YOLOv8也支持自定义增强。不过要注意增强是为了让模型见到更多变化不是为了把图片搞得面目全非。增强后的图片还是要能看出是人。6.3 从单类别到多类别的扩展如果后续需求从“检测人”扩展到“检测人、行李箱、推车”等多类别这个数据集可以作为基础。做法是保留person的标注新增类别的标注把nc改成对应数量names里加上新类别。但要注意新增类别后原来的单类别模型不能直接微调需要重新训练检测头。扩展时还要注意类别平衡。如果person有上万框行李箱只有几百框模型会偏向person。解决办法是对稀有类别做重采样或者在loss里给稀有类别更高权重。7. 一些实操心得与建议关于这个数据集的使用我个人最深的体会是场景聚焦的数据集价值在于“专”而不在于“大”。2189张地铁监控图片如果标注质量过关配合预训练模型完全能训出一个在目标场景可用的检测器。但前提是你得把数据质检、格式转换、参数配置这几步做扎实。另一个心得是不要迷信指标。mAP高不代表实际好用一定要在真实视频流上跑一跑看检测框稳不稳、有没有闪烁、密集场景表现如何。我见过mAP 0.9的模型在视频里框跳得厉害实际根本没法用。视频上的时序稳定性是静态图片指标看不出来的。最后分享一个小技巧训练时把save_period设成10每10个epoch存一次权重。这样如果后期发现某个中间epoch的模型在特定场景表现更好还能找回来。只存best和last有时候会错过更合适的权重。这个数据集后续还可以这样扩展把检测结果接入跟踪算法比如ByteTrack做客流统计和轨迹分析或者结合ReID做跨镜追踪。人员检测是很多上层应用的基础把这一步做稳后面的路就好走了。
返回列表