计算互相关函数?

Posted

技术标签:

【中文标题】计算互相关函数?【英文标题】:Computing cross-correlation function? 【发布时间】:2011-10-22 22:01:50 【问题描述】:

R 中,我使用ccfacf 来计算成对互相关函数,以便找出哪个移位给了我最大值。从外观上看,R 给了我一个标准化的值序列。 Python的scipy中是否有类似的东西,或者我应该使用fft模块来做吗?目前,我的做法如下:

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)

【问题讨论】:

【参考方案1】:

要交叉关联一维数组,请使用numpy.correlate。

对于二维数组,使用scipy.signal.correlate2d。

还有scipy.stsci.convolve.correlate2d。

还有基于 numpy.correlate 的 matplotlib.pyplot.xcorr。

有关不同实现的一些链接,请参阅 this post on the SciPy mailing list。

编辑:@user333700 在评论中添加了指向SciPy ticket for this issue 的链接。

【讨论】:

从该邮件列表帖子链接的实现肯定使用 FFT,也许它们会有所帮助。另外,我不知道发帖者的速度是多少。 np.correlate 不使用 fft,并且仅当第二个系列/窗口相对于第一个较小时才会更快。还有 scipy.signal.fftconvolve。另见projects.scipy.org/numpy/ticket/1260 所有邮件列表链接都坏了!! ;-( @AndreAraujo 我更新了 SciPy 票证的链接以指向互联网档案,因为原始页面似乎已经消失了。所有其他链接(包括邮件列表链接)都对我有用。【参考方案2】:

如果您正在寻找一维或二维的快速、标准化互相关 我会推荐 openCV 库(参见 http://opencv.willowgarage.com/wiki/ http://opencv.org/)。该组维护的互相关代码是您会发现的最快的,并且会被归一化(结果在 -1 和 1 之间)。

虽然这是一个 C++ 库,但代码使用 CMake 维护并具有 python 绑定,因此可以方便地访问互相关函数。 OpenCV 也可以很好地与 numpy 配合使用。如果我想从 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)

对于一维互相关,创建一个形状等于 (N, 1 ) 的二维数组。虽然需要一些额外的代码来转换为 openCV 格式,但 scipy 的加速效果令人印象深刻。

【讨论】:

仅供参考,如果您不想使用 OpenCV,也可以使用 scikit-image 执行此操作。见this example。【参考方案3】:

我刚刚为 N 维数组编写了自己的规范化互相关优化实现。您可以从 here 获得它。

它将直接使用scipy.ndimage.correlate 计算互相关,或者在频域中使用scipy.fftpack.fftn/ifftn 计算互相关,具体取决于哪个最快。

【讨论】:

【参考方案4】:

对于一维数组,numpy.correlatescipy.signal.correlate 快​​,在不同的尺寸下,我看到使用numpy.correlate 的性能增益是一致的 5 倍。当两个阵列大小相似时(连接对角线的亮线),性能差异更加突出(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))

默认情况下,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]

【讨论】:

以上是关于计算互相关函数?的主要内容,如果未能解决你的问题,请参考以下文章

互相关函数以及Matlab仿真

Matlab_xcorr_互相关函数的讨论 [未完成]

关于互相关函数的一些问题,希望懂的人能给我一些帮助,感激不尽!!!

Qt--SLOT槽函数相关

数字信号处理相关函数 ( 能量信号 | 能量信号的互相关函数 | 能量信号的自相关函数 )

数字信号处理相关函数 ( 能量信号 | 能量信号的互相关函数 | 能量信号的自相关函数 )