简体   繁体   English

计算互相关函数?

[英]Computing cross-correlation function?

In R , I am using ccf or acf to compute the pair-wise cross-correlation function so that I can find out which shift gives me the maximum value. R ,我使用ccfacf来计算成对的互相关函数,这样我就可以找出哪个移位给了我最大值。 From the looks of it, R gives me a normalized sequence of values. 从它的外观来看, R给了我一个标准化的值序列。 Is there something similar in Python's scipy or am I supposed to do it using the fft module? 在Python的scipy中是否有类似的东西,或者我应该使用fft模块来做它? Currently, I am doing it as follows: 目前,我的工作如下:

xcorr = lambda x,y : irfft(rfft(x)*rfft(y[::-1]))
x = numpy.array([0,0,1,1])
y = numpy.array([1,1,0,0])
print xcorr(x,y)

To cross-correlate 1d arrays use numpy.correlate . 要使1d数组进行交叉关联,请使用numpy.correlate

For 2d arrays, use scipy.signal.correlate2d . 对于2d数组,请使用scipy.signal.correlate2d

There is also scipy.stsci.convolve.correlate2d . 还有scipy.stsci.convolve.correlate2d

There is also matplotlib.pyplot.xcorr which is based on numpy.correlate. 还有matplotlib.pyplot.xcorr ,它基于numpy.correlate。

See this post on the SciPy mailing list for some links to different implementations. 有关不同实现的链接,请参阅SciPy邮件列表中的这篇文章

Edit: @user333700 added a link to the SciPy ticket for this issue in a comment. 编辑:@ user333700在评论中为此问题添加了SciPy票证的链接。

If you are looking for a rapid, normalized cross correlation in either one or two dimensions I would recommend the openCV library (see 如果您正在寻找一维或二维的快速,标准化的互相关,我会推荐openCV库(参见 http://opencv.willowgarage.com/wiki/ http://opencv.willowgarage.com/wiki/ http://opencv.org/ ). http://opencv.org/ )。 The cross-correlation code maintained by this group is the fastest you will find, and it will be normalized (results between -1 and 1). 由该组维护的互相关代码是您将找到的最快,它将被标准化(结果在-1和1之间)。

While this is a C++ library the code is maintained with CMake and has python bindings so that access to the cross correlation functions is convenient. 虽然这是一个C ++库,但代码是使用CMake维护的,并且具有python绑定,因此可以方便地访问互相关函数。 OpenCV also plays nicely with numpy. OpenCV也很适合numpy。 If I wanted to compute a 2-D cross-correlation starting from numpy arrays I could do it as follows. 如果我想从numpy数组开始计算二维互相关,我可以按如下方式进行。

import numpy
import cv

#Create a random template and place it in a larger image
templateNp = numpy.random.random( (100,100) )
image = numpy.random.random( (400,400) )
image[:100, :100] = templateNp

#create a numpy array for storing result
resultNp = numpy.zeros( (301, 301) )

#convert from numpy format to openCV format
templateCv = cv.fromarray(numpy.float32(template))
imageCv = cv.fromarray(numpy.float32(image))
resultCv =  cv.fromarray(numpy.float32(resultNp))

#perform cross correlation
cv.MatchTemplate(templateCv, imageCv, resultCv, cv.CV_TM_CCORR_NORMED)

#convert result back to numpy array
resultNp = np.asarray(resultCv)

For just a 1-D cross-correlation create a 2-D array with shape equal to (N, 1 ). 对于仅1-D互相关,创建形状等于(N,1)的2-D阵列。 Though there is some extra code involved to convert to an openCV format the speed-up over scipy is quite impressive. 虽然转换为openCV格式需要一些额外的代码,但scipy的加速速度令人印象深刻。

I just finished writing my own optimised implementation of normalized cross-correlation for N-dimensional arrays. 我刚刚为N维数组编写了自己的规范化互相关优化实现。 You can get it from here . 你可以从这里得到它。

It will calculate cross-correlation either directly, using scipy.ndimage.correlate , or in the frequency domain, using scipy.fftpack.fftn / ifftn depending on whichever will be quickest. 它将使用scipy.ndimage.correlate直接计算互相关,或者在频域中使用scipy.fftpack.fftn / ifftn计算互相关,具体取决于哪个最快。

For 1D array, numpy.correlate is faster than scipy.signal.correlate , under different sizes, I see a consistent 5x peformance gain using numpy.correlate . 对于1D数组, numpy.correlatescipy.signal.correlate更快,在不同的大小下,我看到使用numpy.correlate一致的5倍性能增益。 When two arrays are of similar size (the bright line connecting the diagonal), the performance difference is even more outstanding (50x +). 当两个阵列具有相似的尺寸(连接对角线的亮线)时,性能差异更加突出(50x +)。

# a simple benchmark
res = []
for x in range(1, 1000):
    list_x = []
    for y in range(1, 1000): 

        # generate different sizes of series to compare
        l1 = np.random.choice(range(1, 100), size=x)
        l2 = np.random.choice(range(1, 100), size=y)

        time_start = datetime.now()
        np.correlate(a=l1, v=l2)
        t_np = datetime.now() - time_start

        time_start = datetime.now()
        scipy.signal.correlate(in1=l1, in2=l2)
        t_scipy = datetime.now() - time_start

        list_x.append(t_scipy / t_np)
    res.append(list_x)
plt.imshow(np.matrix(res))

在此输入图像描述

As default, scipy.signal.correlate calculates a few extra numbers by padding and that might explained the performance difference. 默认情况下,scipy.signal.correlate通过填充计算一些额外的数字,这可能解释了性能差异。

>> l1 = [1,2,3,2,1,2,3]
>> l2 = [1,2,3]
>> print(numpy.correlate(a=l1, v=l2))
>> print(scipy.signal.correlate(in1=l1, in2=l2))

[14 14 10 10 14]
[ 3  8 14 14 10 10 14  8  3]  # the first 3 is [0,0,1]dot[1,2,3]

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

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