Вычислить функцию взаимной корреляции?
В R
я использую ccf
или acf
для вычисления парной функции взаимной корреляции, чтобы я мог узнать, какой сдвиг дает мне максимальное значение. По внешнему виду, 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
Для кросс-корреляции массивов 1d используйте numpy.correlate.
Для 2d массивов используйте scipy.signal.correlate2d.
Существует также scipy.stsci.convolve.correlate2d.
Существует также matplotlib.pyplot.xcorr, основанный на numpy.correlate.
См. этот пост в списке рассылки SciPy для некоторых ссылок на различные реализации.
Изменить: @user333700 добавил ссылку на билет SciPy для этой проблемы в комментарии.
Ответ 2
Если вы ищете быструю нормализованную взаимную корреляцию в одном или двух измерениях
Я бы порекомендовал библиотеку openCV (см. http://opencv.willowgarage.com/wiki/ http://opencv.org/). Кодекс взаимной корреляции, поддерживаемый этой группой, является самым быстрым, который вы найдете, и он будет нормализован (результаты между -1 и 1).
Хотя это С++-библиотека, код поддерживается с помощью 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 довольно впечатляет.
Ответ 3
Я только что закончил писать собственную оптимизированную реализацию нормированной кросс-корреляции для N-мерных массивов. Вы можете получить его от здесь.
Он будет вычислять кросс-корреляцию либо напрямую, используя scipy.ndimage.correlate
, либо в частотной области, используя scipy.fftpack.fftn
/ifftn
в зависимости от того, что будет быстрее.