第一次读到何恺明那篇CVPR最佳论文时,最让我震撼的不是那些复杂的公式,而是他验证暗通道先验的方式——统计了5000多张图片后发现,在非天空区域,96.1%的像素至少有一个颜色通道的值低于25(8bit图像)。这个发现就像哥伦布发现新大陆,给图像去雾领域开辟了一条全新路径。
暗通道的数学定义其实很直观:对于任意像素点,取其周围一个小窗口(比如15×15),在这个窗口内所有像素的RGB三个通道中,找出每个通道的最小值,然后再取这三个最小值中的最小值。用代码表示会更清晰:
python复制def get_dark_channel(image, window_size=15):
min_channel = np.min(image, axis=2) # 取RGB三通道最小值
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (window_size, window_size))
dark_channel = cv2.erode(min_channel, kernel) # 最小值滤波
return dark_channel
这个操作就像用显微镜观察图像的"最暗基因"。在晴天拍摄的清晰图像中,由于物体表面反射和阴影的存在,总会有某些区域颜色值趋近于0。但雾天拍摄的图像就像被蒙上一层白色薄纱,这个特性就被破坏了。我曾在深圳梧桐山拍摄过同一场景的雾天和晴天照片对比,暗通道图的差异令人震惊——晴天照片的暗通道像繁星点点,而雾天照片则像被均匀涂抹的灰色画布。
那个看似简单的雾图模型I(x)=J(x)t(x)+A(1-t(x)),其实蕴含着深刻的物理意义。去年我在大疆做图像处理项目时,为了向硬件工程师解释这个模型,专门做了个实验:用透明玻璃板模拟大气层,通过调节玻璃的磨砂程度(相当于t(x))和背后灯光强度(相当于A),完美复现了雾化效果。
模型中每个参数都有明确物理含义:
理解这个模型的关键在于认识到:雾化效果是加性噪声和乘性噪声的结合。J(x)t(x)是乘性部分,表示物体反射光在传输过程中的衰减;A(1-t(x))是加性部分,表示大气光的散射效应。这让我想起在调试无人机视觉系统时,发现晨雾中的建筑物边缘总是比理论预测的更模糊——后来才明白这是两种噪声共同作用的结果。
论文中最精妙的部分莫过于如何利用暗通道先验估计透射率。推导过程看似复杂,其实可以分解为几个关键步骤:
在实际编码时,有几点容易踩坑:
python复制def estimate_transmission(hazy_img, A, omega=0.95, window_size=15):
normalized = hazy_img.astype(float) / A
dark_channel = get_dark_channel(normalized, window_size)
transmission = 1 - omega * dark_channel
return np.clip(transmission, 0.1, 1.0) # t0设为0.1
特别要注意的是对天空区域的处理。有次我处理航拍图像时,发现天空区域出现明显色偏,就是因为没有单独处理天空。后来改进的方法是先检测天空区域(通过颜色和纹理特征),然后对这些区域采用不同的透射率计算策略。
估计大气光A看似简单——取暗通道最亮的前0.1%像素对应原图像素的平均值,但实际操作中陷阱重重:
这里分享一个实用技巧:在处理视频序列时,可以跟踪大气光的变化曲线。我发现相邻帧间的A值变化应该是平滑的,利用这个特性可以滤除瞬时估计误差。这个技巧在车载摄像头去雾中特别有效。
最后一步看似只是简单公式J=(I-A)/t+A,但要获得高质量结果需要注意:
python复制def recover_scene(hazy_img, transmission, A, t0=0.1):
transmission = np.maximum(transmission, t0) # 避免除以0
J = np.zeros_like(hazy_img)
for c in range(3): # 对每个颜色通道处理
J[:,:,c] = (hazy_img[:,:,c] - A[c]) / transmission + A[c]
return np.clip(J, 0, 255).astype(np.uint8)
在华为P系列手机的项目中,我们发现直接应用该算法会导致低光场景下细节丢失。后来通过自适应调节t0参数(基于图像亮度直方图),成功解决了这个问题。这提醒我们:没有放之四海皆准的参数,必须根据场景动态调整。
将算法落地时,这些经验可能帮你少走弯路:
有次给交通监控系统做去雾模块,发现传统方法在夜间红外图像上完全失效。后来通过分析发现,红外图像的暗通道特性与可见光不同,于是重新设计了针对红外图像的暗通道提取方法。这个案例告诉我:理论再完美,也要经得起现实数据的检验。
虽然暗通道先验效果惊人,但在某些场景下会失效:
针对这些问题,业界提出了许多改进方案。我在某安防项目中就结合了深度估计网络,将透射率估计转化为深度学习问题。不过有意思的是,即使在深度学习大行其道的今天,暗通道先验作为预处理步骤仍然很有价值——它需要的计算资源少,且能提供不错的初始估计。