1. 项目概述
在自动驾驶和智能交通领域,目标检测算法的可靠性直接关系到行车安全。作为一名长期从事计算机视觉研究的工程师,我经常遇到一个棘手问题:雾霾天气下传统检测算法性能急剧下降。去年参与某城市智慧交通项目时,我们部署的YOLOv5系统在雾天漏检率高达40%,这促使我深入研究解决方案。
经过半年多的实验验证,我们开发了一套融合图像增强与改进YOLOv5的检测框架。核心思路是先通过物理模型还原图像本质特征,再针对雾霾场景优化检测网络。实测在能见度不足50米的浓雾条件下,mAP@0.5仍能保持75%以上,较基线提升12.5个百分点。本文将完整分享从原理到落地的技术细节,包括:
- 暗通道先验算法的工程化改进技巧
- YOLOv5网络结构的针对性优化方案
- 自建雾霾数据集的标注与增强方法
- 实际部署中的性能调优经验
2. 技术方案设计
2.1 整体架构设计
系统采用经典的"前处理+检测"两阶段架构,但每个环节都针对雾霾场景做了深度优化:
code复制[雾霾图像输入] → [DCP去雾增强] → [改进YOLOv5检测] → [目标输出]
选择这种架构主要基于三点考量:
- 模块解耦:便于单独优化图像质量与检测精度
- 实时性保障:两阶段总耗时控制在80ms内(1080Ti显卡)
- 可解释性:物理模型+深度学习结合,更易排查问题
2.2 去雾算法选型
对比测试了三类主流去雾方法:
| 方法类型 | 代表算法 | 优点 | 缺点 |
|---|---|---|---|
| 图像增强 | CLAHE | 计算快(15ms) | 细节丢失严重 |
| 物理模型 | DCP | 物理可解释 | 边缘光晕效应 |
| 深度学习 | AOD-Net | 端到端优化 | 需要大量配对数据 |
最终选择改进版DCP算法,因其:
- 不需要训练数据(实际场景难获取雾/清晰图像对)
- 通过引导滤波优化透射率估计,减轻光晕效应
- 单帧处理耗时稳定在35ms(1080p图像)
3. 核心实现细节
3.1 DCP去雾优化实践
标准DCP算法存在两个工程痛点:
- 天空区域透射率估计不准
- 大气光估计受白色物体干扰
我们的改进方案:
python复制def enhanced_dcp(img, w_size=15, t0=0.1):
# 暗通道计算(优化边界处理)
dark = cv2.erode(np.min(img,2), np.ones((w_size,w_size)))
# 大气光估计(排除前0.1%最亮像素)
hist = np.histogram(dark.flatten(), bins=256)[0]
cum_hist = np.cumsum(hist)/dark.size
threshold = np.where(cum_hist>0.999)[0][0]/255
atmosphere = img[np.where(dark>=threshold)]
# 透射率优化(结合颜色衰减先验)
transmission = 1 - 0.95*dark/atmosphere.max()
transmission = np.clip(transmission, t0, 1)
# 引导滤波细化
return guided_filter(img, transmission, r=60, eps=1e-3)
关键技巧:将引导滤波的半径设为图像短边的5%,能在保持边缘和抑制噪声间取得最佳平衡
3.2 YOLOv5改进方案
针对雾霾场景的三个专项优化:
-
注意力机制增强:
在Backbone末端添加CBAM模块,增强模糊目标的特征响应python复制class CBAM(nn.Module): def __init__(self, c): super().__init__() self.channel_att = ChannelGate(c) self.spatial_att = SpatialGate() def forward(self, x): x = self.channel_att(x) x = self.spatial_att(x) return x -
多尺度特征融合:
修改PANet结构,增加浅层特征权重(对小目标更敏感) -
损失函数调整:
引入Focal Loss解决雾天样本难易不均衡问题python复制loss_obj = FocalLoss(pred_obj, target_obj, gamma=2)
4. 数据集构建与训练
4.1 数据采集方案
由于公开雾霾数据集有限,我们采用三种方式构建数据:
-
真实采集:
- 使用车载摄像头在不同雾霾等级下采集2000+图像
- 覆盖白天/夜间、城市/高速等场景
-
物理仿真:
基于Mie散射理论合成雾霾效果:python复制def add_haze(img, beta=0.8): A = 0.9 # 大气光 transmission = np.exp(-beta*depth_map) return img*transmission + A*(1-transmission) -
数据增强:
- 随机调整雾浓度(beta∈[0.5,1.2])
- 模拟车灯眩光效果
4.2 标注规范优化
针对雾天特点特别标注:
- 对模糊目标采用"宽松框"策略(IoU阈值降至0.4)
- 标注部分遮挡目标的可见区域
- 对极端模糊样本做数据清洗
最终构建包含15,678张图像的数据集,类别分布:
| 类别 | 训练集 | 验证集 | 测试集 |
|---|---|---|---|
| 车辆 | 8,742 | 1,120 | 1,056 |
| 行人 | 6,532 | 835 | 788 |
| 交通标志 | 3,215 | 412 | 389 |
5. 实验与部署
5.1 性能对比实验
在自建测试集上的结果(输入尺寸640×640):
| 方法 | mAP@0.5 | 推理时延 | 显存占用 |
|---|---|---|---|
| 原始YOLOv5 | 62.3% | 28ms | 1.8GB |
| 仅DCP预处理 | 68.7% | 63ms | 2.1GB |
| 本文完整方案 | 74.8% | 76ms | 2.4GB |
关键发现:
- 去雾处理带来6.4%的mAP提升
- 网络改进贡献额外6.1%增益
- 端到端延迟控制在可接受范围
5.2 实际部署经验
在边缘计算设备上的优化技巧:
-
DCP加速:
- 将透射率计算移植到GPU(速度提升3倍)
- 对低分辨率视频流跳帧处理
-
模型量化:
bash复制
python export.py --weights yolov5m.pt --include onnx --dynamic使用TensorRT FP16量化后,模型大小缩减60%
-
异常处理:
- 检测到连续5帧无目标时自动触发重初始化
- 动态调整去雾强度(根据图像熵值判断雾浓度)
6. 常见问题与解决
6.1 去雾过度问题
症状:图像出现明显伪影或噪声放大
解决方案:
- 限制最小透射率t0∈[0.1,0.2]
- 对去雾后图像做非局部均值去噪
6.2 小目标漏检
典型场景:远距离行人检测失败
改进措施:
- 在训练数据中增加小目标样本比例
- 使用更高分辨率输入(896×896)
- 添加专门的小目标检测头
6.3 实时性不足
优化策略:
- 采用多线程流水线:
python复制
Thread1: 图像采集 → DCP去雾 → 缓存队列 Thread2: 从队列读取 → YOLOv5检测 - 对非ROI区域做降采样处理
经过这些优化,我们的系统已在多个城市的智能交通项目中落地,日均处理图像超过200万张。在实际应用中最大的体会是:针对特定场景的算法优化,往往比追求通用模型更能取得实效。下一步计划将这套方法扩展到雨雪天气场景,目前正在收集相关数据。
