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

bbu*_*scu 7 python convolution scipy multidimensional-array

据我所知,这些方法都在各自的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))
Run Code Online (Sandbox Code Playgroud)

谢谢!

War*_*ser 9

这两个函数具有处理边界的不同约定.要使您的呼叫在功能上相同,请将参数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
Run Code Online (Sandbox Code Playgroud)

只有尺寸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
Run Code Online (Sandbox Code Playgroud)


kap*_*tan 5

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

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]])
Run Code Online (Sandbox Code Playgroud)

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