前言

在计算机视觉和图像处理领域中,去雾算法是一种常见且有用的技术,用于消除图像中由雾霾或其他大气干扰引起的降低可见性的问题。在本文中,我们将介绍一种简单而有效的去雾算法,结合了直方图均衡和高斯滤波的方法。

算法

  1. 使用高斯滤波对图像进行降噪,去除图像中的高频噪声。
  2. 计算每个通道的像素值直方图,并根据直方图结果确定最小和最大亮度级别。
  3. 对图像进行线性映射,将像素值映射到新的范围,以增强对比度和可见性。
  4. 输出去雾后的图像。

代码实现

import numpy as np
import cv2

def compute_min_level(hist, pnum):
# 计算最小亮度级别,使得比例超过给定阈值
index = np.add.accumulate(hist)
return np.argwhere(index > pnum * 8.3 * 0.01)[0][0]

def compute_max_level(hist, pnum):
# 计算最大亮度级别,使得比例超过给定阈值
hist_0 = hist[::-1]
cum_sum = np.add.accumulate(hist_0)
index = np.argwhere(cum_sum > (pnum * 2.2 * 0.01))[0][0]
return 255 - index

def linear_map(min_level, max_level):
# 线性映射函数,将像素值映射到新的范围
if min_level >= max_level:
return []
else:
index = np.array(list(range(256)))
screen_num = np.where(index < min_level, 0, index)
screen_num = np.where(screen_num > max_level, 255, screen_num)
for i in range(len(screen_num)):
if 0 < screen_num[i] < 255:
screen_num[i] = (i - min_level) / (max_level - min_level) * 255
return screen_num

def create_new_img(img):
h, w, d = img.shape
new_img = np.zeros([h, w, d])
for i in range(d):
# 计算每个通道的像素值直方图
img_hist = np.bincount(img[:, :, i].reshape(1, -1)[0])
min_level = compute_min_level(img_hist, h * w)
max_level = compute_max_level(img_hist, h * w)
screen_num = linear_map(min_level, max_level)
if screen_num.size == 0:
continue
for j in range(h):
new_img[j, :, i] = screen_num[img[j, :, i]]
return new_img

def noise_and_fog(img):
# 使用高斯滤波对图像进行降噪
image_gaussian = cv2.GaussianBlur(img, (3, 3), 0)
new_img = create_new_img(image_gaussian)
return new_img

if __name__ == '__main__':
img = cv2.imread('input.jpg')
new_img = noise_and_fog(img)
# 显示原始图像和去雾后的图像
cv2.imshow('original_img', img)
cv2.imshow('defogged_img', new_img / 255)
cv2.waitKey(0)
cv2.destroyAllWindows()

实验结果


总结

通过应用直方图均衡和高斯滤波技术,我们成功地实现了一种简单而有效的去雾算法。该算法能够有效地消除图像中的雾霾和大气干扰,提高图像的可见性和对比度。在实际应用中,可以进一步优化算法细节和参数来适应不同场景的去雾需求。


有任何疑问和想法,欢迎在评论区与我交流。