简体   繁体   English

如何实现快速傅里叶变换来关联两个2d阵列?

[英]How to implement the fast fourier transform to correlate two 2d arrays?

I want to do this with larger arrays, but so that I can understand it, i'll use a smaller example. 我想用更大的数组来做这个,但为了让我能理解它,我将使用一个更小的例子。

Let's say I have the following array: 假设我有以下数组:

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

If I want to calculate the correlation of this array with another, by multiplying the corresponding entries. 如果我想通过乘以相应的条目来计算此数组与另一个数组的相关性。 For example, A*A would be equal to A (1*1 = 1, zeros everywhere else). 例如,A * A将等于A(1 * 1 = 1,其他地方为零)。 I read that fast fourier transforms can be used to speed this up with large arrays. 我读到快速傅里叶变换可以用来加速大型阵列。 From what I read, I got the impression if I wanted to multiply two arrays A and B, as in A*B, that I could do it quicker with the following (using numpy in python): 根据我的阅读,我得到的印象是,如果我想将两个数组A和B相乘,就像在A * B中一样,我可以使用以下内容(在python中使用numpy)更快地完成:

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

So in effect, take the fft of A, take the fft of B, multiply the two results, and then get the inverse of that result. 因此,实际上,取A的fft,取B的fft,乘以两个结果,然后得到该结果的倒数。 However, I tried it with the case of A given above, multiplying itself. 但是,我用上面给出的A的情况尝试了它,乘以它自己。 I had hoped the inverse multiplication would give me 我曾希望反向乘法会给我

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

However I got something a bit different, closer to 然而,我有点不同,更接近

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

does anyone know what's going on? 有谁知道发生了什么? Sorry, I'm guessing there's something I'm misunderstanding about the fft. 对不起,我猜我有一些关于fft的误解。

You should use scipy.signal.fftconvolve instead. 您应该使用scipy.signal.fftconvolve

It is already implemented and has been extensively tested, particularly regarding the handling the boundaries. 它已经实施并经过广泛测试,特别是在处理边界方面。 The only additional step necessary to go from the convolution to the correlation operator in 2D is to rotate the filter array by 180° (see this answer ). 在2D中从卷积到相关运算符所需的唯一额外步骤是将滤波器阵列旋转180°(参见本答案 )。

If you must implement your own, you should be aware that multiplication in the frequency domain corresponds to circular convolution in the time domain. 如果必须实现自己的,则应注意频域中的乘法对应于时域中的循环卷积 To obtain the desired linear convolution you need to pad both arrays with zeros, to a length at least twice the size of your original matrix 1 : 要获得所需的线性卷积,您需要用零填充两个数组,其长度至少是原始矩阵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 strictly speaking a size of 2n-1 (instead of 2n) will do, but FFTs tend to perform better when operating on sizes that are multiples of small prime factors. 严格来说, 1的大小为2n-1(而不是2n),但是当操作尺寸为小素因子的倍数时,FFT往往表现更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM