Python中高效的2D互相关?

时间:2018-07-23 18:28:07

标签: python optimization scipy

我有两个数组,大小为(n, m, m)n个图像,大小为(m,m))。我想在两个数组的每个对应的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 个答案:

答案 0 :(得分:3)

我决定改为通过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]

致电通过:

ts=fft_xcorr2D(X)

如果有人要使用它: 我的输入是一个4D数组:(N, 2, #Rows, #Cols)

例如(500, 2, 30, 30)30x30像素的2个波段(例如偏振)的500张图像

如果您输入的内容不同,请根据自己的喜好调整填充 请检查您的输入顺序是否与我的输入顺序相同,否则请更改fft2ifft2函数,np.prod和fftshift中的axis参数。我使用fftshift来获取中间的最大值(否则在角落),因此请谨慎使用,这不是您想要的。

为什么是最大值?从技术上讲,它不是必须的,但就我的目的而言是。 fftshift用于获得看起来像您惯常的关联。否则,象限将“由内而外”翻转。如果您想知道我的意思,请删除fftshift(只是fftshift部分,而不是其参数),像以前一样调用该函数并绘制它。

之后,应该可以使用了。 Possibly x.prod(axis=1) is faster than np.prod(x,axis=1),但它是旧帖子。尝试后对我来说没有任何改善。