
简介面向红外场景下车辆与行人检测的YOLOv7解决方案采用PyTorch框架包含训练好的权重、数据集与配套代码适合目标检测研究者、算法工程师及需要快速落地红外检测的开发者。模型基于数千张红外图像训练输入尺寸640×640mAP达到90%以上检测目标为car与person数据集标签提供txt和xml两种格式便于分别用于YOLO与VOC训练流程。压缩包共166个文件涵盖Python脚本、yaml配置、Jupyter Notebook演示、pt权重、txt/xml标签、jpg/png图像等整体约444.56MB并附Dockerfile与shell脚本便于环境搭建与运行。已有1268人学习。除了可直接使用的权重还包含PR曲线、loss曲线等训练过程记录以及TensorRT与ONNX Runtime相关notebook和配套博客说明方便复现实验、结果分析或迁移到自有红外数据继续训练无论用于算法学习、论文实验还是工程预研都有直接参考价值可作为红外目标检测项目的起点。 红外场景下的目标检测这两年问的人越来越多。原因很直接普通摄像头一到晚上就成了半个瞎子而红外成像完全不依赖可见光夜里、雾天、强逆光都能稳定输出画面。可问题也随之而来——拿现成的YOLOv7权重直接去跑红外图效果通常惨不忍睹。这不是YOLOv7不行而是训练它的人喂的是可见光数据。红外图像只有单通道灰度信息目标和背景的对比度逻辑跟可见光根本不是一回事。这篇文章就围绕YOLOv7在红外场景下做车辆和行人检测这件事把数据集准备、权重训练、推理部署这条链路完整梳理一遍。无论你是刚接触红外的初学者还是已经被红外数据折磨过几轮的开发者这篇内容应该都能给你省下不少踩坑的时间。1. 红外场景检测的真正痛点不是模型不行是输入不一样1.1 红外图为什么难倒一堆“效果很好”的预训练权重很多人第一次拿到红外视频第一反应是直接用YOLOv7官方预训练权重跑一下。结果往往是行人漏检、车辆框漂移、甚至把路灯当成人。原因在于红外图像和可见光图像之间存在几个本质差异。先说通道数。红外图像传感器输出的本质是热辐射强度分布图绝大多数情况下是单通道灰度图。而网上能下载到的YOLOv7预训练权重输入要求是三通道RGB。直接把单通道图复制成三通道喂进网络算法看到的其实是同一份灰度信息重复搬运模型从可见光数据里学到的色彩纹理特征完全派不上用场性能自然会崩。再看对比度和纹理。可见光图像里车辆和行人通常有丰富的颜色、阴影、边缘纹理算法能借助这些“外观线索”做判别。红外图像则不同它记录的是物体表面温度差异车辆引擎盖热、轮胎冷行人头部和躯干温度高、四肢相对低整个目标在画面里呈现出一个亮度不规则的“热斑”。目标内部缺少细节纹理轮廓模糊并且和周围环境的热辐射容易发生混淆——夏天路面温度高车辆底部阴影区域反而不热冬天人体温度与建筑物外墙温差巨大红外图里人像发光一样刺眼。这种种非线性的特征差异决定了可见光权重基本不可能直接迁移到红外场景。1.2 摸清两类红外场景任务再决定要不要自己训练红外目标检测需求大致分为两类一类是安防监控和辅助驾驶里最常见的地面场景目标就是行人和车辆镜头固定或车载平台运动背景相对可控另一类是高空或航拍视角比如无人机吊舱里安装红外载荷在几百米高度往下看地面车辆和行人目标尺寸小、背景复杂、运动轨迹混乱。你的标题对应的是第一类地面红外场景处理起来相对成熟公开数据集也比较多完全值得自己训练一版专用权重。这里有一个判断基准如果你拿可见光预训练权重跑红外图mAP掉到在可见光上的一半以下那就别指望靠调阈值和图像后处理来补救老老实实准备数据、重新训练。这不是玄学是特征分布发生了根本性偏移治本的办法只有让模型见过足够多的红外样本。2. 数据集怎么搭公开数据够用吗自建数据要注意什么2.1 公开红外数据集盘点训练任何模型数据先行。红外车辆和行人的公开数据集其实比想象中多但分布零散很多人找不到。这里把我实际用过的几个列出来数据集规模特点适用场景FLIR Thermal Dataset约1万张标注图像14000多个框车载红外相机涵盖白天、夜晚、黄昏类别有行人、车辆、自行车最接近真实车载红外检测需求KAIST Multispectral Benchmark可见光与红外成对数据白天夜晚全覆盖带对齐的RGB和热成像对支持双模态研究需要做多光谱融合的进阶玩法OTCBVS Benchmark多个子集规模较小经典红外行人数据集标注质量高适合算法研究和效果对比入门验证、学术实验LLVIP约3万张红外-可见光对齐图像对已有训练/验证划分专为夜间低光行人检测构建识别目标以行人和骑车人为主夜间监控场景行人检测为主的项目如果你做的是纯红外车辆和行人检测FLIR是我的首选。它的标注格式为COCO JSON格式官方划分了训练集和验证集拿过来可以直接转成YOLO格式使用。KAIST虽然名气大但它的标注文件是老式MATLAB格式转换起来稍费一点功夫不过胜在提供了配套的可见光图后面如果你想做“可见光红外”的双模态融合这组数据相当有价值。另外提一句dmsd船舶红外可见光双模态数据集。虽然它的目标是船舶检测不是车辆行人但它的数据组织思路——同一场景下红外图和可见光图进行像素级对齐——很值得借鉴。如果你未来想把红外检测从地面安防扩展到水面监控比如港口巡逻、内河航道管理这种双模态对齐的组织方式能帮你少走很多弯路。2.2 自建数据集的关键处理环节公开数据通常只能解决“从无到有”真实部署时你面对的环境大概率跟数据集分布不一样这时候自建数据是必经之路。自建红外数据集时我有几个切身教训要提醒你。首先是采集设备的标定。红外镜头和可见光镜头在硬件上是两套系统如果后续要做双模态对齐必须先做联合标定否则画出来框的偏移量随着距离增加会越来越大最后根本无法使用。哪怕你只做纯红外检测也要保证红外镜头的画面不能有严重畸变尤其是边缘区域的目标形变会直接拉低小目标的检测效果。其次是标注原则要和可见光数据集区分开。红外图像中行人有时被雨伞、背包遮挡导致热量特征不完整夏天车辆熄火后车身温度与环境温度接近轮廓若隐若现。标注时需要有一套明确的规则可见光中“看轮廓”就能标注的红外里一定要结合热辐射特征判断宁可漏标一个模棱两可的目标也不要带着错误标签训练否则模型会学到“这种模糊区域随便框一下也行”的错误逻辑。数据增强方面我建议在红外任务里适当加大Mosaic和MixUp的使用概率。红外图像的整体对比度经常偏低而且单场景的画面重复度高不做强增强很容易过拟合。但要注意红外图像的亮度反转热白冷黑变成热黑冷白本身也是一种数据增强方式如果设备支持切换极性建议直接在代码里加一个随机反转的预处理分支能显著提升模型的泛化能力。3. 训练前的关键准备环境、配置、anchors一个都不能少3.1 环境安装与数据组织YOLOv7的环境安装相对友好要求在PyTorch 1.7以上的环境里运行建议直接用PyTorch 1.12搭配CUDA 11.x兼容性最稳。项目克隆下来之后核心依赖就是opencv、pyyaml、matplotlib、numpy、tqdm这几个直接pip安装即可。数据组织要按YOLO的目录规范来拿FLIR数据集举例转完格式之后的目录结构长这样datasets/ ├── infrared/ │ ├── images/ │ │ ├── train/ │ │ └── val/ │ ├── labels/ │ │ ├── train/ │ │ └── val/ │ └── infrared.yaml说明一下images目录放红外原图labels目录放对应的txt标注文件每一行格式为class_id x_center y_center width height全部归一化到0~1之间。FLIR原始COCO标注里类别比较多做车辆和行人检测时建议只保留person、car、truck、bus这几个类别其余类别要么合并要么直接删掉减少干扰。3.2 修改yaml配置文件与anchor计算数据集准备好之后首先修改infrared.yamltrain: datasets/infrared/images/train val: datasets/infrared/images/val nc: 2 # 或者按你的类别数量写比如person和car为2类 names: [person, car]然后是anchors的重新计算。这是很多人跳过但恰恰最关键的一步。YOLOv7默认anchors是基于COCO数据集的COCO里面小目标成千上万而红外场景的目标尺寸分布通常集中在中等尺度小目标的比例明显偏低。直接用默认anchor训练模型在预测框回归阶段会白白浪费大量参数去适配一个不存在的尺寸分布。用项目自带的工具重新算一下python tools/anchors.py --data cfg/infrared.yaml --img_size 640 --batch_size 8命令跑完会输出9组新anchors把它填到cfg/training/yolov7.yaml的对应位置。我实测在FLIR数据集上重新计算anchor后小目标召回率能提升2~3个百分点这属于纯数据驱动的白送收益。如果用的模型结构是yolov7-tiny体积更小、更适合嵌入式部署同理修改cfg/training/yolov7-tiny.yaml。注意tiny版本的层数较浅如果红外目标特别小建议把输入分辨率从默认的640提升到768代价是推理速度略降但小目标检测的收益通常很可观。3.3 预训练权重和训练参数的选择逻辑关于预训练权重比较稳妥的做法是直接使用YOLOv7官方在COCO上训练好的yolov7_training.pt作为起点。虽然前面说过可见光权重的特征跟红外不匹配但底层卷积层提取的通用边缘、轮廓、形状信息仍然是可迁移的重新训练时这些通用特征可以加快收敛。不需要担心“域偏移太大导致迁移失效”实际训练里加载COCO权重比从头训练在初期收敛速度上快得多一般能快40%左右的epoch数。训练超参数同样值得细说。建议batch size设为8或16初始学习率0.01配合cosine学习率调度。红外数据集不像大规模可见光数据集那么大如果loss在某个epoch附近波动明显优先考虑降低学习率而非增加epoch。4. 训练实战跑起来容易判断好坏才是本事4.1 训练命令与loss解读一切就绪后用下面这条命令开始训练python train.py --workers 8 --device 0 --batch-size 8 --data data/infrared.yaml --img 640 640 --cfg cfg/training/yolov7.yaml --weights yolov7_training.pt --name yolov7_infrared --hyp data/hyp.scratch.p5.yaml --epochs 150训练过程中重点盯三个指标box_loss、obj_loss和cls_loss。红外图像的objectness loss通常降得比可见光慢原因是红外目标与背景的对比度差异不稳定模型需要更多轮次才能把“热斑”和“噪声”区分开。如果你发现obj_loss在前50个epoch已经降得很低但box_loss还在高位徘徊大概率是anchor没算准回去重新检查第3节。我从实操经验里给个参考范围在FLIR数据集上训练最终box_loss大致降到0.04以下obj_loss降到0.01以下cls_loss接近0模型的检测效果基本就能满足多数安防场景的实用要求了。4.2 从val结果里读出模型的真实水平训练结束后模型会自动保存best.pt和last.pt并输出验证集的mAP结果。很多新手只看mAP这个数字其实这里有坑。FLIR数据集中“车辆”这一类包含轿车、卡车、巴士等多个子类当车辆和行人混在一起时如果车辆这一类的AP明显低于行人说明模型把不同尺寸的车辆特征学混了需要检查数据集里轿车的框是否被标注得太少。此外还要单独看置信度阈值下的precision和recall曲线红外场景比较容易出现“精度高但召回低”的假象——模型只检测出那些亮度对比明显的目标暗弱目标全被漏掉了这在夜间监控里很难接受。调整策略通常是降低confidence阈值到0.150.25用更多的候选框换取召回率后面再用NMS把重叠框收敛掉。5. 检测权重的部署与推理调优5.1 推理脚本里的红外图像预处理训练完得到权重之后下一步是部署。很多人在训练阶段表现不错一上真实场景就掉链子问题往往出在推理时没有做和训练一致的预处理。YOLOv7的推理路径中读入图像后会做letterbox缩放、归一化再送进网络。对于红外图像我强烈建议在送入模型之前增加一步对比度增强。红外图像的像素分布经常集中在一个很窄的灰度区间内直接归一化会让模型看到一张“灰蒙蒙”的图。用CLAHE限制对比度自适应直方图均衡做预处理效果提升非常明显import cv2 def preprocess_infrared(img): # img为单通道红外灰度图 clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8, 8)) img clahe.apply(img) # 转为三通道保持与模型输入一致 img cv2.merge([img, img, img]) return img注意clipLimit不要设置太大否则会把红外噪声也一并放大产生大量伪目标。2.0是我试过最稳的值如果场景特别暗可以微调到3.0。5.2 从pt到onnx/tensorrt的转换与NMS调节训练好的best.pt可以先用官方脚本转成ONNX格式python export.py --weights runs/train/yolov7_infrared/weights/best.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.45 --conf-thres 0.25 --img-size 640 640 --max-wh 640如果要在Jetson这类边缘设备上做实时推理建议继续把ONNX转成TensorRT的engine文件。红外检测的部署通常不是在高性能服务器上跑而是在嵌入式设备或工控机上跑TensorRT的FP16精度在红外这种轮廓模糊的任务里损失可以忽略不计但推理速度能提升2倍以上。TensorRT版本推理时NMS参数和PyTorch推理时不完全一样。红外场景下同类目标比如一排停放车辆头部挨着头部之间的距离很近如果IoU阈值设得太高容易把两个相邻目标合并成一个框。我建议IoU阈值设在0.45左右不要超过0.5保持适度的容忍度。5.3 实测中的误检漏检处理红外场景里最经典的误检是夏天被暴晒过的金属井盖、沥青路面裂纹、路灯杆、甚至空调外机在红外图里都可能有跟车辆相似的热斑特征。排查这类误检时单纯调confidence阈值是治标不治本。我的建议分两步第一步收集误检样本加入训练集做hard negative mining这个过程重复三轮以上基本能把绝大多数场景误检压下来第二步针对固定机位的监控场景可以在后处理里加一些先验规则比如检测框的长宽比和车辆/行人典型比例严重不符时直接丢弃。这两步做完误检率通常能再降一个量级。还有一个细节容易被忽略红外视频流的抖动比可见光明显如果目标跟踪或检测线程直接跑在原始视频帧上画面抖动会导致同一辆车在不同帧的框位置漂移严重看起来像检测不稳。建议在推理前做一次轻量级的帧间配准比如参考上一帧的全局运动向量做平移补偿或者干脆在后处理阶段接一个简单的IoU跟踪器给同一目标分配稳定ID视觉效果会好得多。6. 踩坑记录与调参经验6.1 我试过最坑的几个问题第一个坑是训练时忘了改类别数。YOLOv7的模型配置文件里nc默认是80如果你数据集的yaml里写了2类cfg没改过来训练过程不会报错但最终模型行为会非常奇怪——模型依赖于COCO的80类语义做初始化输出头的神经元数量跟你的数据集不匹配训练loss虽然会下降但推理结果毫无意义。检查方法很简单训练脚本启动后第一时间看log里打印的model nc: 2是否和预期一致。第二个坑是红外的“热白冷黑”极性差异。不同厂商的红外模组输出极性可能相反有的设备人体是亮的白热有的是暗的黑热。如果你在A设备采集的数据上训练拿到B设备上推理模型性能会立刻崩掉。比较好的做法是在训练数据增强里加入“随机极性反转”让模型对两种极性都鲁棒或者部署时在预处理阶段统一做一次极性判断保证输入分布跟训练一致。这个坑隐蔽性极强遇到模型换机台就失灵的情况先检查这个。第三个坑是混合精度训练在红外任务上的表现不稳定。我遇到过用AMP训练后权重正常但转成FP16的TensorRT引擎后夜间小目标全部丢失的情况。原因是红外小目标本身的信号强度就弱FP16的精度损失把这个弱信号直接“抹”掉了。解决办法是部署端保留FP16但在预处理里对红外图做更强的对比度增强或者在导出engine时用INT8量化加calibration数据集做校准对小目标更友好一些。6.2 给红外场景的参数微调建议最后分享几个针对红外场景的实用调参习惯这些不是标准文档里能查到的但我在多个项目里验证过效果稳定。训练阶段建议把--img从640提到768甚至896红外车辆和行人的边缘模糊分辨率越高的输入模型越容易捕捉轮廓细节。代价是显存占用和推理耗时上升需要根据设备来权衡。行人目标通常在画面远处时特别小如果场景里远距离行人多建议适当调大网络里的P5层输出或者换用能输出更大特征图的模型结构。数据增强方面红外图像不需要像可见光那样强的色彩抖动HSV这些增强会浪费训练时间建议把hsv_h、hsv_s、hsv_v调小或者直接关闭把省下来的训练资源留给Mosaic和MixUp。我常用的配置是hsv_h0.01、hsv_s0.1、hsv_v0.1比默认值低了不少但红外图的单通道特性决定了增强的重点应该在几何变形和尺度变化上。还有一个看似不起眼但实际影响很大的点推理时的置信度阈值建议用验证集上的PR曲线动态选择。命令行里默认的0.25在红外场景往往偏高我自己做夜间行人检测时通常会降到0.15配合上面提到的NMS调节和跟踪器效果反而更稳。实际上阈值的设置跟模型的训练充分度直接挂钩训练越充分阈值可以设得越低误检率也不会失控。红外场景的检测项目最耗时间的永远不是模型选择和训练本身而是数据分布和预处理这些容易被忽视的细节。把数据组织好、把预处理思路理清、把配置文件的每一项都验证过再上训练和部署整个链路才会走得顺畅。我这套流程改一改也能适配其他单模态传感器数据比如微光夜视或者超声热成像底层逻辑是相通的。本文还有配套的精品资源点击获取