FEATURED · 精选文章

基于YOLOV5的红外车辆检测与TensorRT部署实践

发布时间 / 2026/9/16 2:47:56
来源 / 创域科博编辑部
栏目 / 资讯中心
基于YOLOV5的红外车辆检测与TensorRT部署实践 简介面向计算机视觉开发者和智能交通项目团队这份基于YOLOv5的红外车辆检测与识别资源包解决了夜间和恶劣天气下可见光难以捕捉车辆的痛点可直接用于实时监控、安全预警等场景。压缩包共128个文件大小约263.77MB内部结构涵盖训练好的pt权重模型、Python训练与推理脚本、YAML参数配置、标注XML/JSON数据以及大量jpg/png红外图像样本和mkv/mp4演示视频。目前已吸引1060人学习下载。开发者可直接加载模型进行实时车辆识别也可结合附带的完整源码与数据集深入理解YOLOv5的锚框机制、损失函数和数据增强策略并针对特定车型或环境开展微调训练快速沉淀一套适配自身业务的红外视觉解决方案显著降低从算法研究到项目落地的门槛。1. 红外车辆检测选YOLOV5赌的是工程落地综合成本夜间路口监控和全天候交通流量统计是红外热成像视觉方案最典型的落地场景。相比可见光相机红外热像仪不依赖路灯照明车辆发动机舱、排气管和轮胎摩擦区域的热辐射即使在完全无光条件下也能形成稳定轮廓。但红外图像分辨率低、噪声明显、目标边缘模糊直接拿COCO预训练模型推理漏检和误检会同时出现。这个标题给出的YOLOV5方案以源码、模型、数据集三件套的形式覆盖了从训练到实时推理的完整链路。选YOLOV5而不是更新的YOLOv8或RT-DETR理由在落地的综合成本。红外车辆是单类别、纹理贫瘠的场景新架构的精度增益并不显著却要付出部署脚本、算子支持和社区资料成熟度的代价。YOLOV5的TensorRT导出、数据集标注工具链和训练脚本生态沉淀足够对需要快速完成POC的团队是风险最低的选项。2. YOLOV5检测红外车辆的核心原理从输入预处理到锚框输出2.1 红外图像与可见光图像的差异为什么COCO权重不能直接迁移红外热像仪记录的是物体表面在8-14微米波段的辐射强度分布反映的是温度不是反射光。车辆运行状态下发动机舱、排气管、轮胎等高温部件呈现高亮区域路面温度相对较低呈现暗色背景整个画面的灰度直方图往往集中在某个温度区间对比度天然偏低。可见光图像中的车辆依赖环境光反射拥有颜色、纹理、车标等丰富的判别特征红外图像中车辆只有灰度轮廓模型能依赖的线索只剩热辐射梯度和整体形状。这个差异最直接的影响是骨干网络提取的特征语义完全不同。在ImageNet或COCO上预训练出的浅层卷积核擅长识别边缘方向、颜色块和纹理周期这些能力在红外图像上用处有限。更麻烦的是可见光数据里车灯高亮区域的局部特征与红外图像中发动机舱高温区域的局部特征在灰度分布上可能高度相似预训练权重容易把这类区域错误激活。因此实际项目中我会在推理前对红外图像做一次基于直方图的自适应拉伸。下面是对单张红外图像做预处理并送进YOLOV5的代码import cv2 import numpy as np def preprocess_ir(img, size640): # 红外原始图是单通道灰度图用IMREAD_GRAYSCALE直接读 gray cv2.imread(img, cv2.IMREAD_GRAYSCALE) # CLAHE把低对比度红外图中的温度梯度拉开 clahe cv2.createCLAHE(clipLimit3.0, tileGridSize(8, 8)) gray clahe.apply(gray) # 单通道复制成三通道兼容YOLOV5的RGB输入 rgb cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB) # letterbox等比例缩放不足部分用灰度值114填充 resized, ratio, (dw, dh) letterbox(rgb, (size, size), stride32, color114) resized resized.transpose((2, 0, 1)) # HWC - CHW return resized, ratio, (dw, dh)CLAHE参数在红外场景里的调法有讲究。clipLimit控制对比度增强幅度3.0左右能明显提升远距离车辆的轮廓如果调到5.0以上路面热噪声会被一起放大误检数上升。tileGridSize设8x8还是4x4的区别在于增强粒度4x4适合大气散射严重的雾天8x8在晴朗夜间的道路场景表现更稳。2.2 骨干网络、Neck与检测头的分工逻辑YOLOV5的骨干网络是CSPDarknet它使用C3模块把特征图通道拆成两路一路做残差堆叠一路直接传递最后在末端合并。这种跨阶段连接让梯度回传时重复计算的量变少也让深层网络在数据集规模不大时更难过拟合。对红外车辆这种样本量通常在几千到几万张的任务来说这个结构特性比单纯堆参数更有价值。Neck部分采用FPNPAN的双向融合结构。FPN把高层的语义信息往底层传让低层特征图能看懂目标类别PAN反方向把底层的位置信息往高层传让高层特征图保留更精确的边界。检测头分别在stride 8、16、32的三个特征图上做预测对应小、中、大目标。红外车辆里最难检的远距离小目标依赖stride 8这路输出承担如果训练集里小目标标注占比低于5%这路分支学不到足够的正样本特征部署时远端漏检就会持续存在。检测头的输出维度在单类别任务里是64个边界框回归偏移、1个目标置信度、1个类别概率。损失函数中CIoU负责边界框回归BCEWithLogitsLoss负责置信度和分类。CIoU同时考虑重叠面积、中心点距离和宽高比对红外图像中轮廓模糊但中心位置相对可靠的目标来说回归收敛过程更稳定。2.3 推理参数链路置信度阈值与NMS的取舍YOLOV5推理端的核心参数集中在NMS上。输入图像除以255归一化后送进模型输出是每个锚框的原始预测值经过decode得到坐标、置信度和类别。detect.py里的核心代码非常短# detect.py中的推理主流程 pred model(img)[0] pred non_max_suppression(pred, conf_thres0.25, iou_thres0.45, max_det300)conf_thres和iou_thres对红外场景的影响可以总结为下表参数推荐范围设得偏高设得偏低conf_thres0.15-0.30远距离车辆漏检明显地面热斑被当成目标iou_thres0.40-0.50同一车辆输出多个框并排车辆被错误合并max_det50-100多目标时丢框噪声框占满上限这里有一个重要逻辑红外场景的误检具有集中性热噪声误检往往固定出现在路面、墙壁等位置。不需要通过提高全局阈值来压制它而是先定位误检集中区。确实源于数据分布的话就在训练集中补充对应位置的负样本只是个别环境变量则可以在业务层面对固定区域做ROI屏蔽。全局阈值越往高调小目标的召回损失越大不建议一上来就动conf_thres。3. 用现成源码和模型在本地跑通红外车辆实时推理3.1 YOLOV5环境配置从源码到detect.py跑起来拿到一套红外车辆识别源码第一件事是按仓库结构把环境跑起来。官方仓库的detect.py、train.py、val.py、export.py脚本齐全环境配置最稳妥的顺序是先装Python虚拟环境再按requirements.txt装依赖最后单独确认PyTorch的CUDA版本是否匹配。git clone https://github.com/ultralytics/yolov5.git cd yolov5 python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txtrequirements.txt覆盖了得尽早确认的依赖包括torch、torchvision、opencv-python、numpy、matplotlib、pandas、seaborn和pyyaml。最容易踩的两个坑一是pip默认可能装进CPU版本的PyTorch这时torch.cuda.is_available()返回False需要按操作系统和CUDA版本重新指定安装源二是Linux服务器缺失libGL.so.1时opencv导入直接报错用apt安装libgl1即可解决。提示如果torch.cuda.is_available()返回False先别查模型代码问题基本在torch本身的编译版本。3.2 模型权重与数据集文件的配套确认红外车辆项目的源码通常自带两个关键目录weights目录存放训练好的.pt文件datasets目录存放图像和txt标签。拿到权重后第一步是确认nc类别数避免推理时代码里的类别数和权重不匹配。python -c import torch; ckpttorch.load(weights/best.pt, map_locationcpu); print(ckpt[model].yaml[nc])这条命令直接打印权重中的类别数。输出1说明这个红外车辆模型只检车辆输出2或3说明还包含行人、非机动车等类别推理脚本里的标签名列表要对应修改。数据集的txt标签格式可以用head命令抽查head -n 3 datasets/ir_vehicle/train/labels/0001.txtYOLO格式的五个数字分别是类id、归一化中心x、中心y、宽、高。类id在0到nc-1之间且宽高数值在0到1之间数据集格式就是正常的。3.3 实时检测运行命令与业务集成方式源码级目录下跑实时检测用detect.py就可以。下面的命令覆盖了视频文件和摄像头两种source# 用训练好的best.pt检测红外视频 python detect.py --weights weights/best.pt --source test_ir.mp4 --conf-thres 0.25 --iou-thres 0.45 --save-txt --save-conf # 用第0路摄像头做实时检测 python detect.py --weights weights/best.pt --source 0 --conf-thres 0.25 --device 0--save-txt把每个目标的框坐标、置信度写入runs/detect/exp目录下的txt文件车流量统计等后处理可以直接消费这些数据。--save-conf在txt中追加置信度字段做告警逻辑时常用。摄像头模式下source 0默认用OpenCV的VideoCapture读取UVC协议的红外热像仪是免驱设备直接填设备编号即可。要把检测逻辑嵌入自己的业务服务不要改detect.py的事件循环而是封装Detector类class VehicleDetector: def __init__(self, weightsbest.pt, devicecpu): self.model attempt_load(weights, devicedevice) self.device device def __call__(self, frame): im letterbox(frame, 640, stride32, autoTrue)[0] im im.transpose((2, 0, 1))[::-1] im np.ascontiguousarray(im) im torch.from_numpy(im).to(self.device) im im.float() / 255.0 im im.unsqueeze(0) pred self.model(im)[0] return non_max_suppression(pred, 0.25, 0.45)attempt_load会自动识别权重里的nc和anchorsbest.pt和last.pt都能直接加载。调用时用with torch.no_grad()包裹循环交给调用侧统一管理上下文避免每个检测循环都重建一次计算图。4. 自建红外车辆数据集的训练流程格式、命令与超参数调优4.1 红外车辆数据集准备目录结构、标注格式和样本划分红外车辆训练的起点是数据集。自带数据集不够用时需要自己采集红外视频抽帧和标注。两个建议一是抽帧间隔不能太密同一辆车在连续帧中变化很小太多相似帧会让训练集分布偏移二是标注时把遮挡目标和发热粘连目标谨慎处理热辐射会让两个靠近的车辆在图像上粘连成一片标注者如果不加注意会把两个目标的框合并成一个。标注工具推荐LabelImg或X-AnyLabeling导出格式选YOLO生成的同名txt文件放在labels目录下。目录结构按YOLOV5约定如下datasets/ir_vehicle/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/训练集和验证集的划分需要注意时间序列泄漏问题。红外视频帧在时间上连续如果随机打乱划分验证集里会出现和训练集非常接近的帧验证指标虚高。按时间段划分把原始视频前80%的帧作为训练集、后20%作为验证集才是符合实际部署场景的评估方式。4.2 修改yaml配置并用YOLOV5训练自己的数据集训练前要改两个yaml文件。data yaml描述数据集路径和类别model yaml描述网络规模。data yaml的完整形态# datasets/ir_vehicle.yaml path: ./datasets/ir_vehicle train: images/train val: images/val nc: 1 names: 0: vehicle然后执行训练命令python train.py --data datasets/ir_vehicle.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --batch-size 16 \ --epochs 100 \ --imgsz 640 \ --device 0 \ --name ir_vehicle_exp--weights yolov5s.pt从COCO预训练权重开始迁移训练比从零训练收敛更快泛化性能也更好。--cfg models/yolov5s.yaml里的nc: 1和data yaml不一致时train.py会用data yaml里的值覆盖。--imgsz在显存充裕时设640显存紧张降到544或480对红外车辆这种大目标为主的数据集精度损失很小。4.3 训练日志读法和红外场景超参数微调方案训练产物的核心是runs/train/exp/results.csv和results.png。做模型调优时只看四个指标box_loss、obj_loss、mAP0.5和mAP0.5:0.95。obj_loss先降后升是最常见的异常信号通常意味着学习率过大或模型开始过拟合正确做法是把epochs减到60-80同时把--hyp文件中的lr0从0.01改为0.002。红外车辆单类别检测中以下超参数的建议值和默认值差异明显超参数YOLOV5默认值红外场景建议原因lr00.010.001-0.005小数据集避免训练震荡mosaic1.00.5或关闭拼接改变热辐射分布比例multi-scale01增强小目标泛化能力hsv_h0.0150红外图像无颜色信息mAP0.5在单类别任务中达到0.9以上说明训练收敛不错mAP0.5:0.95达到0.7以上说明边界框回归精度良好。如果前者高而后者低说明框的定位精度差需要检查标签里边界框的标注是否偏保守。红外图像中车辆边缘不锐利标注时容易把热辐射光晕框进去导致框偏大这种标注噪音会直接体现在mAP0.5:0.95上。改进方向是标注时让边界框紧贴高亮区域的core部分去掉光晕。训练结束后best.pt和last.pt在runs/train/ir_vehicle_exp/weights/下用best.pt做验证和部署。验证命令python val.py --data datasets/ir_vehicle.yaml --weights runs/train/ir_vehicle_exp/weights/best.pt --imgsz 6405. 实时红外车辆检测的部署优化TensorRT导出与前处理细节5.1 边缘设备的引擎导出PyTorch直接推理在桌面级GPU上能跑到实时但在Jetson Nano这类边缘硬件上要跑满25 FPS标准做法是导出为TensorRT engine。导出命令python export.py --weights runs/train/ir_vehicle_exp/weights/best.pt --include engine --imgsz 640 --device 0TensorRT导出会进行FP16精度模式推理延迟通常降低约50%。两点经验一是导出时的batch_size必须和部署时保持一致不同batch_size的engine不能混用二是TensorRT固定了输入尺寸640x640多数红外视频流分辨率固定静态engine足够不需要动态shape。5.2 应对红外热像仪温度漂移的前处理策略红外热像仪开机后有明显的温度漂移期前3-5分钟图像整体偏暗且灰度会缓慢上移。如果把预处理固定成0-255范围的线性映射早晚检测性能会波动。更稳的做法是对视频帧做局部自适应直方图均衡frame_gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(4, 4)) frame_enhanced clahe.apply(frame_gray)这段代码放在视频循环里每帧执行。clipLimit2.0比单张图片做增强时低一些防止帧间增强幅度抖动造成检测框闪烁。如果车灯区域频繁出现时检时不检的现象再把clipLimit降到1.5。温度漂移本质上是灰度分布的整体偏移自适应直方图均衡比固定阈值映射更能抵抗这种变化。5.3 验证实时性达标的三条标准实时不能只看平均帧率我习惯从三个指标同时验证。端到端延迟是从摄像头获取帧到拿到检测结果的时间差实测中应控制在100ms以内帧率稳定性要看5分钟内的FPS波形如果最低值与平均值差超过10%说明有线程阻塞或显存抖动CPU占用率长时间高于90%时解码线程调度会出问题整体延迟随之飙升。注意TensorRT导出的engine文件大小通常20-40MB部署时要把engine和标签映射文件、预处理配置一起打包单独拷贝engine文件到无PyTorch环境的设备上才会吃依赖的亏。一个容易被忽略的优化点YOLOV5的letterbox在每帧都做等比例缩放和填充但视频流尺寸固定填充区域坐标也固定提前把缩放矩阵算好缓存起来每帧能省下重复计算的开销。这个技巧在性能受限的嵌入式平台上能换回几十毫秒级别的收益。本文还有配套的精品资源点击获取
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻