回答问题

scipy(或其他流行的库)中是否有基于 FFT 的 2D 互相关或卷积函数?

有这样的功能:

  • scipy.signal.correlate2d- “convolveND实现的直接方法对于大数据会很慢”

  • scipy.ndimage.correlate-“使用精确计算(即非 FFT)将数组与给定内核相关联。”

  • scipy.fftpack.convolve.convolve,这个我不是很懂,但是好像错了

numarray 有一个correlate2d()函数和一个fft=True开关,但我猜 numarray 被折叠成 numpy,我找不到这个函数是否包含在内。

Answers

我发现scipy.signal.fftconvolve,正如 magnus所指出的那样,但当时并没有意识到它是 n\ 维的。由于它是内置的并产生正确的值,因此它似乎是理想的解决方案。

来自二维卷积示例:

In [1]: a = asarray([[ 1, 2, 3],
   ...:              [ 4, 5, 6],
   ...:              [ 7, 8, 9]])

In [2]: b = asarray([[-1,-2,-1],
   ...:              [ 0, 0, 0],
   ...:              [ 1, 2, 1]])

In [3]: scipy.signal.fftconvolve(a, b, mode = 'same')
Out[3]: 
array([[-13., -20., -17.],
       [-18., -24., -18.],
       [ 13.,  20.,  17.]])

正确的!另一方面,STSCI 版本需要一些额外的工作才能使边界正确?

In [4]: stsci.convolve2d(a, b, fft = True)
Out[4]: 
array([[-12., -12., -12.],
       [-24., -24., -24.],
       [-12., -12., -12.]])

(STSCI方法还需要编译,我没有成功(我只是注释掉了非python部分),有一些像这样的错误和修改输入([1, 2]变成[[ 1, 2]]) 等。所以我将接受的答案更改为内置的fftconvolve()函数。)

当然,相关性与卷积是一回事,但有一个输入反转:

In [5]: a
Out[5]: 
array([[3, 0, 0],
       [2, 0, 0],
       [1, 0, 0]])

In [6]: b
Out[6]: 
array([[3, 2, 1],
       [0, 0, 0],
       [0, 0, 0]])

In [7]: scipy.signal.fftconvolve(a, b[::-1, ::-1])
Out[7]: 
array([[ 0., -0.,  0.,  0.,  0.],
       [ 0., -0.,  0.,  0.,  0.],
       [ 3.,  6.,  9.,  0.,  0.],
       [ 2.,  4.,  6.,  0.,  0.],
       [ 1.,  2.,  3.,  0.,  0.]])

In [8]: scipy.signal.correlate2d(a, b)
Out[8]: 
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [3, 6, 9, 0, 0],
       [2, 4, 6, 0, 0],
       [1, 2, 3, 0, 0]])

和最新版本已通过在内部使用 2 的幂大小进行了加速(然后我通过对实际输入使用真正的 FFT 来加速它和使用 5 平滑长度而不是 2 的幂:D)。

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐