python - array - ¿Computing función de correlación cruzada?
describe np array (3)
Acabo de terminar de escribir mi propia implementación optimizada de correlación cruzada normalizada para matrices N-dimensionales. Puedes obtenerlo desde here .
Calculará la correlación cruzada directamente, usando scipy.ndimage.correlate
, o en el dominio de frecuencia, usando scipy.fftpack.fftn
/ ifftn
dependiendo de cuál sea el más rápido.
En R
, estoy usando ccf
o acf
para calcular la función de correlación cruzada por pares para poder averiguar qué cambio me da el valor máximo. Por lo que parece, R
me da una secuencia normalizada de valores. ¿Hay algo similar en Python''s scipy o se supone que debo hacerlo usando el módulo fft
? Actualmente, lo estoy haciendo de la siguiente manera:
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)
Para correlacionar de forma cruzada matrices 1d use numpy.correlate .
Para arreglos en 2D, use scipy.signal.correlate2d .
También hay scipy.stsci.convolve.correlate2d .
También hay matplotlib.pyplot.xcorr que se basa en numpy.correlate.
Consulte esta publicación en la lista de correo de SciPy para obtener algunos enlaces a diferentes implementaciones.
Editar: @ user333700 agregó un enlace al boleto SciPy para este problema en un comentario.
Si está buscando una correlación cruzada rápida y normalizada en una o dos dimensiones, recomendaría la biblioteca openCV (ver http://opencv.willowgarage.com/wiki/ http://opencv.org/ ). El código de correlación cruzada mantenido por este grupo es el más rápido que encontrará, y se normalizará (resultados entre -1 y 1).
Si bien esta es una biblioteca C ++, el código se mantiene con CMake y tiene enlaces de python para que el acceso a las funciones de correlación cruzada sea conveniente. OpenCV también juega muy bien con numpy. Si quisiera calcular una correlación cruzada 2-D a partir de matrices numpy, podría hacerlo de la siguiente manera.
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)
Para una correlación cruzada 1-D, cree una matriz 2-D con forma igual a (N, 1). Aunque hay un código adicional involucrado para convertir a un formato openCV, la aceleración sobre scipy es bastante impresionante.