使用Scipy进行高斯滤波的意外行为

时间:2017-07-22 13:46:18

标签: python image-processing scipy

假设我加载了图片f(x,y),例如

enter image description here

我想计算图像∂/∂x ∂/∂y G*f的高斯导数f,其中G是高斯滤波器,*表示卷积。使用Scipy可以轻松完成:

from scipy.ndimage.filters import gaussian_filter
imshow(gaussian_filter(g, sigma, order=1))

使用sigma=50会产生以下结果:

enter image description here

现在,出于应用原因,我需要使用mode='constant'

进行计算
imshow(gaussian_filter(g, sigma, order=1, mode='constant', cval=0))

然而,结果看起来很合理:

enter image description here

但请注意,我的图片背景强度为1而不是0。因此,使用cval=1

应该是合理的
imshow(gaussian_filter(g, sigma, order=1, mode='constant', cval=1))

enter image description here

现在这是出乎意料的!这个结果毫无意义,是吗?

为了记录,我还检查了部分差异∂/∂x G*f∂/∂y G*f。而

imshow(gaussian_filter(g, sigma, order=[0, 1], mode='constant', cval=1)

看起来很合理

enter image description here

另一个

imshow(gaussian_filter(g, sigma, order=[1, 0], mode='constant', cval=1)

没有:

enter image description here

为什么?

1 个答案:

答案 0 :(得分:1)

gaussian_filterorder都非零时,cval中存在一个错误。 Specifically, it's here

for axis, sigma, order, mode in axes:
    gaussian_filter1d(input, sigma, axis, order, output, mode, cval, truncate)
    input = output

过滤器执行重复的1d卷积,并且每次将cval传递到1d过滤器。问题是,如果有任何衍生物,则cval应设置为0,因为任何常量的导数为零。这就是order=[1, 0]order=[0, 1]没有结果错误的原因。没有测试(没有SciPy开发环境),我认为以下是正确的:

for axis, sigma, order, mode in axes:
    gaussian_filter1d(input, sigma, axis, order, output, mode, cval, truncate)
    if order > 0: 
        cval = 0.0
    input = output

解决方法

非零cval可以通过在过滤之前从图像中减去它来模拟(并且仅在过滤后仅在订单为零时添加回来)。例如:

import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage.filters import gaussian_filter

g = np.ones((500, 500))
g[200:300, 200:300] = 2
sigma = 50
cval = 1
gf = gaussian_filter(g-cval, sigma, order=1, mode='constant')
plt.matshow(gf)
plt.show()

返回

filtered

这是预期的结果。 (我的原始图像与您的图像略有不同,我使用了不同的可视化工具。)