做行人车辆检测这个方向有些年头了。早几年提到“智能交通”“园区安防”,多数人的第一反应是找AI公司买现成方案,价格高不说,后期算法迭代还得看别人脸色。现在我自己更倾向于直接用YOLO系列模型搭建一套可落地的“行人车辆智能检测系统”——就是这个《人车识鉴》项目:输入端接摄像头或视频流,输出端实时框出画面里的行人和车辆,给出类别与置信度,再联动业务做统计、告警、轨迹分析。它适合安防监控、智慧交通、车路协同、校园园区管理等场景,也适合所有想把目标检测真正部署到实际视频流中、而非只停在demo层面的开发者参考。
这篇文章我会把项目的完整链路拆开来讲:从需求分析、数据准备、模型训练,到推理速度对比和工程部署,中间穿插大量实操中踩过的坑和排查思路。如果你正好在看YOLOv5和YOLOv26之间怎么选,或者训练完模型后发现有漏检误检不知道怎么调,这篇应该能给你一份可复制的参考答案。
1. 项目需求与技术选型:行人车辆检测为什么不能只靠“效果好”
1.1 核心需求解析
在做任何检测项目之前,先把需求聊透是最高优先级的工程动作。《人车识鉴》的核心需求其实很清晰:在固定或移动摄像头画面中,对行人和车辆两类目标进行实时定位和分类。但“实时”和“准”这两件事在工程上经常打架。
场景不同,侧重点完全不同。比如单向车道的卡口监控,车辆目标占画面主体,行人往往只是背景局部,这时候模型的检出压力主要在车辆;而园区人行道场景恰好相反,行人可能会被树干、路灯、机动车局部遮挡,目标形态多变。所以我在最开始就把需求拆成了三个约束维度:检测精度、推理速度、部署成本,然后才去选模型。这个顺序不能反——先定需求再选型,而不是看到新模型就往上套。
另一个容易被忽视的点是“持续运行”要求。监控场景的摄像头一年365天不关机,这意味着模型不仅要准,还要稳,不能出现偶发的大面积漏检。所以我在方案里把“模型鲁棒性”放在和“精度”同等重要的位置,这也直接影响后面的数据增强策略和模型阈值设计。
1.2 为什么选YOLO系列而不是两阶段检测器
行人车辆检测在技术路线上有好几个选择:传统HOG+SVM那一套早就不满足精度要求了,属于可以跳过不谈的考古内容;两阶段的Faster R-CNN、Cascade R-CNN在精度上有优势,但在实时视频流场景里,单张图片动辄几十毫秒甚至上百毫秒的推理耗时,多路摄像头并行时算力成本会直接爆炸。工业落地优先考虑的是“摄像头路数×单路帧率”这个综合指标,一阶段检测器的速度优势是压倒性的。
YOLO系列在工业界受欢迎不单是因为快。它的工程生态成熟:从标注数据到训练脚本、再到导出ONNX/TensorRT,工具链几乎是一条龙。对于我这种经常要快速验证想法的人来说,YOLO系模型的开箱即用程度,远比很多论文里的SOTA模型高。它把“把模型跑起来”的成本降到了极低,这本身就是生产力。
《人车识鉴》选YOLOv26,除了它作为系列新版本在精度与速度上的进一步平衡,更重要的是它延续了YOLO生态的打包方式,迁移成本低。项目里我从YOLOv5迁移到YOLOv26,训练脚本、数据格式基本无缝切换,这种生态兼容性在技术选型里是很关键的隐性优势。
1.3 行人车辆检测的难点与应对思路
行人车辆检测表面上看只有两个类目,实际做起来比想象中复杂。行人目标形态变化大,站立、弯腰、奔跑、骑电动车,外观差异极大;车辆则有轿车、卡车、公交车、自行车、三轮车等不同形态,同类别内差异也不小。
另外还有几个硬骨头:小目标密集场景(十字路口远处的人群、车辆)、目标遮挡(行人被车辆遮挡、车辆被树荫覆盖)、光照剧变(逆光、夜间、炫光)。这些问题不是单靠换一个更大的模型就能解决的,而是需要从数据、增强、推理后处理多个层面协同优化。
项目里我确定了一条核心应对思路:以YOLOv26为基线模型,在数据层面做针对性增强,在训练策略上通过分阶段调节解决类别不平衡,在推理端设计带面积筛选的NMS后处理。后面几节我会分别展开,把这套组合拳的细节讲清楚。
2. 数据准备:决定模型上限的隐藏工程
2.1 训练数据集的选择与整合
很多新手上来就急着写训练脚本,实际上一个检测模型的效果天花板,很大程度在数据阶段就定死了。行人车辆检测没有特别大的公开“人车双类”专用数据集,所以我的做法是整合多个公开数据集,再补一部分自采数据。COCO的person类、车辆相关类可以用,但类别标签需要重映射;UA-DETRAC在交通监控场景下表现不错,车辆密集而且有遮挡;还有CrowdHuman,虽然主打人体检测,但对行人形态覆盖很全。
整合时最重要的一步是清洗。不同数据集的标注风格、边界框定义不一样,有的框全身,有的框可见部分,如果不加处理直接混训,模型会学出很奇怪的框偏好。我统一把行人标注定义为“全身可见部分的外接矩形”,车辆标注定义为“车身主体外接矩形,含后视镜但不含明显突出物”。数据清洗阶段我写过一段小脚本,批量检查不同数据集的标签分布和框尺寸分布,把明显错误的标签挑出来人工复核。
整合之后的数据规模大约8万张图,其中行人目标约20万个,车辆目标约15万个。光有数量不够,还要看分布。我统计了目标宽高比和面积分布,发现小目标占比很高——小于32×32像素的目标占了接近三成,这也是训练阶段需要专门处理小目标的直接依据。
2.2 标注规范与类目平衡
类目只有“person”和“vehicle”两类,听起来简单,但标注规范不提前定,后续会出各种奇葩问题。我定了几条硬性规则:
- 被遮挡超过70%的行人/车辆不标,避免模型学到大量无意义的局部特征。
- 镜面反射里的目标不标,那是训练噪音。
- 车辆类别统一,不细分轿车、卡车、公交车,原因是当前业务只关心“有无车辆”,细分反而会拉低整体精度。
类别平衡方面,行人目标数比车辆多,如果直接训,模型容易偏向行人。我的处理方式是在损失函数里给车辆类适当加权重。具体在YOLOv26配置里调整cls_loss的类别权重,让车辆类的损失权重略高于行人,平衡两个类别的梯度贡献。这个操作幅度要小,通常加0.1~0.2就够,加太猛会把行人的召回率拉下来。
2.3 数据增强策略:多算力换鲁棒性
数据增强是成本最低的鲁棒性来源。YOLOv26内置了Mosaic增强、随机仿射变换、HSV色域扰动、MixUp等,但默认策略不能无脑开全,尤其是Mosaic。
Mosaic把四张图拼成一张,好处是小目标数量变多、上下文信息丰富,坏处是训练后期如果一直用,模型会对拼接边界产生依赖。我的策略是训练前80个epoch开启Mosaic,最后20个epoch关闭,让模型回归到正常分布的图片上做精调。这个细节在多个YOLO项目里都验证过,能明显降低验证集上的边界框抖动。
针对行人车辆场景,我还额外加了两种增强:随机遮挡模拟(Random Erasing)和亮度对比度扰动。随机遮挡模拟能模拟行人被树木、车辆局部遮挡的场景,亮度扰动则提升了对逆光、傍晚光线的适应能力。这些增强在YOLOv26的训练配置里都有对应参数项,也可以自己在数据加载器里写,但先用内置的够用。
注意:数据增强不是越狠越好。我在调试时曾把HSV饱和度扰动范围开到0.9,结果验证集精度掉了近2个点。原因是在夜间监控画面中,色彩分布本来就偏暗,过度增强让模型学到了不真实的颜色分布。一般饱和度扰动在0.5左右比较合理。
2.4 数据划分:验证集是模型的“照妖镜”
数据划分看起来是常规操作,但如果划分不合理,后面所有指标都会失真。我的做法是:先按视频片段分组(同一个视频的帧只进训练集或只进验证集),再按8:1:1划分训练、验证、测试集。这样做避免了同源视频帧的数据泄露。
另外我会单独准备一个“困难集”,专门挑那些隧道入口、雨夜、强逆光、行人密集遮挡的图片。这部分数据不参与训练,只在最终评估时使用。模型在常规验证集上可能都到95%的mAP了,但在困难集上往往会掉到80%以下,这个差距才是真实落地时你会感受到的差距。所以我特别建议做检测的朋友都给自己建一个困难集,它比任何训练曲线都能暴露问题。
3. 从零训练YOLOv26:配置、调参与踩坑实录
3.1 环境准备与依赖安装
训练环境这块没什么玄学:一张显存够大的卡,CUDA、cuDNN、PyTorch版本对得上就行。我用的是单张RTX 4090训练,显存24GB,YOLOv26默认输入尺寸640×640,batch size可以开到32左右。
环境搭建有个容易踩的坑是版本兼容。PyTorch版本、CUDA版本、GPU驱动版本三个之间如果搭配不当,训练过程中会出现莫名其妙的CUDA error。我的建议是不要追赶最新版本,直接用官方推荐的组合。安装完依赖后先用官方预训练权重跑一次推理,确认环境正常再开始训练,这一步能省下很多排查装环境的时间。
依赖安装可以用官方给的requirements文件,创建虚拟环境后一次性装齐。我这里贴一下常用的操作,不限定版本号,大家按自己环境匹配:
pip install -r requirements.txt python -c "import torch; print(torch.cuda.is_available())"如果输出True,说明环境基本没问题。
3.2 训练配置的核心参数
YOLOv26的训练参数虽然多,但真正影响命脉的就那么几个。我用的是官方默认的数据格式,在data目录下准备yaml文件指向训练集和验证集路径,然后写一个train.yaml,里面主要调以下参数:
- model: 选择模型规模。项目里选了中等规模的配置,兼顾精度和速度。如果算力紧张,也可以选轻量版本,但行人密集场景下轻量版漏检会明显增多。
- epochs: 我设为300。对这个数据量级,300个epoch足够收敛,太少欠拟合,太多容易过拟合。
- batch-size: 32。
- imgsz: 640。输入尺寸不是越大越好。之前试过960,小目标检出确实更准,但推理速度慢了一半,对视频流实时性不友好。640是监控场景里比较折中的值。
- patience: 早停机制,设为50。如果连续50个epoch验证集指标不提升,自动停止,省时间。
训练启动命令大致如下:
python train.py --data data/people_vehicle.yaml --weights yolov26.pt --batch-size 32 --imgsz 640 --epochs 300 --device 0这里的“yolov26.pt”是预训练权重。用预训练权重做迁移学习,比从零训练收敛快得多,而且最终精度通常更高。
3.3 训练过程的监控与判断
训练不是一键跑完就完事,实时监控曲线才能及时发现问题。我主要看两个东西:一个是训练集和验证集的loss曲线,另一个是验证集的mAP曲线。
Loss曲线正常应该是在前几个epoch快速下降,然后逐渐趋于平缓。如果训练loss持续下降但验证loss回升,那是过拟合信号,可以提前停止或加大数据增强。如果训练loss和验证loss都下不去,卡在很高的位置,先检查数据标签是否有错,再考虑是不是学习率太大或太小。
YOLOv26默认配置里自带学习率自动调度。我在项目里观察到,前20个epoch是loss下降最快的阶段,到100个epoch以后,mAP的提升变得非常缓慢,每10个epoch可能才涨0.1~0.2个点。这种时候不要焦虑,那是模型在精调边界框回归头,属正常现象。
训练过程中每隔一段时间我会在验证集上随机抽一批图片,可视化检测结果。看可视化比看数字更直观:框的位置是否贴合、漏检的目标长什么样、误检的类型是什么。这一步能帮你直观发现数据标注阶段遗留的问题,比如某个场景下大量行人没框出来,很可能训练集里这种姿态的行人数量太少。
3.4 调参实战:欠拟合、过拟合与学习率
训练完第一版模型后,大概率不是一次到位。我遇到的第一个问题是有轻微过拟合——训练集上的置信度很高、loss很低,但验证集mAP只有82%左右。排查下来有两个因素:一是数据量还不太够,二是某些增强在后期没有关掉。
处理方法是在训练后段冻结backbone,只fine-tune检测头。YOLOv26里可以设置冻结参数,这样模型对图像底层特征的改动变小,更加专注于任务本身。另外一个技巧是给大模型加一点weight decay。从默认的0.0005调整到0.001,略微改善了过拟合。
还有一次遇到学习率问题。前30个epoch的loss下降极其缓慢,后来检查发现是初始学习率设小了。YOLOv26的默认学习率一般够用,但如果用了自定义优化器配置,要注意基础学习率是否匹配。我后来直接初始化后先跑20个epoch观察,如果loss下降太慢,就把初始学习率乘2到3倍重跑。这是最省时间的试探。
4. 推理速度对比与工程优化:YOLOv5和YOLOv26怎么选
4.1 YOLOv5与YOLOv26的推理速度理解
很多人搜YOLOv5和YOLOv26推理速度对比,其实想知道的就是“新版本值不值得升级”。我拿同一个数据集、同一张测试卡分别部署了YOLOv5中模型和YOLOv26中模型,比较结果有一个比较直观的判断维度:在输入尺寸640×640、TensorRT FP16精度下,YOLOv26的推理速度与YOLOv5基本持平,但检测精度在行人车辆这类场景下高出3%左右。也就是说,新版模型用接近相同的算力,换来了更准的结果,这笔账是划算的。
但要注意,推理速度这个指标不能只看模型名字。实际影响延迟的因素还包括:是否开启TensorRT、是否使用FP16/INT8量化、batch是否合并、输入分辨率多大、是否做了frame skip。同一个模型在不同优化配置下,速度可以差出3到5倍。
YOLOv5在工程界的存量巨大,它的优势是稳定、资料多、踩坑经验丰富,而且对于一些轻量级边缘设备,YOLOv5n或YOLOv5s的部署方案已经非常成熟。如果你的设备算力极低、场景相对简单,沿用YOLOv5是完全合理的。但如果你在做一个对精度有一定要求的新项目,且算力不是极其紧张,直接上YOLOv26是更面向未来的选择。
4.2 模型量化与TensorRT部署
训练好的PyTorch模型直接用来做视频流推理,速度是远远不够的,必须走部署优化一环。
我的标准流程是先导出ONNX,再转TensorRT engine。YOLOv26官方的导出脚本已经支持这些格式,但有几个细节值得注意。
导出ONNX时,我设置了--simplify做图优化,减少冗余算子。同时--opset版本要和TensorRT支持范围匹配。转换TensorRT时,FP16是绝大多数场景的首选——精度损失在1%以内,但推理速度能比FP32快一倍。INT8虽然更快,但需要校准数据集,且在小目标密集的行人检测场景中,精度波动较大,我一般不轻易用。
转换后的实测数据是:单张640×640图像在RTX 3060上的TensorRT FP16推理延迟约8~10ms,在Jetson Orin Nano上约18~22ms。这个速度跑25帧每秒的视频流完全够用。如果有多路摄像头需求,可以进一步把多路视频帧拼成一个batch做批推理,能显著提高GPU利用率。
提示:部署时一定要把图像的预处理(缩放、归一化)也写进推理管线里,不要在Python端做逐帧的base64转换和resize。我之前在Jetson上部署时,光图像预处理就占了整个管线一半的耗时,后来把resize和归一化都合并成一个CUDA预处理算子,端到端延迟直接下降了30%。
4.3 部署硬件选型建议
硬件选型取决于你面向的落地场景。如果是中心机房服务器部署,一颗中端GPU(如RTX 3060及以上)即可稳定跑4~6路720P视频流;如果是边缘盒子部署,Jetson Orin Nano/Orin NX是性价比不错的选择,功耗低、算力够用。
另外推荐把检测结果通过MQTT或RTSP回传,这样业务端可以做实时告警和统计分析。我在《人车识鉴》里的做法是:检测服务只做检测,把结构化结果(目标类别、坐标、置信度、时间戳)封装成JSON推给下游消息队列,由独立业务服务负责告警、统计和界面展示。解耦之后,检测服务的吞吐量和稳定性都大幅提升。
5. 常见问题与排查技巧实录
5.1 小目标漏检怎么破
行人车辆检测最典型的问题是远处的小目标漏检。小目标在640×640输入下可能只有十几个像素,特征信息本来就稀缺,模型很难兼顾大目标和小任务。
排查思路分三步。第一步,确认是不是输入分辨率太低,适当提升imgsz到960往往立竿见影,但代价是速度下降,需要权衡。第二步,检查训练集中小目标的数量和标注质量,如果小目标占比过低,模型学不好是必然的。第三步,调低推理时的置信度阈值,从0.25降到0.15,通常能找回一些低置信度的漏检目标,但要配合NMS阈值调整,否则误检会增多。
我还用过一种trick:在推理端做多尺度测试(multi-scale inference),对同一帧图像分别用640和960尺寸推理,再合并结果。这个方法能明显提升小目标召回,但推理时间接近翻倍,适合离线分析场景,不适合实时视频流。
5.2 误检、遮挡与目标形态变化
误检频发的核心原因是模型学到的特征不够“判别性”。比如把路灯杆的影子当成人,把路牌当成车,这种场景通常需要回到数据层面补“负样本”。
我在项目里专门收集了一批不包含行人和车辆的纯背景图,加入训练集,并在训练配置里让模型学习“背景”类别。同时提升了NMS的IoU阈值,从默认的0.45调高到0.5,减少重叠框的误保留。遮挡问题则通过放宽检测框的宽高比设定来缓解,因为行人被车辆遮挡时,检测框会变得很窄或很扁,约束太严格容易丢目标。
5.3 夜间与恶劣天气的鲁棒性
模型在白天表现良好,到夜间就崩——这个问题在监控场景几乎必现。我在数据增强里专门加了亮度增强和噪声模拟,还从开源夜景数据集中抽了一部分夜间图像做fine-tune。
效果最明显的是加了一个简单的“low-light增强”逻辑:训练时对部分图像做Gamma校正,模拟暗光环境。这个操作不需要额外数据,纯粹是数据处理层面的事。最终夜间场景的mAP从76%提升到83%,虽然还是不如白天,但至少能用了。
5.4 常见问题速查表
| 现象 | 可能原因 | 处理建议 |
|---|---|---|
| 训练loss不下降 | 学习率过小;数据标签错乱 | 调大初始学习率;抽样检查标签 |
| 验证集mAP偏低 | 过拟合或数据分布单一 | 冻结backbone fine-tune;增加数据增强 |
| 小目标漏检 | 输入分辨率低;小目标样本少 | 提高imgsz;补充小目标数据 |
| 夜间误检多 | 训练数据缺乏暗光样本 | 增加亮度扰动;加入夜间数据fine-tune |
| 推理速度慢 | 未启用TensorRT/量化 | 转ONNX/TensorRT,用FP16 |
| 多路视频卡顿 | 单帧推理逻辑阻塞 | 用batch推理;接入消息队列解耦 |
6. 项目落地的一些实在经验
最后分享几个项目结束后沉淀下来的体会,不扯虚的。
最核心的一点:训练出一个高mAP的模型并不是项目终点,稳定地跑在真实环境里才是。《人车识鉴》上线初期,模型在演示视频里效果惊艳,但接到真实摄像头流后,因为现场光照、角度和训练分布差异巨大,前两周的漏检率明显偏高。我当时的应对是建立了一套“线上数据回流”机制——把推理中置信度很低但实际有目标的帧抽样保存下来,人工复核后定期补充进训练集做增量训练。两轮迭代之后,真实场景的精度才追上来。做检测项目的人,我建议从一开始就预留这个流程,不要等上线了再补。
第二个体会是版本升级要理性看待。YOLOv26作为新版本,确实带来了更高的精度上限和更优的部署体验,但如果你现有的YOLOv5模型在场景里已经跑得很稳,业务目标也都能满足,那强行换版本的意义不大。技术选型永远服务于需求,不是为了追新而追新。反过来说,如果你正好要启动一个新项目,直接选用当前生态成熟、社区活跃的最新版本,是降低长期维护成本的合理决策。
另外,我个人在做这个项目后养成了一个习惯:每个阶段的实验都要留档。哪个数据集、哪个增强配置、哪个超参数,对应的验证集mAP是多少,记录下来。这个习惯在你后续调参或复现实验结果时,能节省大量时间,因为很多问题不是“方法不对”,而是“记不清上次是用什么跑出来的结果”。
《人车识鉴》这个项目目前已经能稳定支撑园区场景下的实时人车检测与统计功能,后续我还在规划加入多摄像头跨镜追踪和轨迹热力分析。如果你正在做类似的方向,或者对行人车辆检测有自己的一套玩法,欢迎交流。工程这条路,永远是动手做一遍比看十篇文章更有效。