scipy.ndimage.filters.convolve和scipy.signal.convolve有什么区别?

时间:2013-06-03 11:13:37

标签: python scipy multidimensional-array convolution

据我所知,这些方法都在各自的DLL中实现为C函数,看起来ndimage版本更快(实现使用并行化代码,如调用blas或MKL)

此外,当我尝试通过运行以下代码检查它们返回相同的结果时,相等的断言失败。我无法从文档中弄清楚这两种方法之间究竟存在什么功能差异(文档不清楚0相对于内核原点的位置是什么意思;从示例中,我推断它在中心,但我可能错了。)

from numpy import random, allclose
from scipy.ndimage.filters import convolve as convolveim
from scipy.signal import convolve as convolvesig

a = random.random((100, 100, 100))
b = random.random((10,10,10))

conv1 = convolveim(a,b, mode = 'constant')
conv2 = convolvesig(a,b, mode = 'same')

assert(allclose(conv1,conv2))

谢谢!

2 个答案:

答案 0 :(得分:9)

这两个函数对于处理边界有不同的约定。要使您的呼叫在功能上相同,请将参数origin=-1origin=(-1,-1,-1)添加到convolveim的呼叫中:

In [46]: a = random.random((100,100,100))

In [47]: b = random.random((10,10,10))

In [48]: c1 = convolveim(a, b, mode='constant', origin=-1)

In [49]: c2 = convolvesig(a, b, mode='same')

In [50]: allclose(c1,c2)
Out[50]: True

仅在b的尺寸均匀时移动原点。当它们是奇数时,函数在使用默认origin=0时达成一致:

In [88]: b = random.random((11,11,11))

In [89]: c1 = convolveim(a, b, mode='constant')

In [90]: c2 = convolvesig(a, b, mode='same')

In [91]: allclose(c1,c2)
Out[91]: True

答案 1 :(得分:4)

有一个非常重要的区别。图像包中的实现似乎是图像处理中用于在卷积之后实现图像的“相同”尺寸的典型限制版本。因此,如果我们使用mode ='constant',它与信号处理包中的'same'选项一致,如上例所示。信号处理包似乎实现了卷积运算符的真正严格定义。也许因为这个原因它更慢。查找包含完全不同结果的一些示例。

In [13]: a=array([[1,2,1]])
In [14]: b=array([[1],[2],[1]])

In [17]: convolveim(a,b)
Out[17]: array([[4, 8, 4]])

In [18]: convolveim(b,a)
Out[18]: 
array([[4],
       [8],
       [4]])

In [19]: convolvesig(a,b)
Out[19]: 
array([[1, 2, 1],
       [2, 4, 2],
       [1, 2, 1]])

In [20]: convolvesig(b,a)
Out[20]: 
array([[1, 2, 1],
       [2, 4, 2],
       [1, 2, 1]])

请注意,信号处理包实现是可变的,正如预期的正确卷积一样。但是,图像包中的实现不是,它提供了与第一个参数具有“相同”维度的解决方案。