Python中高效的2D互相关?

7
我有两个大小为(n,m,m)的数组(n表示大小为(m,m)n张图像)。我想在这两个数组中的每个对应的n之间执行交叉相关。
例如:n=1 -> corr2d([m,m]<sub>1</sub>,[m,m]<sub>2</sub>) 我的当前方法在Python中包含一堆for循环。
for i in range(len(X)):
    X_co = X[i,0,:,:]/(np.max(X[i,0,:,:]))
    X_x = X[i,1,:,:]/(np.max(X[i,1,:,:]))
    autocorr[i,0,:,:]=correlate2d(X_co, X_x, mode='same', boundary='fill', fillvalue=0)

显然,当输入包含许多图片时,这种方法非常缓慢,并且如果 (m,m) << n.,它会成为总运行时间的重要组成部分。
明显的优化是跳过循环并将所有内容直接馈送到已编译的相关函数中。目前我正在使用scipy的correlate2d。我查找了一些函数,但没有找到允许沿某个轴或多个输入进行相关操作的函数。
有关如何使scipy的correlate2d起作用或替代方法的任何提示吗?
1个回答

8

我决定通过FFT来实现它。

def fft_xcorr2D(x):
    # Over axes (-2,-1) (default in the fft2 function)
    ## Pad because of cyclic (circular?) behavior of the FFT
    x = np.fft2(np.pad(x,([0,0],[0,0],[0,34],[0,34]),mode='constant'))

    # Conjugate for correlation, not convolution (Conv. Theorem)
    x[:,1,:,:] = np.conj(x[:,1,:,:])

    # Over axes (-2,-1) (default in the ifft2 function)
    ## Multiply elementwise over 2:nd axis (2 image bands for me)
    ### fftshift over rows and column over images
    corr = np.fft.fftshift(np.ifft2(np.prod(x,axis=1)),axes=(-2,-1))

    # Return after removing padding
    return np.abs(corr)[:,3:-2,3:-2]

Call via:

ts=fft_xcorr2D(X)

如果有人想使用它: 我的输入是一个4D数组:(N, 2, #Rows, #Cols) 例如:(500, 2, 30, 30):500张图片,2个波段(极化,例如)的30x30像素
如果你的输入不同,请根据你的需要调整填充 检查你的输入顺序是否与我的相同,否则改变fft2ifft2函数中的轴参数,np.prod和fftshift。我使用fftshift来使最大值在中间(而不是在角落),因此如果这不是你想要的,请小心。
为什么是最大值?从技术上讲,它不必是,但对于我的目的来说,它是。 fftshift用于获得看起来你习惯的相关性。否则,象限会被“翻转”。如果您想知道我是什么意思,请删除fftshift(只删除 fftshift 部分,不删除其参数),然后像以前一样调用函数并绘制它。
之后,它应该可以使用了。 可能x.prod(axis=1)比np.prod(x,axis=1)更快,但那是一篇旧帖子。在我尝试后没有任何改进。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接