一、雨雾天气到底让自动驾驶视觉吃了什么亏
开自动驾驶的车,遇到大雨或者浓雾,摄像头就像戴了磨砂眼镜。雨滴会遮挡镜头,雾气会散射光线,拍出来的画面模糊成一片。常见的问题有三个:目标检测漏掉行人或车辆,车道线完全看不清,距离估算严重偏差。比如你正想超车,结果系统把雾中的卡车误判成静止物体,那就危险了。这些失效的根本原因在于:摄像头依赖可见光,而雨雾会破坏光的传播路径。下面先看一个简单的相机退化模型(不用记公式,理解意思就行):
场景反射的光经过雾层时,一部分被吸收,一部分被散射,最后到达相机的光强是直接衰减光加上环境光(也就是雾的亮度)。所以图像对比度降低,颜色发白,细节消失。
二、光靠摄像头不行,得请雷达大哥帮忙
既然摄像头在雨雾里掉链子,那就拉上毫米波雷达和激光雷达一起干活。这就是多传感器融合。毫米波雷达不怕雨雾,能直接测距离和速度;激光雷达虽然受雾影响,但比摄像头强一些,能提供精确的点云轮廓。
2.1 融合方案的核心思路
不管传感器类型是什么,最终都要把数据统一到同一个坐标系下,然后融合它们的优势。一般做法是:用雷达检测障碍物的位置和运动状态,用激光雷达补充形状信息,用摄像头提供颜色和纹理(哪怕模糊也有一点帮助),最后通过卡尔曼滤波或深度学习模型把三种数据揉在一起。
2.2 实战:用Python演示简单雷达与摄像头数据融合
下面用模拟数据演示一下如何把雷达检测到的目标框投影到摄像头图像上。技术栈:Python + OpenCV + NumPy。
import cv2
import numpy as np
# 模拟摄像头内参和雷达外参(实际场景需要标定)
camera_matrix = np.array([[800, 0, 320],
[0, 800, 240],
[0, 0, 1]], dtype=float)
# 假设雷达坐标系到相机坐标系的旋转和平移(R|T)
R = np.eye(3, dtype=float)
T = np.array([0, 0, 2]) # 雷达在相机后2米
# 模拟雷达检测到的目标(x,y,z世界坐标,单位米)
radar_points = np.array([
[10, 0, 0], # 正前方10米
[8, -1.5, 0], # 左前方8米
[12, 2, 0] # 右前方12米
])
# 将雷达点投影到图像平面
def project_radar_to_image(radar_pt, camera_mat, rot, trans):
# 转换到相机坐标系
pt_cam = rot @ radar_pt + trans
# 投影到像素
pt_img = camera_mat @ pt_cam
u = int(pt_img[0] / pt_img[2])
v = int(pt_img[1] / pt_img[2])
return (u, v)
# 创建一张空白图像模拟摄像头画面
img = np.ones((480, 640, 3), dtype=np.uint8) * 200 # 灰色背景
# 在图像上画出雷达点对应的位置(用红色圆圈标识)
for pt in radar_points:
uv = project_radar_to_image(pt, camera_matrix, R, T)
cv2.circle(img, uv, 5, (0, 0, 255), -1) # 红色实心圆
# 显示结果(实际运行会弹出窗口)
cv2.imshow('Radar Projection', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 注释:这段代码只是演示了坐标变换,真实融合还需要考虑时间同步、遮挡处理等。
上面代码把雷达检测到的点(比如行人位置)画到了模拟图像上,帮助直观理解融合的第一步。实际系统中,还会把雷达的测距信息与摄像头检测框匹配,然后输出一个置信度更高的目标。
三、图像复原:给摄像头“洗把脸”
多传感器融合是补短板,但摄像头本身也还有救。图像复原技术可以去掉雾气效果,让画面变清晰。常用的方法有基于物理模型的暗通道先验去雾算法,以及基于深度学习的DehazeNet。
3.1 暗通道先验去雾原理(一句话说)
对无雾图像,在大多数非天空区域,至少有一个颜色通道的值非常低(称为暗通道)。而有雾图像暗通道亮度更高。利用这个差异可以估算出雾的透射率和大气光,从而复原出清晰图像。
3.2 用OpenCV实现一个简易去雾函数
import cv2
import numpy as np
def simple_dehaze(image):
"""
基于暗通道先验的简化去雾
输入:有雾彩色图像(BGR格式)
输出:去雾后的图像
"""
# 转换为浮点型方便计算
img = image.astype(np.float32) / 255.0
# 计算暗通道:每个像素取RGB最小值,然后模糊
dark_channel = np.min(img, axis=2)
# 用最小值滤波模拟暗通道(实际需要用腐蚀操作)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 15))
dark_channel = cv2.erode(dark_channel, kernel)
# 估计大气光:取暗通道中最亮的前0.1%的像素对应的原图亮度
flat_dark = dark_channel.ravel()
flat_img = img.reshape(-1, 3)
num_pixels = flat_dark.shape[0]
top_k = int(num_pixels * 0.001)
indices = np.argpartition(flat_dark, -top_k)[-top_k:]
atmospheric_light = np.max(flat_img[indices], axis=0) # 各通道的大气光值
# 估计透射率:使用简化公式 t = 1 - omega * dark_channel
omega = 0.95
transmission = 1 - omega * dark_channel
# 设置透射率下限,避免过亮
transmission = np.clip(transmission, 0.1, 1.0)
# 复原图像 J = (I - A) / t + A
restored = np.zeros_like(img)
for c in range(3):
restored[:,:,c] = (img[:,:,c] - atmospheric_light[c]) / transmission + atmospheric_light[c]
# 裁剪到0~1并转回uint8
restored = np.clip(restored, 0, 1) * 255
return restored.astype(np.uint8)
# 读取一张有雾的图像(假设存在)
# img_hazy = cv2.imread('foggy_road.jpg')
# img_clear = simple_dehaze(img_hazy)
# cv2.imshow('Dehazed', img_clear)
# 注释:实际使用时需要调整参数,并且暗通道先验对天空区域可能过度增强。
这个函数虽然简单,但在很多场景下能让摄像头画面从“白茫茫”变成“看得清车道线和车辆轮廓”。配合多传感器融合,可以提升检测的召回率。
四、协同优化:把两招结合起来打组合拳
多传感器融合和图像复原不是二选一,而是可以协同工作。具体做法:先用图像复原模块对摄像头原始帧进行去雾增强,然后送入目标检测和车道线识别算法;同时雷达和激光雷达数据也并行处理;最后在决策层将两种结果融合。这样即便单个传感器有瑕疵,也能靠其他传感器和增强后的数据互相矫正。
4.1 流程度伪代码展示
# 技术栈:Python(假设使用YOLO目标检测、OpenCV去雾、自定义雷达融合模块)
def autonomous_driving_pipeline(radar_data, lidar_data, camera_frame):
# 步骤1:图像复原
dehazed_frame = simple_dehaze(camera_frame) # 使用上面定义的函数
# 步骤2:视觉感知(目标检测+车道线识别)
detections_visual = yolo_detector(dehazed_frame) # 返回框坐标和类别
lanes_visual = lane_detector(dehazed_frame) # 返回车道线参数
# 步骤3:雷达目标检测
radar_targets = radar_processor(radar_data) # 提取目标位置和速度
# 步骤4:激光雷达点云处理
lidar_objects = lidar_segmenter(lidar_data) # 得到3D包围盒
# 步骤5:多传感器融合(简单举例:用IOU匹配)
fused_objects = fuse_detections(detections_visual, radar_targets, lidar_objects)
# 步骤6:融合车道线与视觉车道线(一般以摄像头为主,雷达辅助验证)
final_lanes = refine_lanes(lanes_visual, radar_data)
return fused_objects, final_lanes
在协同方案中,图像复原确保视觉模块在雨雾天不至于完全失明,而雷达和激光雷达提供稳定的距离信息,两者互补。例如,雷达检测到前方有物体但摄像头因雾看不清,图像复原后摄像头可能找回轮廓,从而提升分类精度。
五、应用场景与优缺点
5.1 应用场景
城市道路:雨雾天交叉路口行人、非机动车检测。
高速公路:大雾天气车道保持、前车距离预警。
山区或沿海:经常有团雾的盘山路。
雨夜:雨水反光加雾气,摄像头几乎失效。
5.2 技术优点
可靠性提升:单一传感器失效时仍有备份。
适应性强:图像复原能处理不同浓度的雾气。
成本可控:毫米波雷达价格已大幅下降,加装去雾算法只消耗算力。
易维护:图像复原和融合算法均可在线更新。
5.3 技术缺点
计算开销:同时跑多个传感器处理和去雾算法,对嵌入式芯片要求高。
融合标定复杂:传感器之间需要精确的时空同步,误差大会导致融合错位。
去雾算法局限性:暗通道先验在大片天空区域容易过曝,深度学习模型需要大量雨雾训练数据。
传感器本身限制:毫米波雷达角度分辨率低,无法区分车道线;激光雷达在浓雾中也会衰减。
六、注意事项
硬件选型要匹配:低端雷达可能噪声大,融合时容易引入误报。
天气动态变化:雨雾浓度不均匀,去雾参数需要自适应调整,不能固定。
安全冗余设计:即便融合方案,也不能完全依赖单一传感器输出,需要设置置信度阈值。
法规合规:自动驾驶系统在雨雾天必须达到一定安全等级才能上路,目前很多方案还在验证阶段。
数据闭环:收集实际雨雾场景数据,持续优化去雾模型和融合逻辑。
七、文章总结
雨雾天气对自动驾驶视觉造成巨大挑战,但通过多传感器融合(雷达+激光雷达+摄像头)和图像复原(去雾算法)的协同优化,可以显著提升系统在恶劣天气下的感知能力。本文从问题出发,用直观代码演示了雷达投影和简易去雾实现,并给出了融合流程。没有一种万能技术,但组合拳让每一路传感器各司其职,摄像头负责识别,雷达负责测距,激光雷达负责三维轮廓。未来随着神经辐射场(NeRF)或端到端融合模型的发展,雨雾天的感知会越来越可靠。但现阶段,保证硬件的鲁棒性和算法的实时性,才是落地关键。