11

据我所见,这些方法都是在各自的 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))

谢谢!

4

2 回答 2

11

这两个函数有不同的处理边界的约定。要使您的调用在功能上相同,请将参数origin=-1或添加origin=(-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
于 2013-06-03T12:31:19.380 回答
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]])

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

于 2013-11-08T19:12:05.910 回答