# Cross-correlation, sharp peak at 0?

First of all, I have to stress that I am not a professional of coding, no more than a professional of signal processing. I am a chemist that happen to be working on a project involving both. So in advance, please forgive me if my questions are not well worded, or seem trivial to you (in addition, I am not a native english speaker). I have several questions that are not directly related to each other, so I might open several threads as I got answers.

So, I am working on a project involving the interference patern of a laser, and more importantly, shifting of this pattern alongside the horizontal (x) axis. Here is the typical diffraction pattern I observe through my camera :

My goal is to precisely measure the shift of that pattern that happens during my experiment. For a better understanding of what I mean, I attach an exemple with a signal shifted from the other.Keep in mind that the shift presented here, that is of about 40 pixels, is considered HUGE, and will never really happen during my work, I am typically observing shift of about 0-5 pixels.

To achieve this goal, I wrote a C# code that computes the cross-correlation between two arrays (I reduced my image to a single 1024 pixels line, by calculating the mean of the signal alongside each 768 pixels row). The cross-correlation has been computed using this forumula (using the Accord Framework):

corr(a, b) = ifft(fft(a_and_zeros) * conj(fft(b_and_zeros))).

The code seems to work, here is the kind of cross-correlation figure I get :

This particular figure is obtained when cross-correlating two identical images (I guess I could call it auto-correlation, but I am not sure, and, as expected, I find a shift of 0 pixels). Keep in mind that this figure is the product of a modification of the cross-correlation results array, as applying Fast Fourier Transform results in the peak being "cut in half" at the edge of the array.

My problem arise when I zoom on the peak :

As you see, the peak is sharp, and I think it should be smooth. This is a problem when I want to observe low shift, as the "sharpness" of the peak hides the real maximum :

The problem disappears when the shift becomes bigger, but then the presence of a really sharp peak I can't explain is exposed :

Note that this peak doesn't come from me modifying the array to center the peak, it is present at the edge if I don't modify the results.

This ends up with my results not being realistic for low shifts (AKA the shifts I care about) as shown here :

As you can see, things are not exactly on point (this is the very start of the project, so the experimental setup is far from perfect, as is the code), but the tendancy is there, and I would really be able to solve this peak issue before going further.

So I come to you in hope of finding out why my experiment are behaving this way, and what I could do about it ! Is there a reason linked to the way cross-correlation works, or something else ? I couldn't find any issue in the code, as of now.

Thanks a lot !

• Your image might be too blurry to use with small shifts. I wish I could help more, I only used cross-corelation with 1-D signals, never with images. Second of all, you could use Python or Octave for data processing, simpler and more powerful than C# especially for prototyping. They're both free.
– Ben
May 16, 2018 at 12:22
• Also your image seems to be saturated, it will be harder for cross-correlation to work well. Can you acquire images without saturation and try again?
– Ben
May 16, 2018 at 12:28
• Yes, the images are highly saturated here, but it is because I just took them for this example. During my experiments I change the exposure time of the camera so I am sure there is no saturation ! As I said in the OP, I do 1D cross-correlation here. I reduce each image to an array of 1024 values before processing. I tried using 2D cross-correlation before, but it was much slower and didn't have much interest for me. I'll look into Python, but Id rather use only one language. My goal is to have a unique software to do everything related to my setup. May 16, 2018 at 12:37

Since your shift is going to be in the 0-5 pixel range, I am assuming you are going to want a method that gives you sub-sample accuracy.

I have a suggestion for you to try. Read my article Exponential Smoothing with a Wrinkle and apply the technique to your 1D signal. Look for some matching zero crossings in the difference case near the center of your data frame. You should be able to determine the zero crossing by linear interpolation of the two nearest points, or do linear regression on the nearest four or five. The linear interpolation should be sufficient. You should be able to measure the shift at several zero crossings. If it is a true shift, all the values you calculate should be the same. Average them for noise mitigation.

This method is easy to code and takes way fewer calculations than the method you are using.

BTW, that is a very good presentation of your question.

Ced

• You're right, I want sub-sample accuracy, and my next question following this one would have been about a parabolic interpolation method. Thanks a lot for your answer, I will read your article with interest ! I'll keep you updated if I decide to switch to your method, but it seems interesting. May 16, 2018 at 14:21
• @Trion, Actually reading the article may not be necessary as it is mostly a treatment of the method on a pure tone. All you need to do is smooth your signal in a forward direction, then smooth it in the backward direction. Take the difference of the two results, plot it, look at it, and I'm sure you can figure out what to do from there. May 16, 2018 at 14:27
• I read it anyway ;) This is indeed very interesting and could work for me, if it wasn't for the peak dilatation that I am pretty sure does occur along with the shift. Anyway, I will discuss it with my boss tomorrow, maybe the dilatation is negligible at our scale. May 16, 2018 at 15:18
• @Trion, If the dilation is symmetric, then it won't impact the results. The nice thing about the differences approach is that it washes out any DC bias and the zero crossings correspond to the peaks and valleys. If the "humps" are symmetric, the zero crossings very accurately mark the peaks. If the humps are asymmetric, and they are consistently so, the shift in the zero crossing locations will correspond to the peak location shifts precisely. The smoothing will mitigate the effects of noise and pixelation of your image. I think you should do the plots so you have something to discuss. May 16, 2018 at 16:22
• @Trion, I'm kind of surprised that the precision isn't good enough. You could also try doing the cross correlation on the smoothed signals and a parabolic fit on the peak. Jun 2, 2018 at 14:31