【问题标题】:How to implement the fast fourier transform to correlate two 2d arrays?如何实现快速傅立叶变换以关联两个二维数组?
【发布时间】:2015-06-16 14:11:50
【问题描述】:

我想用更大的数组来做这个,但是为了我能理解它,我会用一个更小的例子。

假设我有以下数组:

    A = [[0, 0, 100],
         [0, 0, 0],
         [0, 0, 0]] 

如果我想计算这个数组与另一个数组的相关性,通过乘以相应的条目。例如,A*A 将等于 A(1*1 = 1,其他地方为零)。我读到快速傅立叶变换可用于通过大型数组加快速度。从我读到的内容来看,如果我想将两个数组 A 和 B 相乘,就像在 A*B 中一样,我可以通过以下方式更快地做到这一点(在 python 中使用 numpy):

a = np.conj(np.fft.fftn(A))
b = np.fft.fftn(B)
c = np.fft.ifft(a*b)

所以实际上,取 A 的 fft,取 B 的 fft,将两个结果相乘,然后得到该结果的倒数。但是,我用上面给出的 A 的情况进行了尝试,将自身相乘。我曾希望逆乘法能给我

[[0, 0, 10000],
 [0, 0, 0    ],
 [0, 0, 0    ]]

但是我得到了一些不同的东西,更接近

[[10000, 0, 0],
 [10000, 0, 0],
 [10000, 0, 0]]

有人知道发生了什么吗?抱歉,我猜我对 fft 有什么误解。

【问题讨论】:

  • 嗯,我得到的输出与我预期的不同,我认为可以肯定地说这是因为我不明白我在这里做的事情,而不是电脑犯了一个错误
  • 您看到的是边缘效应。要正确执行此操作,您需要在所有方向上以 ~1/2 的大小对两个数组进行零填充。另外,我认为您希望在最后一步中使用np.fft.ifftn (c)。
  • 对不起,我是想写 ifftn。我来看看边缘效果,谢谢
  • 等一下,我最后没有 n...现在试了一下,看起来效果更好。现在左上角只有一个 1000 条目。谢谢指出
  • @Franz - 很高兴它正在工作!不过,总的来说,您仍然需要担心边缘效应。请注意,fft/fft2/fftn/etc 都采用 shape 参数,如果您将要填充的形状传递给它,它将处理零填充。

标签: python arrays numpy fft correlation


【解决方案1】:

您应该改用scipy.signal.fftconvolve

它已经实现并经过了广泛的测试,特别是在处理边界方面。在 2D 中从卷积到相关算子所需的唯一额外步骤是将滤波器阵列旋转 180°(参见 answer)。

【讨论】:

    【解决方案2】:

    如果你必须自己实现,你应该知道频域中的乘法对应于时域中的circular convolution。要获得所需的线性卷积,您需要用零填充两个数组,长度至少是原始矩阵大小的两倍1

    s = [2*x for x in np.shape(A)]
    a = np.conj(np.fft.fftn(A,s))
    b = np.fft.fftn(B,s)
    c = np.fft.ifftn(a*b)
    

    1 严格来说,大小为 2n-1(而不是 2n)就可以了,但 FFT 在处理小素因数的倍数时往往表现更好。子>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-10
      • 2011-07-12
      • 2011-04-21
      相关资源
      最近更新 更多