据我所知,这些方法都在各自的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))
谢谢!
答案 0 :(得分: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
仅在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]])
请注意,信号处理包实现是可变的,正如预期的正确卷积一样。但是,图像包中的实现不是,它提供了与第一个参数具有“相同”维度的解决方案。