简介:针对红外场景下车辆与行人检测需求,这份基于YOLOv8的完整方案集成了训练好的检测权重、数千张红外车辆行人数据集,以及训练过程输出的PR曲线、loss曲线等评估材料,适用于自动驾驶、夜间监控、安防巡检等领域的开发者参考或直接迁移使用。压缩包共包含2000个文件,其中1984个txt文件为标注文件,13个md文件为说明文档,2个pdf文件为补充资料,1个yaml文件为模型配置,整体大小约317.64MB,文件结构清晰,便于按需查找。模型权重基于数千张红外图像训练,输入尺寸为640×640,最终mAP超过90%,可对car与person两类目标进行检测,既可直接加载推理,也可利用现有标注数据继续训练或微调,同时附带的评估曲线能辅助分析模型收敛情况与性能瓶颈。目前已有657人学习使用,对于需要快速搭建红外场景车辆行人检测系统的研究者与工程师,是一份可落地的工程参考资源。 做红外场景下的车辆行人检测,最难的不是模型本身,而是很多人一上来就踩了数据分布的坑。我自己最开始也犯过这个错误:直接用COCO预训练权重去跑红外视频,结果白天效果看着还行,一到晚上或者逆光场景,漏检率直接飙到一半以上。后来把整套流程重新捋了一遍——从红外数据集的选型、标注规范、训练策略到权重导出——才算真正把YOLOv8在红外场景下的性能压榨出来。这篇文章就把我完整跑通的经验整理出来,适合正在做红外安防、辅助驾驶、边缘端巡检,或者准备拿红外数据集训练自己的YOLOv8检测器的朋友参考。
1. 这关过不去,后面全是坑:为什么可见光权重在红外场景直接掉点
很多人觉得目标检测模型不都一样吗,换个输入图像照样能跑。理论上没错,但实际效果天差地别。核心原因在于YOLOv8预训练权重是在ImageNet和COCO这类可见光数据集上训练出来的,模型学习到的是可见光图像的颜色、纹理和边缘统计规律。红外图像是热辐射成像,本质上是单通道灰度图,目标与背景的区分依据是温度差异,而不是颜色和反光特性。
具体到车辆和行人这两个类别,红外图像里有几个非常明显的分布差异。
第一是纹理信息极度匮乏。可见光下车身有logo、车牌、玻璃反光,行人衣服有颜色分界,这些都是模型容易抓住的强特征。红外图里这些东西全没了,车身就是一个均匀的亮块或者暗块,行人常常只剩一个轮廓。模型在可见光上学到的纹理特征在红外图上没有对应物,等同于特征失效。
第二是灰度分布偏移。红外热像仪输出的灰度值范围跟相机完全不同,常见的有白热和黑热两种模式。白热模式下高温物体显示为白色,行人和行驶中的车辆通常偏亮;黑热模式完全反过来,目标变成暗色。如果你拿白热模式训练的模型去跑黑热模式的视频,模型会把前景当背景,直接全部漏检。
第三是噪声模式完全不一样。红外传感器的噪声不是可见光传感器的那种高斯噪声,它包含大量的固定条纹噪声、坏点、非均匀性噪声。加上很多红外镜头是定焦热像仪,边缘画质衰减严重,过曝的热斑区域甚至会把目标整个吞掉。
所以不管你最终是打算用现成红外权重做推理,还是准备自己训练,第一步必须搞清楚:你的输入图像到底是什么样的红外成像风格,目标在图像里是亮还是暗,画面的噪声和过曝情况严不严重。这个判断决定了后续所有数据集和训练参数的设定方向。
我见过最典型的翻车现场:有人拿别人的红外权重直接部署到自己的黑热模式摄像头上,跑了一天检测率为零,还以为是权重文件损坏,其实是模式没匹配上。
2. 红外数据集的选型取舍:公开资源与自采方案的优劣势拆解
2.1 公开红外数据集盘点与使用边界
当前能做车辆行人检测的公开红外数据集并不多,质量参差不齐,我把常用且相对靠谱的几个列出来对比一下。
| 数据集 | 规模 | 含车辆行人 | 特点 | 获取方式 |
|---|---|---|---|---|
| FLIR ADAS | 14452张红外图+配准可见光 | 均包含 | 车载场景,夜间居多,类别丰富 | 官网申请下载 |
| KAIST | 95000+对可见光/红外配准图 | 以行人为主 | 多光谱行人检测经典基准 | 官网申请 |
| OTCBVS | 多个子集,共几千张 | 部分包含 | 红外热像经典数据,多用于benchmark | 官网开放 |
| LLVIP | 约3万对可见光/红外图 | 以行人为主 | 低光照行人检测,红外图质量高 | GitHub开放 |
这里必须提醒一句:FLIR ADAS虽然是目前用得最多的开放红外数据集,但它有自己的问题。它的红外图尺寸普遍是640x512,目标在画面中占比偏小,直接训练出来的模型对小目标的召回率一般比较差。KAIST的问题在于标注框的噪声比较大,部分行人标注漏标严重,拿来训练之前需要做一轮清洗和重标注。OTCBVS各子集之间拍摄设备差异大,存在明显的域偏移。
公开数据集最划算的用法不是直接拿来做训练集,而是先做预训练或者迁移学习的起点:用公开红外数据把模型先喂一遍,让它适应红外域的灰度分布,然后再用自己的少量数据进行微调,这样比从COCO权重直接迁移到红外域要稳定得多。
2.2 自采数据:红外场景想提精度绕不开的关键动作
如果项目要求检测准确率比较高,尤其涉及到具体场景部署,自采数据基本是绕不开的。我自己踩过一轮之后总结出来一套可行的采集标注流程,供参考。
采集设备方面,不需要一上来就买昂贵的高分辨率热像仪。普通的红外测温球机、红外枪机,或者FLIR一类的入门级热成像模组都可以。关键不是分辨率多高,而是采样的时间段和场景覆盖要够全。建议覆盖夜间、黄昏、逆光、雨天、起雾这几个典型工况,每个工况至少采集30分钟以上视频。固定摄像头的场景要覆盖远近不同距离的目标出现情况;车载移动场景则要覆盖跟车、会车、交叉路口等典型驾驶状态。
采集到视频之后不要急着抽帧标注。先用ffmpeg按每秒1到2帧抽帧,然后做一次人工筛选,剔除严重过曝、目标完全不可辨、画面全黑这三类垃圾帧。筛选后的图像建议通过脚本做一次直方图统计,看看灰度分布是偏暗还是偏亮,方便后面数据增强时决定要不要加灰度拉伸。
标注这一步特别容易翻车。红外图像对比度低,人眼长时间看会导致标注质量严重下滑。我推荐在标注前先对图像做一次CLAHE对比度增强,让目标边界更清晰,标完再把原图拿来训练,不要让标注员直接盯着原始红外灰度图干活。标注规范里要明确一条:黑热模式下亮的目标边界、白热模式下暗的目标边界,都必须按实际轮廓标,不能因为看得模糊就少标或者画大框。
2.3 数据增强策略:红外场景不能照搬可见光
很多人在红外训练里直接套用YOLOv8默认的增强策略,包括mosaic、mixup、HSV变换等。这里有一个误区:HSV色域增强在单通道红外图上几乎无意义,而mosaic和mixup虽然有帮助,但需要重新考量参数。
红外图的增强重点应该放在这几类:灰度变换类(对比度拉伸、直方图均衡化、伽马校正),用于模拟不同热像仪增益和自动增益控制带来的灰度差异;噪声模拟类(添加条纹噪声、椒盐噪声、高斯噪声),用于模拟低质量红外传感器的噪声干扰;几何类(随机旋转、平移、缩放、翻转),红外目标本身不存在颜色反转问题,几何增强可以放心使用。
我实测下来,在自采的小数据集上(约6000张图),对比度拉伸和条纹噪声模拟这两个增强对最终mAP的提升最明显,分别能带来3到5个点的涨幅。
3. 训练前的关键准备:环境、标注检查和data.yaml配置
3.1 环境配置的几种选择与GPU要求
YOLOv8训练本身对硬件要求不算特别高,关键在于你想要什么样的训练速度和batch size。如果你手里只有一张GTX 1660 Ti(6GB显存),完全能跑,但需要用yolov8s这种小模型,并且把imgsz压到640,batch size设为8到16之间,训练时间会拉长,一个150轮的训练预计要跑十几到二十个小时。如果有RTX 3060 12GB以上,基本可以流畅跑yolov8m,batch size上到16没有压力。如果要用yolov8l或者更大模型,建议显存至少16GB以上,或者开梯度累积。
环境配置就是标准的ultralytics安装流程,重点提醒两点:一是CUDA、PyTorch、ultralytics三者的版本要匹配,二是训练前先跑一次官方coco8小demo确认整套链路是通的,不要等到自己数据集训练一半才发现是环境问题。
3.2 目录结构与data.yaml的正确写法
数据集目录建议严格按YOLO格式组织:
datasets/infrared_det/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 ├── labels/ │ ├── train/ # 对应txt标签 │ └── val/ └── data.yaml每个标签txt文件里每一行是:class_id x_center y_center width height,其中坐标都是归一化到0到1之间的浮点数。标注工具有labelImg和X-AnyLabeling,都是直接用。
data.yaml的内容决定模型输出头怎么初始化,一定不能写错:
# datasets/infrared_det/data.yaml path: datasets/infrared_det train: images/train val: images/val nc: 2 names: 0: vehicle 1: pedestrian这里有个容易忽略的细节:如果你从公开数据集转格式,一定要检查标注坐标是不是归一化的,类别编号是不是从0开始连续排。我之前用过一个转好的FLIR数据集,它把类别编号写成了从1开始,训练的时候类别错位,模型精度直接崩掉。
3.3 训练前的最小验证集检查
开始训练之前,我强烈建议先做一个纯人工检查:随机抽取50到100张训练图和10到20张验证图,用程序在原图上画出标注框,肉眼看一遍框的位置是否贴合目标轮廓。这一步看起来笨,但能提前发现大量标注错位、漏标、坐标归一化错误这类问题。不要嫌麻烦,标注质量直接决定训练上限,这一步能挡住70%以上的后续疑难杂症。
4. 完整训练流程与调参记录:从baseline到收敛
4.1 第一次训练:先跑baseline再说
建议第一次训练先不要做任何自定义优化,直接用推荐配置跑一个baseline,后面所有改进都基于这个baseline来对比,省得自己都不知道改哪里有效果。
第一次训练的命令参考:
yolo detect train \ model=yolov8s.pt \ data=datasets/infrared_det/data.yaml \ epochs=150 \ imgsz=640 \ batch=16 \ device=0 \ workers=8 \ project=runs/infrared_det \ name=baseline_yolov8s注意这里的model=yolov8s.pt,ultralytics会加载COCO预训练权重,同时根据data.yaml里nc=2自动替换检测头。这就是迁移学习的标准用法,比完全从零训练yolov8s.yaml收敛快得多。
训练过程中需要关注两个东西:一个tensorboard或者ultralytics自带的训练曲线,另一个是每个epoch结束在验证集上的mAP50和mAP50-95。正常情况应该是box_loss、cls_loss、dfl_loss三条曲线稳定下降,mAP平稳上升。如果出现训练loss下降但验证mAP震荡剧烈不上升,基本可以判断过拟合,需要增加数据增强强度或者加早停策略。
4.2 参数调节与模型尺寸选择
baseline跑完之后,根据结果决定下一步方向。几种典型情况和对策:
| 现象 | 可能原因 | 调整方向 |
|---|---|---|
| mAP50低于70% | 红外域偏移大,训练数据不足 | 加大数据增强强度,加入公开红外数据预训练 |
| 小目标漏检严重 | 特征图分辨率不足,目标太小 | 将imgsz提升到960或1280,尝试添加P2检测头 |
| 训练loss不收敛 | 学习率不合适或标注错误较多 | 调低学习率到0.0005,回到标注检查步骤 |
| 推理时重复检出同一个目标 | 置信度阈值过低或NMS参数不合适 | 调高conf阈值到0.3以上,调低iou阈值到0.6 |
模型尺寸的选择上,我的经验是:边缘部署(如RK3588、Jetson Orin Nano)优先yolov8s,速度精度平衡最好;服务器端推理或者对精度要求高,可以上yolov8m甚至yolov8l。yolov8n在红外小目标场景下精度损失太明显,不太推荐。
4.3 训练异常的完整排查链路
训练中遇到最烦人的问题就是loss变成NaN。完整的排查链路我建议按这个顺序来:
第一步检查学习率是否过高,尤其是在batch size改大之后。YOLOv8默认学习率0.01,在红外数据集较小的情况下很可能震荡,如果初始loss曲线就剧烈波动,直接把lr0降到0.001。
第二步检查数据和标注里是否有异常值。比如标注坐标出现负数或者大于1,或者图像里出现了全黑全白这种极端样本,可能导致loss异常放大。
第三步检查混合精度训练是否在部分显卡上不稳定。可以加amp=False关掉混合精度再试试,虽然是牺牲一点训练速度,但能排除80%的NaN问题。
第四步如果以上都排查完了还是NaN,检查数据集里是否混入了损坏的图片文件。写一个程序遍历所有图像,用PIL尝试打开,fopen失败的图片全部删掉,这招在多人协作采集的数据集里经常能救命。
4.4 画损失函数曲线的坑
很多教程让你用tensorboard,YOLOv8训练完后其实自带results.png,里面就包含了box_loss、cls_loss、dfl_loss、precision、recall、mAP这些曲线,足够日常分析。
如果你想自己画验证集上的PR曲线或者不同置信度下的预测结果可视化,推荐直接用ultralytics自带的功能:训练完后对单张红外图跑:
yolo detect predict \ model=runs/infrared_det/baseline_yolov8s/weights/best.pt \ source=test_images/infrared_night.jpg \ conf=0.25 \ iou=0.7多生成几张不同场景的可视化图,比只看指标更能定位漏检问题。
5. 红外场景专项优化:数据增强、模型结构与后处理调整
5.1 灰度对比度增强作为输入预处理
红外图像最大的特点是全局对比度低、局部动态范围大。常见做法是在推理和训练前都做一次自适应直方图均衡化(CLAHE)。我实测CLAHE对红外车辆行人检测的提升非常稳定,尤其在夜间低照度场景,可以直接让mAP50提高2到4个点。
具体做法是在数据集加载阶段增加预处理逻辑,或者在推理脚本里加上这一段简单的OpenCV处理:
import cv2 def infrared_preprocess(image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) enhanced = clahe.apply(gray) return cv2.cvtColor(enhanced, cv2.COLOR_GRAY2BGR)注意一个细节:如果训练时没有做CLAHE,而推理时做了,这会造成训练和推理输入分布不一致。最佳实践是把CLAHE统一加到数据预处理流程里,让训练和推理走完全相同的管线。
5.2 针对红外小目标的模型结构小改造
红外场景下远距离目标特别多,远处车辆在640分辨率下可能只有30x20像素,常规检测头很难抓住。一个成本很低但效果明显的改动是添加P2小目标检测头,让模型在更高分辨率的特征图上做检测。ultralytics提供了配好的yolov8-p2.yaml,你可以通过model=yolov8s-p2.yaml加载这个结构。
另一个试验方向是加入注意力机制。我试过在YOLOv8的C2f模块里插入CA(Coordinate Attention),在自采红外数据集上mAP50提升了约1.8个点,代价是推理速度下降了大概10%。如果你的项目对实时性要求不那么苛刻,这个改动值得一试。
5.3 后处理参数与黑热模式适配
红外推理阶段最常见的两个问题,一个是置信度阈值设太高导致漏检,一个是NMS的iou阈值设太高导致同一目标重复出框。
红外场景下目标对比度低,模型输出置信度普遍比可见光场景低0.1到0.2。建议把conf阈值降到0.2到0.25,而不是默认的0.25到0.3。如果在黑热模式下推理成了全漏检,优先检查预处理里是否做了灰度反转。针对单通道红外输入,还有一个常用技巧:把单通道复制成三通道输入给模型,而不是直接拿三通道灰度图,这样模型对通道维度的统计规律更稳定。
6. 权重验证与部署:演示、导出和实际运行中的几个坑
6.1 best.pt不是唯一权重文件
训练结束后runs目录下会生成best.pt和last.pt两个权重。best.pt是验证集mAP最高的权重,last.pt是最后一个epoch的权重。日常部署基本都用best.pt。
这里有一个很多人忽略的细节:YOLOv8的权重文件是一个完整的状态字典,里面包含了模型结构和参数。加载的时候务必保证训练时的模型配置和推理时一致。如果你训练用了p2检测头,推理时也要用对应的模型结构,不能直接换成标准yolov8s去加载。最简单的办法是推理时直接用model=best.pt,不要手动指定模型结构。
6.2 从PyTorch权重到部署格式
如果你准备部署到RK3588或Jetson平台上,建议的导出链路是PyTorch权重先转ONNX,再转目标平台格式。导出命令:
yolo export model=best.pt format=onnx imgsz=640 opset=12 yolo export model=best.pt format=engine device=0 # TensorRT导出导出ONNX时几个参数容易踩坑。opset版本太低可能导致部分算子不支持,建议不低于12。imgsz必须跟训练时保持一致,否则检测性能会明显下降。如果导出的是TensorRT引擎,第一遍跑会慢,因为需要做engine优化,这个属于正常现象。
用GTX 1660 Ti这类显卡做TensorRT部署,建议使用fp16精度,能明显提升推理速度,同时对精度的损失在红外场景下几乎可以忽略。如果部署到Jetson Orin Nano这类设备上,显存比较小,优先选择yolov8s的fp16权重,实测可以跑到接近实时的水平。
6.3 推理测试:确认模型在真实场景中的稳定性
权重导出来之后,一定要拿连续的视频流而不是单张图片做稳定性测试。红外摄像头通常存在自动增益调整,画面亮度会随着目标进入视野而变化,单张图片测不出这种动态影响。用一段至少5分钟的真实视频跑推理,重点看三件事:目标进出视野时是否出现掉帧级别的漏检、目标之间靠近时是否出现标签跳变、灰度模式反转(白热黑热切换)时是否恢复正常检测。
还有一个常见问题:如果你做的是实时视频流检测,结果会随帧闪烁,同一个目标这一帧检测到了下一帧又没了。这通常不是模型问题,而是置信度阈值卡在临界值上。解决方案是配合一个简单的目标跟踪器,比如ByteTrack或者DeepSORT,让检测结果在时间轴上平滑输出。YOLOv8自带的yolo predict命令也支持track=true参数来开启内置跟踪。
最后分享一个我自己的小习惯:做完一轮训练和优化之后,把训练参数、数据集构成、增强策略、最终指标一起记录到训练日志里。红外场景的项目周期长,调试次数多,没有记录很容易忘了上一个版本的训练参数,等想复现最好的结果时只能从头试——这种亏我吃过不止一次。
本文还有配套的精品资源,点击获取