基于暗通道先验的低照度图像去模糊
时间: 2023-07-27 09:06:02 浏览: 205
基于暗通道先验方法的图像去雾
基于暗通道先验的低照度图像去模糊算法可以通过以下步骤实现:
1. 估计暗通道:将低照度图像转换为灰度图像,并使用一个小的滑动窗口来计算每个像素点的暗通道值。
2. 估计大气光:在暗通道图像中找到像素值最大的位置,该位置对应的像素值即为大气光的估计值。
3. 估计传输率:根据暗通道先验,估计传输率。其中,透射率$t(x)$可以表示为:$t(x) = 1 - \omega \min_{c \in \{R,G,B\}}(\frac{I(x)}{A_c})$,其中,$\omega$是调节因子,$I(x)$是像素点$x$的暗通道值,$A_c$是大气光在通道$c$上的值。
4. 估计退化函数:由于低照度图像可能存在运动模糊,需要估计退化函数。一种简单的方法是将传输率平方后得到退化函数$h(x)$,即$h(x)=t^2(x)$。
5. 恢复图像:使用逆滤波或盲复原等方法来恢复图像。
下面是基于暗通道先验的低照度图像去模糊的Python代码示例:
```
import cv2
import numpy as np
def get_dark_channel(img, window_size):
# 计算每个像素点在指定窗口下的最小值
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (window_size, window_size))
dark_channel = cv2.erode(img_gray, kernel)
return dark_channel
def get_atmospheric_light(img, top_percent):
# 获取全局大气光值
im_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
height, width = im_gray.shape
num_pixels = height * width
num_select_pixels = int(num_pixels * top_percent)
im_gray_flat = im_gray.reshape(num_pixels)
indices = np.argsort(-im_gray_flat)
return np.mean(im_gray_flat[indices[:num_select_pixels]])
def get_transmission(img, atmospheric_light, omega):
# 获取透射率
img_dark = get_dark_channel(img, 15)
transmission = 1 - omega * (img_dark / atmospheric_light)
return transmission
def get_blur_kernel(img, transmission, kernel_size):
# 获取模糊核
h = np.ones((kernel_size, kernel_size))
kernel = np.zeros((kernel_size, kernel_size, 3))
for i in range(3):
kernel[:,:,i] = h * transmission
kernel /= kernel.sum()
return kernel
def restore_image(img, kernel):
# 恢复图像
img_blur = cv2.filter2D(img, -1, kernel)
img_restore = cv2.normalize(img / img_blur, None, 0, 255, cv2.NORM_MINMAX)
return img_restore
def deblur(img, omega=0.95, top_percent=0.001, kernel_size=15):
# 低照度图像去模糊
atmospheric_light = get_atmospheric_light(img, top_percent)
transmission = get_transmission(img, atmospheric_light, omega)
kernel = get_blur_kernel(img, transmission, kernel_size)
result = restore_image(img, kernel)
return result
```
使用该算法进行低照度图像去模糊,只需调用`deblur`函数即可,如下所示:
```
img = cv2.imread('input.jpg')
result = deblur(img)
cv2.imwrite('output.jpg', result)
```
其中,`img`为输入图像,`omega`为调节因子,`top_percent`为全局大气光值所占像素百分比,`kernel_size`为模糊核大小。
阅读全文