python scipy convolve2d似乎不正确

时间:2013-11-19 16:53:37

标签: python python-2.7 scipy convolution

我的目标是创建和可视化图像的偏导数(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

首先,我通过来自 scipy 模块(短路)的convolve2d函数为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],但这在数学上是不正确的。 有人能帮我吗 ?

2 个答案:

答案 0 :(得分:8)

差异的原因有两方面:

  1. 你已经忘记了在卷积的数学定义中内核的翻转。
  2. 您假设的边界条件与scipy.signal
  3. 不同

    另外,对于你正在做的事情,你几乎肯定想要scipy.ndimage.convolve而不是scipy.signal.convolve2dndimage的默认值设置为使用图像,对于有限精度的整数数据更有效,这是图像的标准。


    要使用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)

答案 1 :(得分:3)

f g 的卷积是 f(x')g(x - x')的积分 DX' 。这样做的结果是内核翻转。要么使用翻转的内核,要么使用 f(x')g(x + x')scipy.ndimage.correlate,因此内核保持与输入相同的方向

有关详细信息,请参阅Convolution,有关有限差异的一些信息,请参阅Python finite difference functions?