Finding the how much two curve got shifted ?

I have two different image from those I have drawn two different intensity profile along the column profile.
I have attached those both curves. Can anyone suggest me how much the test imaage intensity curve shifted from the reference image intensity through matlab code or matlab built in function? I have tried finddelay function but it gives me answer 0 which is obviously not true in this case.

 Accepted Answer

[edit: I tried xcorr() and did notlike the results. xcorr() does not have a normalization option that I like. Therefore I wrote a for loop, to compute the Pearson correlation between the two waveforms, with different lags.]
I see that you attached an image. Please attach the actual data.
It does not look like a simple sideways shift. It looks more complicated.
Find the lag where the cross correlation is maximal. It seems obvious to use xcorr(), but none of the xcorr() normalization options gives good results in this case.
t=1:34;
x=45*sin(2*pi*t/20)./(2*pi*t/20)+160; % ref., green
y=40*sin(2*pi*t/30)./(2*pi*t/30)+170; % test blue
plot(t,x,'-g',t,y,'-b'); legend('x=Test','y=Ref.'); grid on
Curves above are similar to your curves.
Limit the lags (m) to +-20, because the signal is only 34 points long.
N=length(x);
maxLag=20;
for m=-maxLag:maxLag % m>0: shift y to the right
xSeg=x(max(1+m,1):min(N+m,N));
ySeg=y(max(1-m,1):min(N-m,N));
rho=corrcoef(xSeg,ySeg); % rho = 2x2 matrix
xyCorr(m+maxLag+1)=rho(1,2); % save the off diagonal element
end
plot(-maxLag:maxLag,xyCorr,'-r.'); grid on
Find the lag corresponding to max correlation.
[maxCorr,idx]=max(xyCorr);
bestLag=idx-maxLag-1;
Show that best lag point on the plot:
hold on; plot(bestLag,maxCorr,'bd','MarkerFaceColor','b')
Plot x and y, with y shifted by bestLag:
xPlot=x(max(1+bestLag,1):min(N+bestLag,N));
yPlot=y(max(1-bestLag,1):min(N-bestLag,N));
nP=length(xPlot);
figure;
plot(1:nP,xPlot,'-g.',1:nP,yPlot,'-b.')
legend('x=Test','y(shifted)=Ref(shifted)')

6 Comments

@William Rose Thank you very much.
Can you explain :
1) why to Limit the Lags between +-20
2) If I want to shift the x curve towards the y , how the code will be change ? ( I assume then lag limit will be 0 to 20)
You are welcome.
I chose +- 20 lags max because the signal is only 34 points long. By the time it has shifted +-20, the two signals overlap by less than half their length, which is not very much overlap.
When you say "if I wanted to shift the x toward y...", I'm not sure what you mean by "toward". Since we tested +-20 lags, we tested shifts in both directions, and this can be regarded as x going on way, or y going the other.
The way my code is written, when m>0, y is shifted to the right relative to x, or equivalently, x is shifted to the left relative to y. If you want to investigate leftward shifts of x relative to y, use m>=1, and so on.
I chose m>0 to correspond to rightward shifts of y relative to x, to be consistent with Matlab's xcorr(). The xcorr() help says
The cross correlation articles in Wikipedia and Wolfram Mathworld use the opposite sign convention for lags:
Therefore I always triple-check the sign convention for the lags, whenever I use a cross-correlation function.
@William Rose Thank you very very much for your detailed answer. This helped me to understand the whole concept as I was also studying this for my own and this is why I am replying you late. One more question , and it is last.
Plot x and y, with y shifted by bestLag: Is this portion of code can be written using matlab built in function circularshift ( circshift) ? If not, then why?
@Amit, circshift will wrap the points around as they go off the end, so x(N) moves to x(1), or vice versa, depending on which way you are shifting. And in your case, such a wraparound would not be desirable.
x=[sin(2*pi*(0:10)/20),zeros(1,10)];
plot(0:20,x,'-r.',0:20,circshift(x,-5),'-gx',0:20,circshift(x,15),'-bo');
legend('circshift 0','circshift -5','circshift +15')
I have found correlation analysis to be useful in several research studies. I recommend that you generate some simulated data with known delay relationships, to test any code that you write. This helps me test my code and cofirms my understanding of the meaning of "positive" and "negative" lags for my particular situation and software.
@William Rose Thanks again for your kind help.
Can I ask one more question?
rho = 2x2 matrix; but why you save the off only the diagonal element?
Thank you in Advance !
I should have just used corr(x',y'). I tried corr(x,y) and it gave a matrix of NaNs because I had fogotten that you must use column vectors for corr(). So I used corrcoef(x,y), which returns a 2x2 matrix, and I took the off diagonal element. That wasn't very smart of me. Either off-diagonal is fine, since they are equal.
x=rand(1,10); y=rand(1,10);
corrcoef(x,y)
ans = 2×2
1.0000 0.2021 0.2021 1.0000
% For the result above, rho(1,1)=corr(x,x)=1;
% and rho(1,2)=corr(x,y);
% and rho(2,1)=corr(y,x)=rho(1,2);
% and rho(2,2)=corr(y,y)=1
corr(x,y) % This would work if x,y were column vectors, but they're not.
ans = 10×10
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
corr(x',y') % This is what I should do since x,y are row vectors.
ans = 0.2021

Sign in to comment.

More Answers (0)

Products

Release

R2023a

Asked:

on 12 Sep 2023

Commented:

on 26 Sep 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!