生成一维高斯核的最简单方法

问题描述 投票:0回答:2

我想知道在给定滤波器长度的情况下,在 python 中生成一维高斯核的最简单方法是什么。我认为这个想法是评估向量 [-filter-length,...,filter_length] 值的正态分布,这是正确的吗?

到目前为止,我已经这样做了,但我不知道为什么它不正确:

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
也是一个参数。

这是不正确的,因为我得到,例如,对于 length=3 和 sigma=math.sqrt(1.0/2/math.log(2))

[0.23485931967491286, 0.46971863934982572, 0.23485931967491286]

应该是:

[0.25, 0.5, 0.25]

那么,是否存在舍入问题?我不知道发生了什么事...

编辑我认为我应该以某种方式截断

问题解决了问题是我没有正常化。我必须将向量除以其所有分量的总和。

python image-processing computer-vision
2个回答
5
投票

我对 numpy 语法不是很坚定,但是如果你用狄拉克脉冲对内核进行卷积,你会得到与输出相同的内核。

因此,您可以简单地使用 inbuild scipy.ndimage.filters.gaussian_filter1d 函数,并使用此数组作为输入: [ 0, 0, 0, ... 0, 1, 0, ...0, 0, 0 ]

输出应该是一个高斯核,其峰值值为 1。 (将 1 替换为所需内核中所需的最大值)

所以本质上,您将获得 gaussian_filter1d 函数内部使用的高斯核作为输出。这应该是生成高斯核的最简单且最不容易出错的方法,您可以使用相同的方法使用相应的 scipy 2d 函数生成 2d 核。当然,如果目标是从头开始,那么这个方法只能作为参考

关于你的方程:
要获得 [..., 0.5, ...] 作为公式的输出,您需要解决

(1/(sigma*np.sqrt(2*np.pi)) = 0.5

所以正确的西格玛应该是
sigma = math.sqrt(2*1/np.pi)


0
投票

对于那些喜欢完整工作的复制/粘贴代码示例的人:

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]

© www.soinside.com 2019 - 2024. All rights reserved.