1
$\begingroup$

I have two vectors of matching lengths. They are readings from two different sensors (one is from a smartphone and the other is from a wiimote) of the same hand movement. I am trying to find the time offset between them to synchronise the readings for further processing. The readings I get are of the format (Time(ms) Value) for accelerations in the X,Y and Z direction.

For the synchronization, I plotted the cross-correlation function xcorr2() between the two sets. I am getting the same graph (a weird triangle peak and a straight line at the bottom) for Accelerations along the x, y and z directions (which I guess is good) but I don't know how to interpret it. What do the axes in the graph represent?

Can anyone explain to me what xcorr2() means in a qualitative sense. From the correlation function, how do I determine the offset (i.e. how many seconds is sensor1 behind sensor2)?

Thanks!

Imelza

enter image description here

  • 0
    Wouldn't this be more appropriate for http://math.stackexchange.com?2011-02-15
  • 0
    You will probably get a better answer from http://stats.stackexchange.com/2011-02-15

2 Answers 2

1

The peak of the triangle represents your offset. If the two vectors were identical, the peak would appear exactly in the center. If they are offset from each other, the peak will occur offset from the center.

I'd do an experiment and correlate a vector with itself. Then use a function like argmax() to find the index of the maximum position. It should be len(vector)/2 plus or minus 1. Then do the correlation of the two different signals, and do argmax on that. Subtract the value you just found for identical vectors, and you will have your offset. If you reverse the order of the signals, the offset will be negative.

Remember that there are different implementations of correlation, like a circular cross-correlation, where the signals are wrapped around. You don't want that. If the Matlab function is a circular cross-correlation (FFT-enhanced), then you need to zero pad first. Read into the different implementations and options of xcorr2.

Here's a simple example in Python.

  • 0
    I like the simplicity of the results from `rxy = real(irfft(rfft(x, K) * conj(rfft(y, K))))`, where x is length L, y is length M, and K is L+M-1 rounded to the next even number (due to using rfft). The L non-negative lags are at rxy[:L], and the M-1 negative lags are at rxy[:-M:-1]. For example, the 1st positive lag is at rxy[1], and the 1st negative lag is at rxy[-1], and the 0 lag is at rxy[0].2011-02-18
  • 0
    (Meta: I can't say that I like this font, though. Maybe it's an issue with my browser, Chrome, but it looks squished, and the number 0 looks like the letter o.)2011-02-18
  • 0
    Also, using numpy.fft.rfft is about 3 times faster than scipy.signal.fftconvolve. I wouldn't use numpy.correlate or scipy.signal.correlate on arrays longer than about 2**15 -- it's way too slow. Likewise, matplotlib.pyplot.xcorr uses numpy.correlate.2011-02-18
  • 0
    @eryksun: Does your version include this change? http://projects.scipy.org/scipy/browser/trunk/scipy/signal/signaltools.py?rev=5968 http://projects.scipy.org/numpy/ticket/12602011-02-18
  • 0
    @endolith: Yes, it does. But fftconvolve is using scipy.fftpack.fftn, which computes the negative frequencies. numpy.fft.rfft only computes the non-negative frequencies, returning an array sized N/2+1.2011-02-18
  • 0
    @endolith: As to the NumPy ticket, it doesn't look like any progress was made on the proposal, and it was unscheduled. cdavid mentions adding an FFT-based version to NumPy, but I suppose they decided that scipy.signal.fftconvolve based on fftpack's fftn is sufficient.2011-02-18
  • 0
    Hi, thanks for the reply. I just did the correlation of one vector with itself.. and my maximum is NOT length(vector)/2 .. its about 200 samples off.. do you know why that could happen? One important (and possibly extremely stupid) question is that the vector is a single row vector of values (I store time in a different vector) The sampling is not uniformly spaced, so how do I account for this?2011-03-10
  • 0
    @Imelza I don't know how to do correlations with non-uniformly sampled data. See Graham's answer about interpolation.2011-03-11
  • 0
    Yes, I resampled it to be uniform and your method works now. Thanks a lot!!2011-03-17
1

@Imelza If the data is not uniformly sampled in time, xcorr will not work correctly (and shifting it by samples will not give the right correspondence.) You could use interp1 to resample it uniformly first.

  • 0
    also, you may be getting 200 samples off because the default lags are bipolar--they start from negative lags. You can get the lags xcorr is using with [c,lags] = xcorr(a,b);2011-03-11
  • 1
    Thanks! I resampled the data uniformly and it pretty much worked. Thanks very much!2011-03-17