雨雾天锥桶识别掉点50%?YOLOv11+轻量去雾实战,召回率从42%提升至92%
一、项目背景:恶劣天气下的自动驾驶痛点
上个月在做园区自动驾驶巡检项目时,遇到了一个致命问题:晴天时道路锥桶识别准确率能到98%,但一到小雨或者大雾天,召回率直接跌到42%,经常出现漏检导致车辆撞上锥桶的情况。客户要求雨雾天气下识别准确率必须达到90%以上,否则项目无法验收。
我试过直接用官方YOLOv11预训练权重微调,也试过各种复杂的去雾算法,效果都不理想。踩了无数坑后总结出:雨雾天识别差不是单一问题,而是数据集偏差+图像退化+模型特征提取能力不足三者叠加的结果。单纯靠调参或者加数据根本解决不了,必须从预处理、模型结构到训练策略做全链路优化。
最终我采用了轻量MSRCR去雾+YOLOv11小目标优化+域自适应微调的方案,经过两周的调优,实现了:晴天准确率98.7%,小雨天94.3%,大雾天91.5%,单张1080P图片推理速度仅18ms,完全满足自动驾驶实时性要求。本文将分享所有可直接复用的代码和经验。
二、技术栈选型
优先保证实时性和边缘设备部署能力:
- 目标检测:YOLOv11n(速度最快,小目标检测能力优于前代)
- 图像去雾:MSRCR多尺度Retinex(轻量高效,CPU即可实时运行)
- 数据增强:Albumentations 1.4(支持雨雾模拟增强)
- 训练框架:PyTorch 2.4 + Ultralytics 8.3
- 部署框架:TensorRT 10.2(Jetson Orin NX部署)
三、系统整体架构
专门针对雨雾天气设计的两级处理架构,将去雾增强与目标检测解耦,便于单独优化:
四、雨雾天识别难的核心原因
很多人以为雨雾天识别差只是因为图像模糊,其实远不止如此:
- 大气散射效应:光线被水滴散射,导致目标对比度下降,边缘模糊,远处的小锥桶几乎和背景融为一体
- 伪目标干扰:雨滴、雾气团、路面反光会产生大量类似锥桶的纹理,导致误检率飙升
- 数据集严重偏差:COCO等公开数据集中雨雾样本占比不足1%,模型根本没见过这种场景
- 特征混淆:雨雾会破坏目标的形状和颜色特征,模型容易把锥桶误判成垃圾桶、路牌或者树木
五、核心优化方案详解
5.1 第一步:构建高质量雨雾锥桶数据集
这是所有优化的基础,没有好的数据,再复杂的模型也没用。我总共构建了1500张图片的数据集,其中:
- 真实雨雾样本:600张(在不同天气条件下实地拍摄)
- 合成雨雾样本:700张(用晴天图片合成)
- 晴天样本:200张(保证晴天效果不下降)
关键技巧:
- 不要只拍清晰的锥桶,多拍远处的小锥桶、被雾气半遮挡的锥桶、被雨水打湿的锥桶
- 使用Albumentations自动合成雨雾效果,参数要贴近真实场景:
importalbumentationsasA# 真实感雨雾增强rain_fog_transform=A.Compose([A.RandomRain(slant_lower=-10,slant_upper=10,drop_length=20,drop_width=1,blur_value=3,brightness_coefficient=0.8,rain_type="drizzle",p=0.7),A.RandomFog(fog_coef_lower=0.1,fog_coef_upper=0.5,alpha_coef=0.1,p=0.6),A.RandomBrightnessContrast(brightness_limit=(-0.3,0.1),contrast_limit=(-0.2,0.1),p=0.8)])- 标注时特别注意小目标,小于16×16像素的锥桶也要标注,这是雨雾天漏检的重灾区
5.2 第二步:轻量实时去雾预处理
我测试了Dark Channel Prior、DehazeNet、MSRCR等多种去雾算法,最终选择了MSRCR:它不需要训练,纯CPU即可实时运行,效果足够好,非常适合边缘部署。
MSRCR核心代码:
importcv2importnumpyasnpdefmsrcr_dehaze(image,sigma_list=[15,80,250],G=5.0,b=25.0,alpha=125.0,beta=46.0):"""多尺度Retinex色彩恢复去雾算法"""image=np.float32(image)+1.0# 避免log(0)retinex=np.zeros_like(image)forsigmainsigma_list:gaussian=cv2.GaussianBlur(image,(0,0),sigma)retinex+=np.log(image)-np.log(gaussian)retinex=retinex/len(sigma_list)# 色彩恢复img_sum=np.sum(image,axis=2,keepdims=True)img_color=np.log(alpha*image/img_sum)retinex=retinex*(G*img_color+b)# 归一化min_val=np.min(retinex)max_val=np.max(retinex)retinex=(retinex-min_val)/(max_val-min_val)*255returnnp.uint8(retinex)效果对比:仅加入这一步预处理,雨雾天召回率就从42%提升到了67%,而且推理速度只增加了2ms。
5.3 第三步:YOLOv11模型针对性优化
针对雨雾和小目标的特点,对YOLOv11做三处关键修改:
- 提升输入分辨率:从640×640提高到800×800,小目标检测精度提升明显,速度只下降15%
- 加入CBAM注意力机制:在Backbone的最后三个C2f层加入CBAM,让模型自动关注锥桶区域,忽略背景噪声
- 加强P3检测头:将P3层的通道数从128增加到192,提升小目标特征提取能力
修改yolov11n-cone.yaml配置文件:
backbone:-[-1,1,Conv,[64,3,2]]-[-1,1,Conv,[128,3,2]]-[-1,2,C2f,[128,True]]-[-1,1,Conv,[256,3,2]]-[-1,2,C2f,[256,True]]-[-1,1,Conv,[512,3,2]]-[-1,2,C2f,[512,True]]-[-1,1,CBAM,[512]]# 加入CBAM-[-1,1,Conv,[1024,3,2]]-[-1,2,C2f,[1024,True]]-[-1,1,CBAM,[1024]]# 加入CBAMhead:-[-1,1,Conv,[512,1,1]]-[-1,1,nn.Upsample,[None,2,'nearest']]-[[-1,6],1,Concat,[1]]-[-1,2,C2f,[512,False]]-[-1,1,CBAM,[512]]# 加入CBAM-[-1,1,Conv,[192,1,1]]# P3通道数从128增加到192-[-1,1,nn.Upsample,[None,2,'nearest']]-[[-1,4],1,Concat,[1]]-[-1,2,C2f,[192,False]]# P3-[-1,1,Conv,[192,3,2]]-[[-1,12],1,Concat,[1]]-[-1,2,C2f,[512,False]]# P4-[-1,1,Conv,[512,3,2]]-[[-1,9],1,Concat,[1]]-[-1,2,C2f,[1024,False]]# P5-[[15,18,21],1,Detect,[nc]]5.4 第四步:域自适应微调策略
先在合成雨雾数据集上预训练30轮,然后在真实雨雾数据集上微调20轮,微调时冻结Backbone前5层,只训练后面的特征提取层和检测头。这样既可以利用合成数据的多样性,又能让模型适应真实雨雾场景,避免过拟合。
训练命令:
# 第一阶段:合成数据预训练yolo traindata=cone_synthetic.yamlmodel=yolov11n-cone.yamlepochs=30imgsz=800batch=16# 第二阶段:真实数据微调yolo traindata=cone_real.yamlmodel=weights/last.ptepochs=20imgsz=800batch=8freeze=5六、最终效果对比
所有测试均在包含300张雨雾天图片的独立测试集上进行:
| 方案 | 雨雾天召回率 | 雨雾天mAP@0.5 | 推理速度(ms) | 误检率 |
|---|---|---|---|---|
| 原生YOLOv11n 640 | 42.1% | 38.7% | 8 | 23.5% |
| 原生YOLOv11n 800 | 51.3% | 47.2% | 11 | 19.8% |
| +MSRCR去雾 | 67.5% | 62.3% | 13 | 12.7% |
| +模型结构优化 | 82.4% | 78.6% | 16 | 7.3% |
| +域自适应微调 | 92.1% | 89.5% | 18 | 3.2% |
可以看到,每一步优化都带来了明显的效果提升,最终方案在保证实时性的前提下,将雨雾天召回率提升了50个百分点。
七、踩坑避坑指南
- 不要用复杂的深度学习去雾算法:DehazeNet、FFA-Net等虽然去雾效果好,但推理速度慢,而且容易引入伪影,反而降低检测精度。MSRCR是工业界的最佳选择
- 不要只在合成数据上训练:合成雨雾和真实雨雾还是有差距的,必须有至少30%的真实样本,否则模型在实际场景中会严重掉点
- 不要盲目提高分辨率:超过1280×1280后,精度提升不到5%,但速度会下降50%以上,800×800是最佳平衡点
- 不要忽略误检问题:雨雾天误检率很高,可以通过降低置信度阈值同时提高NMS的IOU阈值来平衡
- 不要用大模型:YOLOv11n足够用,YOLOv11s的速度会慢一倍,精度提升不到2%,完全得不偿失
八、总结与展望
雨雾天气下的目标检测是自动驾驶落地必须解决的问题,没有银弹,必须从数据、预处理、模型三个方面同时入手。本文介绍的方案已经在多个园区自动驾驶项目中落地,效果稳定可靠。
未来可以探索的方向:
- 实现端到端的去雾检测一体化模型,进一步提升速度
- 加入多传感器融合,结合毫米波雷达的点云数据,提升极端天气下的鲁棒性
- 引入自监督学习,利用大量无标注的雨雾图片提升模型泛化能力
最后提醒大家,工业项目的核心永远是贴近真实场景的数据,只要数据足够好,简单的模型也能做出惊艳的效果。
