我的目标是创建和可视化图像(2D)的偏导数。我将用第一个有限的中心差分方程来实现
wikipedia。
F关于x的偏导数是
df(x,y)/dx = f(x + 1,y)-f(x-1,y)
我们可以将其写为卷积核H = [-1,0,1]并应得到相同的结果
通过将图像与内核进行卷积
dfx = F * H
这是我的源代码:
from numpy import *
from pylab import *
from PIL import *
from scipy import signal as sg
#create artifical image with constant positive slope
myImage=zeros((5,5),dtype=float)
for y in range(5):
for x in range(5):
myImage[y,x]=y+x
首先,我通过convolve2d-函数从 scipy 模块创建了x和y的第一个中心有限差分(简称)
kernel=array([[-1,0,1]]) #create first central finite difference kernel
pdx=sg.convolve2d(myImage,kernel,"same") #dI(x,y)/dx
现在我使用循环创建相同的
H,W=myImage.shape[0:2]
pdx=zeros((H,W),dtype=float)
for y in range(1,H-1):
for x in range(1,W-1):
pdx.itemset(y,x,im.item(y,x+1)-im.item(y,x-1))
让我们看一下结果:
pdx-convolve2d的内核方法
array([[-1., -2., -2., -2., 3.],
[-2., -2., -2., -2., 4.],
[-3., -2., -2., -2., 5.],
[-4., -2., -2., -2., 6.],
[-5., -2., -2., -2., 7.]])
pdx-循环的有限差分
array([[ 0., 0., 0., 0., 0.],
[ 0., 2., 2., 2., 0.],
[ 0., 2., 2., 2., 0.],
[ 0., 2., 2., 2., 0.],
[ 0., 0., 0., 0., 0.]])
我对结果感到困惑。为什么核方法具有负斜率?
为了获得相同的结果,我必须将内核翻转为H = [1,0,-1],但这在数学上是不正确的。
有人能帮我吗 ?
最佳答案
差异的原因有两个:
scipy.signal
另外,对于您正在做的事情,您几乎肯定需要
scipy.ndimage.convolve
而不是scipy.signal.convolve2d
。 ndimage
的默认设置设置为适用于图像,并且对于有限精度的整数数据(这是图像的标准)更有效。要使用
scipy.signal
来复制循环版本,您已经注意到需要反转内核。这是卷积的数学定义。内核在被“扫掠”之前就被翻转了。例如:http://en.wikipedia.org/wiki/File:Convolution3.PNG
其次,默认情况下,
scipy.signal.convolve2d
用零填充边界,而您根本不对边界进行操作。要使用scipy.signal.convolve2d
再现边界条件,请使用boundary='symm'
(无论如何,对于此特定内核……通常,您只是忽略了边界,而convolve2d
对此没有选择。)最后,出于您的目的(图像处理),使用
scipy.ndimage.convolve
效率更高。在这种情况下(一维内核),使用scipy.ndimage.convolve1d
效率最高。例如。 scipy.ndimage.convolve1d(data, [1, 0, -1], axis=0)
关于python scipy convolve2d似乎不正确,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20077378/