尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

监控视角YOLO行人检测:数据集工程与训练避坑实战

发布时间:2026/9/27 20:24:13

资讯中心
01
ARTICLE

监控视角YOLO行人检测:数据集工程与训练避坑实战

监控视角YOLO行人检测:数据集工程与训练避坑实战
简介面向安防监控场景下的行人目标检测需求这份 YOLO 数据集采用 YOLOv5 标准目录结构包含训练、验证、测试三部分标签文件与类别定义可直接加载训练特别适宜目标检测学习者、行人检测项目开发者以及 YOLOv5 改进研究者使用。资源包共 2000 个文件其中 1999 个 txt 标注文件对应标准 YOLO 标签格式另有 1 个 Python 可视化脚本压缩后整体约 305.88MB脚本可随机读取一张图片绘制边界框并保存至当前目录无需修改即可运行便于快速检查标注结果。数据集附带的 class 文件明确了唯一类别“行人”标注字段与 YOLOv5 训练要求一致能减少数据格式转换和标注整理的额外工作适合作为监控视角下行人检测的基准数据或用于对比不同 YOLOv5 改进策略的效果。目前已有 251 人学习/下载配合作者博客中的 YOLOv5 改进实战系列文章可帮助读者将精力集中于模型结构设计、训练调参与结果分析。1. 监控视角的 YOLO 行人检测为什么公开权重总让你翻车监控项目上线前算法工程师干得最多的活不是调模型而是跟数据集较劲。同一个公开权重拿到小区门口低机位画面里三米外的行人糊成一团漏检率肉眼可见地高晚上切到红外通道模型更是像喝醉了酒。YOLO 的目标检测管线本身已经很成熟真正决定落地效果的是你手里那份监控视角下的行人数据集有没有正确划分、类别 class 文件对不对得上、数据可视化脚本能不能帮你把标注质量看清。这篇笔记围绕这样一套数据集工程讲落地路径覆盖目录结构、class 文件、可视化脚本和 YOLOv8 训练参数适合准备自建监控行人数据的算法工程师也适合想用真实数据跑通一版目标检测训练的新手。2. 划分好的数据集怎么用目录组织、class 文件与 data.yaml 对齐拿到一份划分好的监控行人数据集第一件事不是急着训练而是先把目录结构和标注格式摸清。很多人在这步跳过去结果训练到一半发现标注路径全错返工成本比重新标数据还高。一份规范的检测数据集结构通常一眼就能看明白。2.1 监控数据集的标准目录结构与标注格式我一般会先跑一遍 tree 命令确认数据集是不是长这样YOLO-Person-Monitor/ ├── images/ │ ├── train/ │ ├── val/ │ ├── test/ ├── labels/ │ ├── train/ │ ├── val/ │ ├── test/ ├── class.txt └── data.yamlimages 下面按 train、val、test 分目录labels 目录和 images 一一对应每张图的标注信息写在同名 txt 文件里。要注意train 图片目录里不能残留多余的临时文件YOLO 训练时会扫描整个目录多出任何非图片文件都可能让数据加载中断。class.txt 和 data.yaml 放在数据集根目录是后续训练直接引用的两个关键文件。labels 里的标注文件是纯文本格式每一行代表一个目标0 0.4532 0.7123 0.1354 0.3211 0 0.2810 0.5504 0.0921 0.1877五列的含义依次是类别ID、目标中心点 x 坐标比例、中心点 y 坐标比例、目标宽度比例、目标高度比例。后四列都是归一化数值用像素坐标除以图片宽高得到数值范围在 0 到 1 之间。YOLO 从 Darknet 时代就是这个格式ultralytics 框架也沿用同一套所以这份数据集拿回来基本不需要做格式转换只要确认路径对得上、类别ID从 0 开始连续编号就行。提示如果 class.txt 里类别数量和你标注文件里的最大类别ID对不上比如 class.txt 只有一类但标注文件里出现了 ID2 的目标那这份数据的标签肯定有问题必须先修数据再训练。2.2 train/val/test 划分比例与抽帧去重的取舍监控场景的数据集划分和普通网图数据集最大的区别在于“时间相关性”。一段 1 小时的监控视频相邻两帧之间几乎只有几像素的位移如果直接随机划分验证集里会出现大量训练帧的“孪生兄弟”mAP 看起来虚高 10 个百分点部署到新场景立刻现原形。我一般会按这个流程处理原始视频抽帧先用 30 秒到 1 分钟的片段试看画面变化速度画面变化快的场景每隔 15 帧抽一帧画面变化慢的每隔 30 帧抽一帧相当于每秒钟留 1 到 2 帧既保住信息量又不产生太多冗余。抽完帧再做一次感知哈希去重把相似度高于 0.95 的帧删掉这一步能再砍掉 20% 左右的重复样本。划分比例按 7:2:1 到 8:1:1 之间调整。正样本多的场景可以给 test 留 10%让最终验证更有说服力正样本紧张的监控点位比如地下车库我建议把 test 占比降到 5%把更多样本留给训练。更关键的是按摄像头分组划分摄像头 A 的画面只进 train摄像头 B 的画面只进 val 和 test避免同一位置场景同时出现在训练和验证两边。很多现成数据集按场景目录组织直接随机划分就会踩进这个坑。2.3 class.txt 与 data.yaml类别顺序错一位就全盘错乱class.txt 是数据集“给人看的类别清单”常见做法是每行一个类别名行号就是该类别在标注文件里的 ID# class.txt 内容 persondata.yaml 是“给模型读的类别清单”训练时必须和 class.txt 保持完全一致# 监控行人检测配置路径按你实际位置修改 path: D:/dataset/YOLO-Person-Monitor train: images/train val: images/val test: images/test nc: 1 names: 0: person这里最容易翻车的情况是数据集负责人把 class.txt 按自己的习惯改了顺序比如把 person 从第 0 位挪到第 1 位但 labels 里所有标注的类别ID没跟着改data.yaml 也没更新。训练出来的模型会把行人预测成另一个类甚至把所有背景都当成行人。我见过一个项目把行人和自行车两个类搞反了部署了一个多月才发现是个类别错位而不是算法不行。如果你的监控项目后续要扩展多类比如同时检测行人和骑行者class.txt 要加一行data.yaml 的 names 也要同步加标注文件第一列的 ID 必须和行号对齐。扩展之前先跑一个统计脚本确认每个类别实际有多少样本别在只有 200 个样本的类别上强行加权重那会让损失函数被少数类带偏。3. 数据可视化脚本用四张图把标注质量看透再开训很多人把数据可视化脚本当成“交差用的辅助工具”训练前跑一遍截图完事。实际上可视化暴露的问题比任何统计指标都直观漏标、错标、类别顺序错乱全都能在图上一眼看出来。监控场景的行人数据集尤其需要这一步因为俯视角、小目标多标注员的习惯差异会在训练里被放大。3.1 在图上画 bbox随机抽样叠加类别标签的脚本先用一段脚本随机抽出训练集里的图片把标注框和类别画回去人工过一遍。这一步能检查标注框是否贴合人体轮廓、是否存在大量漏标、类别ID是否张冠李戴。# overlay_bbox.py import cv2 import numpy as np from pathlib import Path img_dir Path(images/train) label_dir Path(labels/train) random_state np.random.RandomState(2025) # 随机抽 9 张图检查 img_paths list(img_dir.glob(*.jpg)) random_state.shuffle(img_paths) for img_path in img_paths[:9]: img cv2.imread(str(img_path)) if img is None: continue h, w img.shape[:2] label_path label_dir / (img_path.stem .txt) if not label_path.exists(): continue with open(label_path) as f: for line in f: parts line.split() if len(parts) ! 5: continue cls_id int(parts[0]) cx, cy, bw, bh map(float, parts[1:]) # 归一化坐标换算回像素坐标 x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) color (0, 255, 0) if cls_id 0 else (0, 0, 255) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, fcls-{cls_id}, (x1, y1 - 6), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 1) save_dir Path(check_imgs) save_dir.mkdir(exist_okTrue) cv2.imwrite(str(save_dir / img_path.name), img) print(已生成检查图到 check_imgs/ 目录)这段脚本的逻辑不复杂先按 txt 文件里的五列读出类别和归一化坐标再把归一化坐标乘回图片宽高画矩形框和类别文本。运行后打开 check_imgs 目录逐张看重点检查三类问题。第一框是否明显大于或小于人体轮廓监控场景行人密集、遮挡多标注员经常只框露出部分导致框偏小这种情况会在训练时让模型学到错误的目标边界。第二同一张图里漏标的目标多不多特别留意远处的小目标和骑行者这是漏标高发区。第三类别文本是否和画面内容一致一旦发现 cls-1 画在行人身上直接回去查 class.txt 和 data.yaml 的顺序。提示检查图脚本里的颜色判断只区分了类别 0 和 非 0如果数据集有 4 个类别建议改成按 cls_id 映射不同颜色否则看久了容易混淆。3.2 类别分布、宽高比与目标尺寸分布三个必看统计图单张看图只能发现“明显错误”统计分布才能暴露“系统性偏差”。我会跑一段统计脚本画出三张分布图目标宽高比分布、目标面积分布、目标高度占整图比例分布。# stats_dataset.py import numpy as np from pathlib import Path import matplotlib.pyplot as plt label_dir Path(labels/train) ratios, areas, heights [], [], [] class_count {} for label_path in label_dir.glob(*.txt): with open(label_path) as f: for line in f: vals line.split() if len(vals) ! 5: continue cls_id int(vals[0]) bw float(vals[3]) bh float(vals[4]) class_count[cls_id] class_count.get(cls_id, 0) 1 # 宽高比行人通常高瘦比值集中在 0.3 左右 ratios.append(bw / bh) # 面积占全图比例 areas.append(bw * bh) # 目标高度占全图高度比例 heights.append(bh) plt.figure(figsize(14, 4)) plt.subplot(1, 3, 1) plt.hist(ratios, bins50, range(0, 3)) plt.title(bbox width/height ratio) plt.subplot(1, 3, 2) plt.hist(areas * 10000, bins50) plt.title(bbox area ratio (x1e-4)) plt.subplot(1, 3, 3) plt.hist(heights, bins50, range(0, 1)) plt.title(bbox height / image height) plt.tight_layout() plt.savefig(dataset_stats.png) print(已生成统计图 dataset_stats.png) print(类别统计, class_count)运行完后我会按这三张图各看一个点。宽高比分布如果出现一个诡异的双峰说明数据里混入了非行人目标比如把电动车、三轮车也标成了 person这种标签噪音会直接把模型的定位精度拉下来。面积分布如果大多数目标占比不到 0.001也就是目标像素面积很小那就要认真考虑用大分辨率训练或切图推理。高度占比分布最直观监控场景大量行人高度只占整图 5% 到 10%这类目标在 640×640 的输入下大约只有 3060 像素高靠默认配置很难检出。这三个分布的结论要落到训练参数上宽高比离群样本过多就回去改标签面积普遍很小就考虑 imgsz1280 或者把高分辨率原图切成 960×960 的 patch 再训类别分布严重不均衡比如 person 有 5 万样本、rider 只有 800 样本那就先加 rider 的数据再谈训练光靠损失函数加权是治标不治本。3.3 可视化结果告诉我该加哪些数据而不是直接开训很多新手跑完可视化看到图“好像没问题”就直接启动训练了这是把可视化脚本用废了。可视化真正的价值是逼你回答两个问题当前数据的难点在哪里后续补数据往哪个方向补。我判断补数据方向有一套固定套路把叠框检查图按时间段分类早中晚各看一批。如果发现傍晚和夜间图里的标注框特别少说明这批监控数据基本是白天采集的训练出来的模型夜战能力会很差补数据优先找夜间录像。如果高度占比分布图显示大多数行人都在画面下半部分说明相机仰角偏高或安装位置特殊俯视样本太少模型上了新点位大概率翻车。把这些结论写在数据集说明里下次扩充数据就有明确方向而不是“再传两千张图片进来”这种碰运气式做法。4. 用 YOLOv8 训练监控行人数据集最小命令与四个必调参数数据集检查完终于可以进入训练环节。现在跑 YOLO 目标检测最稳定的选择是 YOLOv8 这一代训练命令短、配置直观、预训练权重好找。YOLOv9、YOLOv10 也有各自优势但监控行人检测这种任务稳定复现比追新版本重要得多。4.1 环境配置与预训练权重下载环境配置的坑通常不在框架本身而在 CUDA 版本和 Python 版本打架。我一般会用虚拟环境隔离项目避免把系统 Python 环境搞乱python -m venv yolov8-env source yolov8-env/bin/activate pip install ultralytics装完先跑一条预测命令验证环境顺便拿到预训练权重yolo detect predict modelyolov8n.pt sourcehttps://example.com/test.jpg第一次运行会自动下载 yolov8n.pt 权重文件网络慢或超时时可以手动把权重文件提前放到当前目录再用本地路径指定。确认命令能输出检测结果图说明环境没问题。提示不要直接用 YOLOv5 的旧环境升级上去跑 YOLOv8两个系列的依赖差异会导致莫名其妙的报错。监控项目图省事往往会在这步翻车重装环境花的半小时比调参划算得多。4.2 写 data.yaml 并跑通第一条训练命令数据集的 data.yaml 在第 2 章已经写好了这里直接用它。训练本身只有一条命令yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs100 \ batch32 \ imgsz640 \ device0 \ workers8 \ patience15这条命令的含义是用 yolov8n 预训练权重做迁移学习在监控行人数据集上训练 100 轮。epochs 设 100 对监控数据通常够用如果 val loss 在 60 轮左右就开始回升patience15 会自动早停不会硬跑完 100 轮浪费时间。第一次训练建议先不调任何高级参数跑通一次全流程确认数据加载、loss 计算、指标输出都正常再谈优化。跑通之后看两个信号判断训练状态一个是终端里的 mAP50 是否稳定上升另一个是 loss 曲线是否在某个节点突然跳变。如果第一次训练就在某个 epoch 直接崩掉先别查模型结构回头检查标注文件里有没有负数坐标或大于 1 的坐标这类脏数据会让 loss 变成 NaN。4.3 四个必调参数batch、imgsz、workers、patience监控行人检测这四个参数尤其需要单独调因为它们直接关系到小目标检出和显存占用参数推荐值说明batch1664V100 这类 24G 显存可以用 64小显存卡用 1632。单类 person 对 batch 要求不高宁可小 batch 也别把 imgsz 缩到 320imgsz6401280监控小目标多640 起步漏检严重就上 960 或 1280。imgsz 翻倍显存占用大概是原来的 4 倍workers412Windows 建议 24Linux 可以拉到 812。设太高会造成数据加载线程卡死表现为训练进度条半天不动patience1520监控数据量大设 5 容易早早停下设 30 又浪费时间。15 是比较平衡的值imgsz 这个参数是监控场景的胜负手。640×640 下一个高度占画面 10% 的行人只有 64 像素高YOLOv8 的检测头虽然能处理但特征提取阶段很容易把它和背景纹理混在一起。切到 1280×1280同样的行人变成 128 像素特征区分度直线上升。代价是显存占用大幅增加显存不够就降 batch或者用 960 这个中间档。workers 的坑比较隐蔽。很多人为追求速度把 workers 拉到 16结果程序直接卡在第一个 epoch 加载数据看起来像是死机了。这是因为 Windows 下多进程数据加载有保护机制worker 进程数超过 CPU 核心数后会互相竞争。我一般先用默认值跑一个 epoch确认数据加载流畅再逐步往上加。4.4 训练中看什么loss 曲线与 val 指标别只盯 mAP训练启动后终端每秒刷屏新手容易盯着 mAP 看一整天。我习惯每隔五个 epoch 看一次三件套box_loss、cls_loss、dfl_loss以及每轮的 mAP50 和 mAP50-95。mAP50 高于 0.8 只能说明大目标检得好监控场景真正要看 mAP50-95这个指标对边界框精度更敏感小目标一框偏就掉分。还有一个容易忽视的指标是分类损失和定位损失的相对大小。box_loss 降得很慢、cls_loss 早就收敛说明模型“知道人在哪里但框不准”优先调 imgsz 或锚框设置反过来 cls_loss 居高不下说明类别特征区分度不够先查类别标注一致性。训练结束后在 runs/detect/train 目录下会生成混淆矩阵、PR 曲线、验证集预测样例图。我每次都会把 PR 曲线放大看低置信度区间置信度 0.1 附近如果召回率已经开始明显下滑说明模型对低质量目标不够敏感部署时要考虑调低置信度阈值代价是误检增多这个 trade-off 要在测试集上拉一遍曲线再定。5. 监控行人训练避坑五条血泪经验监控数据集训练踩过的坑很多问题不是模型结构不行而是数据链路里的小细节。这里挑五条最典型的记录每条都是现象、原因、解决三段式希望能帮你少走几次弯路。5.1 连续帧抽帧造成的“数据泄漏”验证集虚高现象训练时 mAP50 冲到 0.87验证集看着很漂亮一接到陌生监控点位效果直接掉到 0.4 左右。原因数据是从两段连续视频里抽的帧抽帧间隔太短验证集和训练集里存在大量近乎重复的帧。模型等于“背过”了验证场景泛化能力自然虚胖。解决抽帧时把间隔拉大到每秒 1 帧再做感知哈希去重划分时按摄像头或时间段分组一组整体进训练另一组整体进验证。宁可训练集少一点也要保证验证集完全没见过的场景。5.2 class 文件与 data.yaml 顺序错位类别全靠蒙现象模型训练 loss 正常但部署后把行人预测成了自行车把汽车预测成了行人输出类别完全对不上。原因class.txt 和 data.yaml 里的类别顺序不一致两个文件的行号错位模型学到的类别 ID 和实际含义对不上。解决训练前把 class.txt 和 data.yaml 放在同一个目录写一个脚本逐行对比二者确认顺序完全一致。改过任何一个文件后立刻检查 labels 里对应的类别 ID 是否有越界值。这个坑最容易出现在“从多类数据里裁剪单类”的场景删除其他类别后忘了重映射 ID。5.3 BN 崩溃小 batch、高学习率加小目标loss 直接变 NaN现象训练到第 50 轮左右loss 曲线像心电图一样突然跳高再往后直接变成 NaN进度条也不动了。原因batch size 设太小BN 层的均值和方差统计不稳定学习率设得太高让 BN 层在几次迭代里被推到数值溢出。监控数据里小目标多特征图响应偏弱放大了这种波动。解决batch 至少 16遇到显存不够就降 imgsz 而不是降 batch把初始学习率从默认的 0.01 降到 0.001让 BN 统计先稳定下来确认开了 warmup 并跑满前三个 epoch。目标检测模型微调崩了八成逃不出这几个原因。5.4 小目标漏检imgsz 640 困住了三米外的行人现象训练指标和验证指标都正常拿到实拍视频里一看远处的行人三米外就丢了框走近了才检测出来。原因监控视角的行人目标高度占比经常只有 5%640×640 输入下大约 30 像素高特征经过几次下采样后只剩几个像素的响应。解决训练和推理都用更大的分辨率先试 960再看显存决定是否上 1280。这么做 train 时间会长一倍左右但对小目标的收益非常直接。如果换了大分辨率还漏那要把画面切块推理或者用专门的小目标检测头配置。5.5 混淆矩阵行和不等于 1别把它当 bug 修现象训练完看 confusion_matrix.png发现每一行的数字加起来不是 1.0有人以为是归一化 bug试图手动修复。原因YOLO 绘制混淆矩阵时每一行会单独归一化同时背景列单独计算所以行和不为 100% 是正常现象不是代码问题。解决不看行和只看对角线数值和背景列。对角线数值高说明对应类别检得好背景列数值高说明误检严重模型把大量背景当成了目标。监控场景尤其要看“person 被误检为背景”这一格那代表漏检。只要分布符合预期就不用管行和。6. 最后一招留一条独立视频流验证夜间与俯视效果训练结束不等于项目结束。我每个监控项目都会留一条单独的技巧拿一段“没参与过训练、没参与过验证”的原始监控视频做二次验证而且是按时间抽完整的一天从早到晚、含夜间红外画面。只有这条视频上的表现才是你真实要交付的效果。复现方法很简单训练完成后跑一条预测命令yolo predict modelruns/detect/train/weights/best.pt \ sourcenight_intersection.mp4 \ conf0.25 \ save_txtTrue \ save_confTrue对着输出结果我会手动标记三种 bad case完全漏检的行人、框偏到两个行人之间的误检、置信度高但类别错误的硬误检。这些 case 全部回收进训练集补一轮增量训练比闷头调损失函数权重有效得多。夜间场景如果漏检严重先在训练配置里把亮度、对比度增强的幅度调大再用夜间帧做二次增强很多情况下能救回一半以上的漏检。我的习惯是每次训练前先想清楚“这次验证用哪段视频”而不是“这次调什么超参”。验证集选对了参数调得才有意义验证集选错了所有调参都是自我安慰。希望这篇笔记能让你把监控场景的 YOLO 行人检测这条链路一次走通少交点学费。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。