如何获取高斯滤波器?

6

我希望获得一个大小为m行n列的高斯窗口。 我知道如何得到一维的高斯窗口,即下面这样。

from scipy.stats import multivariate_normal
multivariate_normal(mean=[1, 5], cov=(2.5))

现在我需要一个矩阵的两个维度。 目的:我想将这个滤镜放在图片的顶部。绿色是一张图片的矩阵。蓝色圆圈是高斯滤镜。我不确定如何得到蓝色窗口。
我考虑应用类似于以下内容的某些东西 -
gw = multivariate_normal(mean=[1, 5], cov=(2.5))

for i in range(image.shape[0):
    image_gauss_window[i:] = gw

输入图像描述

你能提供一种找出图像高斯滤波器的方法吗?我看到OpenCV中有很多函数将高斯模糊应用于图像。但是这里我想要在将其应用/卷积到图像之前找到过滤器。

4个回答

7

使用 np.fromfunction:

您可以使用我编写的基本计算机视觉库中的一些代码。

如果您有sizesigma,那么您可以使用这行代码获取2d numpy array高斯 kernel

kernel = np.fromfunction(lambda x, y: (1/(2*math.pi*sigma**2)) * math.e ** ((-1*((x-(size-1)/2)**2+(y-(size-1)/2)**2))/(2*sigma**2)), (size, size))

然后要对其进行 归一化,只需将每个 元素 除以 总和

kernel /= np.sum(kernel)

例如,使用 size5sigma1 的内核将给出以下结果:

array([[ 0.00296902,  0.01330621,  0.02193823,  0.01330621,  0.00296902],
       [ 0.01330621,  0.0596343 ,  0.09832033,  0.0596343 ,  0.01330621],
       [ 0.02193823,  0.09832033,  0.16210282,  0.09832033,  0.02193823],
       [ 0.01330621,  0.0596343 ,  0.09832033,  0.0596343 ,  0.01330621],
       [ 0.00296902,  0.01330621,  0.02193823,  0.01330621,  0.00296902]])

您可以看到的是一个漂亮对称的二维正态分布曲线,中心处呈现出高峰。


您可以通过 matplotlib 来可视化这个高斯滤波器:

gaussian


为什么你使用 size-1 而不是直接使用 size - information_interchange
经过仔细检查,我相信这具有居中效果! - information_interchange

7

使用Python中的openCV

示例:5x5内核,Sigma=1.0:

第一种方法:使用矩阵,中间只有一个1

    visualization_matrix = np.zeros((5,5))
    visualization_matrix[2,2] = 1.0
    print(visualization_matrix)

    [[0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0.]
     [0. 0. 1. 0. 0.]
     [0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0.]]

    gauss_kernel = cv2.GaussianBlur(visualization_matrix , (5, 5), 1.0, 
                                    borderType=cv2.BORDER_ISOLATED)
    print("Kernel: \n", gauss_kernel)

    Kernel:
    [[0.00296902 0.01330621 0.02193823 0.01330621 0.00296902]
     [0.01330621 0.0596343  0.09832033 0.0596343  0.01330621]
     [0.02193823 0.09832033 0.16210282 0.09832033 0.02193823]
     [0.01330621 0.0596343  0.09832033 0.0596343  0.01330621]
     [0.00296902 0.01330621 0.02193823 0.01330621 0.00296902]]

第二种方法:使用 cv2.getGaussianKernel
    xdir_gauss = cv2.getGaussianKernel(5, 1.0)
    kernel = np.multiply(xdir_gauss.T, xdir_gauss)
    print("Kernel: \n", kernel)

    Kernel: 
    [[0.00296902 0.01330621 0.02193823 0.01330621 0.00296902]
     [0.01330621 0.0596343  0.09832033 0.0596343  0.01330621]
     [0.02193823 0.09832033 0.16210282 0.09832033 0.02193823]
     [0.01330621 0.0596343  0.09832033 0.0596343  0.01330621]
     [0.00296902 0.01330621 0.02193823 0.01330621 0.00296902]]

结果是相同的。

请注意,在Python中,卷积核大小必须为奇数。因此,使用例如4x4的卷积核不受所使用的函数支持。


5
如果你正在寻找一种"Python"的方法来创建一个二维高斯滤波器,你可以通过两个一维高斯滤波器的点积来创建它。
创建一个单独的1x5高斯滤波器。
x = np.linspace(0, 5, 5, endpoint=False)
y = multivariate_normal.pdf(x, mean=2, cov=0.5)

然后将其转换为一个二维数组。
import numpy as np
y = y.reshape(1,5)

将y与自身进行点乘以创建对称的2D高斯滤波器。
GF = np.dot(y.T,y)

这看起来很简单,试着去做一下。 - ajayramesh
2D对称高斯滤波器 === 高斯滤波器? - ajayramesh
是的,它是同一件事。 - yapws87

3

这个函数在OpenCV中不存在,但是OpenCV提供了基本函数来创建它,这个函数叫做cv::getGaussianKernel。因为我不熟悉python,所以我用c++编写了我的程序,但我知道将这段代码转换成python很简单。

Mat xdirectionGauss = getGaussianKernel(4,  //Size of kernel in x direction
                                        1.4);  // Sigma in x direction

Mat kernel =xdirectionGauss*xdirectionGauss.t();  //kernel * transpose(kernel)
的输出将会像这样:
[0.035183571, 0.058602851, 0.058602851, 0.035183571;
0.058602851, 0.097610727, 0.097610727, 0.058602851;
0.058602851, 0.097610727, 0.097610727, 0.058602851;
0.035183571, 0.058602851, 0.058602851, 0.035183571]

如果将结果与产生2D内核的MATLAB进行比较,则输出结果与opencv完全相同。

>> h = fspecial('gaussian',[4 4], 1.4)

h =

0.0352    0.0586    0.0586    0.0352
0.0586    0.0976    0.0976    0.0586
0.0586    0.0976    0.0976    0.0586
0.0352    0.0586    0.0586    0.0352

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