经典去雾算法--暗通道先验去雾(DCP)

本文详细介绍何凯明博士提出的基于暗通道先验的单幅图像去雾算法,包括算法背景、有雾图片表达公式、暗通道定义、透射率公式、求解全球大气光值及获得精确透射率图的方法。此算法在计算机视觉领域有广泛应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.背景介绍

基于暗通道先验的单幅图像去雾算法来自于何凯明博士2009年的CVPR论文:《Single Image Haze Removal Using Dark Channel Prior》,2009年的CVPR共收到约1450篇投稿,其中393篇文章被接收,接收率为26%。只有一篇文章被选为那年的最佳论文。这是CVPR创立25年以来首次由中国人获得这个奖项。他根据Dark Object Subtraction原理通过大量实验发现局部找最暗点进行均匀去雾有很好的效果。由此得到对于一个无雾图像,每个局部区域都很有可能有一些暗的地方,换言之,至少一个颜色通道会有很低的值、或黑色东西。

这篇论文研究的问题是图像的去雾技术,它可以还原图像的颜色和能见度,同时也能利用雾的浓度来估计物体的距离,这些在计算机视觉上都有重要应用(例如三维重建,物体识别)。但是之前人们还没找到简单有效的方法来达到这个目的。在这篇论文里,他们找到了一个非常简单的,甚至说令人惊讶统计规律,并提出了有效的去雾方法。

2.去雾算法详述

2.1 有雾图片表达公式

有雾图像散射模型:

2.2暗通道定义

作者根据对5000多幅无雾图像的暗通道图数据观察发现:约75%的像素值为0,且90%的像素点具有非常低的值,且集中在[0,16]。由此提出暗通道先验理论,即对于一副无雾图像,其暗通道可以表示为:

2.3 透射率公式

2.4 求解全球大气光值

上述推论中都是假设全球达气光A值时已知的,在实际中,我们可以借助于暗通道图来从有雾图像中获取该值。具体步骤如下:

1) 求出有雾图像的暗通道图,从暗通道图中按照亮度的大小取前0.1%最亮的的像素。

2) 在这些位置中,在原始有雾图像I中寻找对应的具有最高亮度的点的值,作为A值。

2.5获得更精确的透射率图

要获得更为精细的透射率图,何博士在文章中提出了了soft matting方法,能得到非常细腻的结果。但是这一方法弱点就是速度特慢,不使用于实际使用。在2011年,何博士又发表了一片论文,其中提到了导向滤波的方式来获得较好的透射率图。该方法的主要过程集中于简单的方框模糊,而方框模糊有多重和半径无关的快速算法。这个导向滤波算法除了在去雾方面外,还有着其他多方面的应用。

后续会更新softmatting和引导滤波

2.6 最终结果输出

全局大气光值和透射率都已经求出,就可以进行去雾了,当投射图t 的值很小时,会导致J的值偏大,从而使图像整体向白场过度,因此一般可设置一阈值t0,当t值小于t0时,令t=t0,即:

 

 

### DCP算法的Python实现 通道先验(Dark Channel Prior, DCP)是一种有效的图像方法。该技术基于自然场景中的无区域通常至少有一个颜色通道具有较低强度这一观察。 以下是DCP算法的一个简化版本实现: ```python import cv2 import numpy as np def dark_channel(img, size=15): """计算通道""" b, g, r = cv2.split(img) min_rgb = cv2.min(cv2.min(r, g), b) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (size, size)) return cv2.erode(min_rgb, kernel) def atmospheric_light(img, dark_ch): """估计大气光值A""" h, w = img.shape[:2] flat_img = img.reshape(h * w, 3) flat_dark = dark_ch.ravel() search_percentage = int(0.001 * h * w) indices = flat_dark.argsort()[-search_percentage:] a = np.mean(flat_img.take(indices), axis=0) return a def transmission_estimation(img, A, omega=0.95, k_size=15): """估算透射率图T(x)""" norm_I = img / A dark_c = dark_channel(norm_I, k_size) T = 1 - omega * dark_c guided_filter_T = guideFilter(img, T, radius=k_size, eps=0.001) return guided_filter_T def recover(img, t, A, tx=0.1): """恢复无图像J(x)""" max_t = np.max(t) t = cv2.max(tx, t/max_t) J = (img - A) / t[:, :, None] + A return J.clip(0, 255).astype('uint8') def dehaze(image_path): src = cv2.imread(image_path) I = src.astype('float64') / 255 dark = dark_channel(I) A = atmospheric_light(src, dark) te = transmission_estimation(I, A) result = recover(I, te, A) cv2.imshow("Original", src) cv2.imshow("Dehazed Image", result) cv2.waitKey(0) cv2.destroyAllWindows() dehaze('path_to_your_foggy_image.jpg') ``` 此代码实现了基本的DCP流程,包括通道提取、大气光估计以及最终的图像重建过程[^1]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值