应用高斯滤波器后,图像变暗。

3
当我运行以下代码时,输出结果会变得模糊,但是当我增加sigma值时,图像会变暗。
导入模块

import numpy as np
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
import math
import copy

高斯滤波器代码
e = 2.71828182845904
pi = 3.1415926535897

def gaus(mat_l,sigma):
    Matrix = [[0.0 for x in range(mat_l)] for y in range(mat_l)] 
    for x in range(-(int(mat_l/2)),(int(mat_l/2))+1):
        for y in range(-(int(mat_l/2)),(int(mat_l/2))+1):
            ee = pow(e,(-(((pow(x,2)+pow(y,2))/(2*(pow(sigma,2)))))))
            aa = (1/(2*pi*pow(sigma,2)))
            result = ee*aa
            Matrix[x+int(mat_l/2)][y+int(mat_l/2)] = round(result,6)
    return Matrix

卷积编码

def matrix_convolve(image,kernel,a,b,mul=1):
    print(kernel)
    img_x, img_y = image.shape
    kernl_x, kernl_y = kernel.shape

    result = copy.deepcopy(image)
    for i in range(img_x-int(len(kernel)/2)):
        for j in range(img_y-int(len(kernel)/2)):
            result[i][j] = 0
            summ = 0
            for s in range(-a,a+1):
                for t in range(-b,b+1):
                    summ += kernel[s,t] * image[i+s,j+t]
            result[i][j] = math.ceil(mul*summ)
    return result

驱动程序

image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

kernal = gaus(5,5)
kernal = np.array([kernal[0],kernal[1],kernal[2],kernal[3],kernal[4]])

result3 = matrix_convolve(image,kernal,2,2)
plt.imshow(result3.astype(np.uint8),cmap='gray')
plt.show()

当sigma为5时,输出图像为 sigma_5的输出图像

当sigma为2时,输出图像为 sigma_2的输出图像

result3=cv2.GaussianBlur(image,(5,5),5)
plt.imshow(result3.astype(np.uint8),cmap='gray')
plt.show()

使用OpenCV模糊处理时,对于sigma 5的输出如下图所示: opencv

1
当您增加sigma时,曲线会变得更平缓。如果矩阵的总和小于1,则应用它将使图像变暗。 - Mark Ransom
没错。但目的是要模糊图像。你有什么建议? - Mrcreamio
归一化可以确保区域保持不变。因此振幅必须减小。请参见http://pages.stat.wisc.edu/~mchung/teaching/MIA/reading/diffusion.gaussian.kernel.pdf.pdf。我认为您想通过`aa`来去除归一化,以使内核的中心成为单位。如果由于某种原因它不是单位,则通过除以中心值进行归一化。 - fmw42
@fmw42:核心的中心不应该是单位矩阵,而是核心值的总和应该为1。 - Cris Luengo
@Cris Luengo 是的,你说得对。我的错误。 - fmw42
1个回答

7
问题在于您只对高斯核进行了5x5网格的采样。 sigma越大,截断的核就越多,失去的能量也就越多。
模糊核应该总和为1。例如,如果总和为0.5,则输出图像的平均强度将是输入的一半。
解决方案有两个:
  1. 采样更大比例的核。至少采样1+2*ceil(2*sigma),但最好是3倍而不是2倍。
  2. 使您的核归一化。即使从中心采样到3*sigma,采样仍会损失一些能量,特别是对于小的sigma。归一化核很简单,只需将所有核值相加,然后将每个核值除以该总和即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接