假设我加载了图片f(x,y)
,例如
我想计算图像∂/∂x ∂/∂y G*f
的高斯导数f
,其中G
是高斯滤波器,*
表示卷积。使用Scipy可以轻松完成:
from scipy.ndimage.filters import gaussian_filter
imshow(gaussian_filter(g, sigma, order=1))
使用sigma=50
会产生以下结果:
现在,出于应用原因,我需要使用mode='constant'
:
imshow(gaussian_filter(g, sigma, order=1, mode='constant', cval=0))
然而,结果看起来很合理:
但请注意,我的图片背景强度为1
而不是0
。因此,使用cval=1
:
imshow(gaussian_filter(g, sigma, order=1, mode='constant', cval=1))
现在这是出乎意料的!这个结果毫无意义,是吗?
为了记录,我还检查了部分差异∂/∂x G*f
和∂/∂y G*f
。而
imshow(gaussian_filter(g, sigma, order=[0, 1], mode='constant', cval=1)
看起来很合理
另一个
imshow(gaussian_filter(g, sigma, order=[1, 0], mode='constant', cval=1)
没有:
为什么?
答案 0 :(得分:1)
当gaussian_filter
和order
都非零时,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()
返回
这是预期的结果。 (我的原始图像与您的图像略有不同,我使用了不同的可视化工具。)