生成一维高斯核的最简单方法
我在想,生成一个一维高斯核的最简单方法是什么,给定滤波器的长度。在我看来,应该是对向量[-滤波器长度,...,滤波器长度]的正态分布进行计算,这样理解对吗?
到目前为止,我做了这个,但我不知道为什么不对:
result = np.zeros( filter_length )
mid = filter_length/2
result=[(1/(sigma*np.sqrt(2*np.pi)))*(1/(numpy.exp((i**2)/(2*sigma**2)))) for i in range(-mid,mid+1)]
return result
这里的sigma
是标准差,是一个参数。filter-length
也是一个参数。
之所以不对,是因为比如说当长度=3,sigma=math.sqrt(1.0/2/math.log(2))时,我得到的结果是:
[0.23485931967491286, 0.46971863934982572, 0.23485931967491286]
但应该是:
[0.25, 0.5, 0.25]
所以,是不是有四舍五入的问题?我不知道发生了什么……
编辑 我觉得我应该以某种方式进行截断。
问题解决 问题在于我没有进行归一化。我需要把向量的每个元素都除以它们的总和。
2 个回答
对于喜欢有完整可复制粘贴代码示例的人:
import numpy as np
filter_length = 3
sigma=math.sqrt(1.0/2/math.log(2))
result = np.zeros( filter_length )
mid = int(filter_length/2)
result=[(1/(sigma*np.sqrt(2*np.pi)))*(1/(np.exp((i**2)/(2*sigma**2)))) for i in range(-mid,mid+1)]
sumresult = np.sum(result)
print(result/sumresult)
[0.25 0.5 0.25]
我对numpy的语法不是很熟悉,但如果你把一个卷积核和一个狄拉克脉冲(Dirac impulse)进行卷积,你会得到和这个卷积核一样的输出。
所以你可以直接使用内置的 scipy.ndimage.filters.gaussian_filter1d 函数,把这个数组作为输入:[ 0, 0, 0, ... 0, 1, 0, ...0, 0, 0]
输出应该是一个高斯核,最高点的值为1。(如果你想要不同的最大值,可以把1替换成你想要的值)
总的来说,你会得到gaussian_filter1d函数内部使用的高斯核作为输出。这应该是生成高斯核最简单、出错可能性最小的方法,你也可以用同样的方法生成一个二维的核,只需使用相应的scipy二维函数。当然,如果你的目标是从头开始做,那么这个方法只是作为参考比较好。
关于你的公式:
要想用你的公式得到[..., 0.5, ...]这样的输出,你需要解这个方程:
(1/(sigma*np.sqrt(2*np.pi)) = 0.5
所以正确的sigma应该是:
sigma = math.sqrt(2*1/np.pi)