the*_*0ID 5 python image-processing scipy
鉴于我已f(x,y)加载图像,例如,
我想计算\xe2\x88\x82/\xe2\x88\x82x \xe2\x88\x82/\xe2\x88\x82y G*f图像 的高斯导数f,其中G是高斯滤波器,*表示卷积。使用 Scipy 可以轻松完成此操作:
from scipy.ndimage.filters import gaussian_filter\nimshow(gaussian_filter(g, sigma, order=1))\nRun Code Online (Sandbox Code Playgroud)\n\n这样sigma=50会产生以下结果:
现在,出于应用原因,我需要使用以下方法进行计算mode=\'constant\':
imshow(gaussian_filter(g, sigma, order=1, mode=\'constant\', cval=0))\nRun Code Online (Sandbox Code Playgroud)\n\n尽管如此,结果看起来还是合理的:
\n\n\n\n但是,请注意我的图像背景的强度是1而不是0。因此,使用应该是合理的cval=1:
imshow(gaussian_filter(g, sigma, order=1, mode=\'constant\', cval=1))\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n现在这是出乎意料的!这个结果没有任何意义,不是吗?
\n\n作为记录,我还检查了偏微分\xe2\x88\x82/\xe2\x88\x82x G*f和\xe2\x88\x82/\xe2\x88\x82y G*f。然而
imshow(gaussian_filter(g, sigma, order=[0, 1], mode=\'constant\', cval=1)\nRun Code Online (Sandbox Code Playgroud)\n\n看起来很合理
\n\n\n\n另一个
\n\nimshow(gaussian_filter(g, sigma, order=[1, 0], mode=\'constant\', cval=1)\nRun Code Online (Sandbox Code Playgroud)\n\n才不是:
\n\n\n\n这是为什么?
\n小智 4
gaussian_filter当 和order均cval非零时,会出现一个错误。具体来说,它在这里:
for axis, sigma, order, mode in axes:
gaussian_filter1d(input, sigma, axis, order, output, mode, cval, truncate)
input = output
Run Code Online (Sandbox Code Playgroud)
滤波器执行重复的一维卷积,并且每次都传入cval一维滤波器。问题是,如果有任何导数,则应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
Run Code Online (Sandbox Code Playgroud)
可以通过在过滤之前从图像中减去非零来模拟非零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()
Run Code Online (Sandbox Code Playgroud)
回报
这是预期的结果。(我的原始图像与您的有点不同,并且我使用了不同的可视化工具。)