Normalized Cross-Correlation in Python
Asked Answered
P

4

24

I have been struggling the last days trying to compute the degrees of freedom of two pair of vectors (x and y) following reference of Chelton (1983) which is:

degrees of freedom according to Chelton(1983)

and I can't find a proper way to calculate the normalized cross correlation function using np.correlate, I always get an output that it isn't in between -1, 1.

Is there any easy way to get the cross correlation function normalized in order to compute the degrees of freedom of two vectors?

Pirri answered 22/11, 2018 at 18:4 Comment(2)
Article on the topic ncbi.nlm.nih.gov/pmc/articles/PMC6147431 All links are there.Momus
Here is a nice answer: https://mcmap.net/q/402401/-how-to-interpret-the-values-returned-by-numpy-correlate-and-numpy-corrcoef/987846Sonatina
F
19

Nice Question. There is no direct way but you can "normalize" the input vectors before using np.correlate like this and reasonable values will be returned within a range of [-1,1]:

Here i define the correlation as generally defined in signal processing textbooks.

c'_{ab}[k] = sum_n a[n] conj(b[n+k])

CODE: If a and b are the vectors:

a = (a - np.mean(a)) / (np.std(a) * len(a))
b = (b - np.mean(b)) / (np.std(b))
c = np.correlate(a, b, 'full')

References:

https://docs.scipy.org/doc/numpy/reference/generated/numpy.correlate.html

https://en.wikipedia.org/wiki/Cross-correlation

enter image description here

Faustofaustus answered 22/11, 2018 at 18:12 Comment(5)
I tried it but now it does get values until 2, doesn't stay <2. Is ok if this happens?Gonagle
can you post here in the comments an example of this?Faustofaustus
@makis , why are you multiplying the standard deviation with len(a) at your code example?Laboy
@RonU len(a) means scipy doc or matlab doc 's N which is equivalent to max(len(a), len(b)). So, c = np.correlate(normalized_a, normalized_b, 'full') / max(len(a), len(b)) may be more understandable.Andromada
I am using this for two numpy 2D matrices and getting a ValueError: object too deep for desired arrayAirfield
P
9

MATLAB ➜ xcorr(a, b, 'normalized');

MATLAB normalized cross-correlation implementation in Python.

import numpy as np
a = [1, 2, 3, 4]
b = [2, 4, 6, 8]
norm_a = np.linalg.norm(a)
a = a / norm_a
norm_b = np.linalg.norm(b)
b = b / norm_b
c = np.correlate(a, b, mode = 'full')
Psychogenesis answered 6/2, 2022 at 9:27 Comment(1)
This is giving me exactly what matlab's normalized xcorr returns!Edlun
C
1

If you are interested in the normalized correlation when the sequences are aligned (not the correlation function of the correlation versus time offsets), the function numpy.corrcoef does this directly, as computing the covariance matrix of x and y and then normalizing it by the standard deviation of x and the standard deviation of y.

https://numpy.org/doc/stable/reference/generated/numpy.corrcoef.html#numpy.corrcoef

This is the Pearson correlation coefficient and will have a range of +/-1.

Cholla answered 26/11, 2021 at 21:47 Comment(0)
A
-1

a = np.dot(abs(var1),abs(var2),'full')

b = np.correlate(var1,var2,'full')

c = b/a

This is my idea: but it will normalize it 0-1

Animation answered 27/11, 2019 at 13:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.