Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
finding the shift

Subject: finding the shift

From: li

Date: 31 Jan, 2011 15:02:03

Message: 1 of 12

Dear all,
Does anyone know how to find the shift of 2 images in frequency domain?thanks
since my wayis to compute (an approximation of) the 2D Fourier transform of the continuous images.
you may refer to this thanks
http://www.flickr.com/photos/58977081@N02/5404190021/
I really donno how to do the first steep since I am not really good at matlab
I know I have to to a fft first thanks

Subject: finding the shift

From: Sean de

Date: 31 Jan, 2011 16:40:22

Message: 2 of 12

"li " <kiluajp@hotmail.com> wrote in message <ii6itb$sms$1@fred.mathworks.com>...
> Dear all,
> Does anyone know how to find the shift of 2 images in frequency domain?thanks
> since my wayis to compute (an approximation of) the 2D Fourier transform of the continuous images.
> you may refer to this thanks
> http://www.flickr.com/photos/58977081@N02/5404190021/
> I really donno how to do the first steep since I am not really good at matlab
> I know I have to to a fft first thanks

Here:
Save this to PCdemo.m

function [row col] = PCdemo(I, I2)
%I,I2 are reference and target images
%[row col] are row, column shifts
%SCd 4/2010
%

    %Fourier transform both images
    fi = fft2(double(I));
    fr = fft2(double(I2));

    %Perform phase correlation (amplitude is normalized)
    fc = fi .* conj(fr);
    fcn = fc ./abs(fc);

    %Inverse fourier of peak correlation matrix and max location
    peak_correlation_matrix = abs(ifft2(fcn));
    [peak, idx] = max(peak_correlation_matrix(:));
    
    %Calculate actual translation
    [row, col] = ind2sub(size(peak_correlation_matrix),idx);
    if row < size(peak_correlation_matrix,1)/2
        row = -(row - 1);
    else
        row = size(peak_correlation_matrix,1) - (row - 1);
    end;
    if col < size(peak_correlation_matrix,2)/2
        col = -(col - 1);
    else
col = size(peak_correlation_matrix,2) - (col - 1);
    end
end


To test it: download my function imtranslate here:
http://www.mathworks.com/matlabcentral/fileexchange/27251-imtranslate
Translate your image some amount and run it.

I = imread('cameraman.tif'); %Read in cameraman image
I2 = imtranslate(I,[-11.3 17.8]); %Translate 11.3 down 17.8 over
%NOTE: these are not integer pixel shifts. This is the glory of Phase
%Correlation. It's immune to intensity changes caused by sub pixel shifts
%The integer shift (rounded) of the above is [11 18].
%SUBNOTE cameraman.tif is built in to IPT so you can see run this m.file and see
%what's happening

figure;
imshow(I);
title('Cameraman Original');
figure;
imshow(I2);
title('Cameraman Shifted');

[row col] = PCdemo(I, I2);

disp('The shifts are:')
disp([row col])

Subject: finding the shift

From: li

Date: 31 Jan, 2011 18:57:04

Message: 3 of 12

"Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <ii6olm$99k$1@fred.mathworks.com>...
> "li " <kiluajp@hotmail.com> wrote in message <ii6itb$sms$1@fred.mathworks.com>...
> > Dear all,
> > Does anyone know how to find the shift of 2 images in frequency domain?thanks
> > since my wayis to compute (an approximation of) the 2D Fourier transform of the continuous images.
> > you may refer to this thanks
> > http://www.flickr.com/photos/58977081@N02/5404190021/
> > I really donno how to do the first steep since I am not really good at matlab
> > I know I have to to a fft first thanks
>
> Here:
> Save this to PCdemo.m
>
> function [row col] = PCdemo(I, I2)
> %I,I2 are reference and target images
> %[row col] are row, column shifts
> %SCd 4/2010
> %
>
> %Fourier transform both images
> fi = fft2(double(I));
> fr = fft2(double(I2));
>
> %Perform phase correlation (amplitude is normalized)
> fc = fi .* conj(fr);
> fcn = fc ./abs(fc);
>
> %Inverse fourier of peak correlation matrix and max location
> peak_correlation_matrix = abs(ifft2(fcn));
> [peak, idx] = max(peak_correlation_matrix(:));
>
> %Calculate actual translation
> [row, col] = ind2sub(size(peak_correlation_matrix),idx);
> if row < size(peak_correlation_matrix,1)/2
> row = -(row - 1);
> else
> row = size(peak_correlation_matrix,1) - (row - 1);
> end;
> if col < size(peak_correlation_matrix,2)/2
> col = -(col - 1);
> else
> col = size(peak_correlation_matrix,2) - (col - 1);
> end
> end
>
>
> To test it: download my function imtranslate here:
> http://www.mathworks.com/matlabcentral/fileexchange/27251-imtranslate
> Translate your image some amount and run it.
>
> I = imread('cameraman.tif'); %Read in cameraman image
> I2 = imtranslate(I,[-11.3 17.8]); %Translate 11.3 down 17.8 over
> %NOTE: these are not integer pixel shifts. This is the glory of Phase
> %Correlation. It's immune to intensity changes caused by sub pixel shifts
> %The integer shift (rounded) of the above is [11 18].
> %SUBNOTE cameraman.tif is built in to IPT so you can see run this m.file and see
> %what's happening
>
> figure;
> imshow(I);
> title('Cameraman Original');
> figure;
> imshow(I2);
> title('Cameraman Shifted');
>
> [row col] = PCdemo(I, I2);
>
> disp('The shifts are:')
> disp([row col])

o.... thanks sos soosososo much can u teach me how to do so?
for example %Calculate actual translation
    [row, col] = ind2sub(size(peak_correlation_matrix),idx);
    if row < size(peak_correlation_matrix,1)/2
        row = -(row - 1);
    else
        row = size(peak_correlation_matrix,1) - (row - 1);
    end;
    if col < size(peak_correlation_matrix,2)/2
        col = -(col - 1);
    else
col = size(peak_correlation_matrix,2) - (col - 1);
    end
end this part how did you think that
what is the principle behind it? thanks

Subject: finding the shift

From: Sean de

Date: 31 Jan, 2011 19:15:08

Message: 4 of 12

"li " <kiluajp@hotmail.com> wrote in message <ii70m0$2fs$1@fred.mathworks.com>...
> o.... thanks sos soosososo much can u teach me how to do so?
> for example %Calculate actual translation
> [row, col] = ind2sub(size(peak_correlation_matrix),idx);
> if row < size(peak_correlation_matrix,1)/2
> row = -(row - 1);
> else
> row = size(peak_correlation_matrix,1) - (row - 1);
> end;
> if col < size(peak_correlation_matrix,2)/2
> col = -(col - 1);
> else
> col = size(peak_correlation_matrix,2) - (col - 1);
> end
> end this part how did you think that
> what is the principle behind it? thanks

You're welcome,

This part accounts for negative translation and no translation.
Try putting a break point on this line:
[row, col] = ind2sub(size(peak_correlation_matrix),idx);
Then call the function with an image containing a negative and a positive translation:
I = imread('cameraman.tif');
PCdemo(I,imtranslate(I,[3.5,-7.6]));

You'll see that 'row' is 254 and that 'col' is 9. Clearly neither of these values are correct so you have to calculate the actual value based on them.
The subtraction of 1 accounts for the fact that MATLAB indexing starts at 1 (not zero like in other languages). The subtraction from the size accounts negative shifts.

-Sean

Subject: finding the shift

From: li

Date: 15 Feb, 2011 07:29:04

Message: 5 of 12

"Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <ii71ns$b7p$1@fred.mathworks.com>...
> "li " <kiluajp@hotmail.com> wrote in message <ii70m0$2fs$1@fred.mathworks.com>...
> > o.... thanks sos soosososo much can u teach me how to do so?
> > for example %Calculate actual translation
> > [row, col] = ind2sub(size(peak_correlation_matrix),idx);
> > if row < size(peak_correlation_matrix,1)/2
> > row = -(row - 1);
> > else
> > row = size(peak_correlation_matrix,1) - (row - 1);
> > end;
> > if col < size(peak_correlation_matrix,2)/2
> > col = -(col - 1);
> > else
> > col = size(peak_correlation_matrix,2) - (col - 1);
> > end
> > end this part how did you think that
> > what is the principle behind it? thanks
>
> You're welcome,
>
> This part accounts for negative translation and no translation.
> Try putting a break point on this line:
> [row, col] = ind2sub(size(peak_correlation_matrix),idx);
> Then call the function with an image containing a negative and a positive translation:
> I = imread('cameraman.tif');
> PCdemo(I,imtranslate(I,[3.5,-7.6]));
>
> You'll see that 'row' is 254 and that 'col' is 9. Clearly neither of these values are correct so you have to calculate the actual value based on them.
> The subtraction of 1 accounts for the fact that MATLAB indexing starts at 1 (not zero like in other languages). The subtraction from the size accounts negative shifts.
>
> -Sean
one more question.
can this code regonize the non integer shift? which mean shift with 0.7, 1.7 etc.... thanks

Subject: finding the shift

From: Sean de

Date: 15 Feb, 2011 11:49:04

Message: 6 of 12

"li " <kiluajp@hotmail.com> wrote in message <ijda00$7ss$1@fred.mathworks.com>...
> one more question.
> can this code regonize the non integer shift? which mean shift with 0.7, 1.7 etc.... thanks

Not in it's current form but it can certainly be extended to measure sub-pixel shifts.
Two referencess:
http://www.mathworks.com/matlabcentral/fileexchange/18401-efficient-subpixel-image-registration-by-cross-correlation
(All done for you)

http://www.mathworks.com/matlabcentral/newsreader/view_thread/269829
(Very good description of what to do)

Subject: finding the shift

From: li

Date: 16 Feb, 2011 14:56:04

Message: 7 of 12

"Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <ijdp7g$1jp$1@fred.mathworks.com>...
> "li " <kiluajp@hotmail.com> wrote in message <ijda00$7ss$1@fred.mathworks.com>...
> > one more question.
> > can this code regonize the non integer shift? which mean shift with 0.7, 1.7 etc.... thanks
>
> Not in it's current form but it can certainly be extended to measure sub-pixel shifts.
> Two referencess:
> http://www.mathworks.com/matlabcentral/fileexchange/18401-efficient-subpixel-image-registration-by-cross-correlation
> (All done for you)
>
> http://www.mathworks.com/matlabcentral/newsreader/view_thread/269829
> (Very good description of what to do)

thank you for your advice.
I am know so much my project now.
I have another question again
now I have 2 shifted low resolution images from my computer.
and I try to use the image regisstration by cross correlation
> http://www.mathworks.com/matlabcentral/fileexchange/18401-efficient-subpixel-image-registration-by-cross-correlation
when I use the cameraman.tif to be the read in image, it works perfectly.
However when I change it into my low resolution images it stops.
I found it is a error like
Error in ==> efficient_subpixel_registration at 51
g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);

is it the problem of pixel size? thanks

Subject: finding the shift

From: Sean de

Date: 16 Feb, 2011 15:52:05

Message: 8 of 12

"li " <kiluajp@hotmail.com> wrote in message <ijgoi4$j7g$1@fred.mathworks.com>...

> Error in ==> efficient_subpixel_registration at 51
> g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
>
> is it the problem of pixel size? thanks

Please report the _full_ error message. We can't deduce from here what's happening. I can hypothesize that is had to do with odd sizes but I don't know...

Subject: finding the shift

From: li

Date: 16 Feb, 2011 16:01:06

Message: 9 of 12

"Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <ijgrr5$pvv$1@fred.mathworks.com>...
> "li " <kiluajp@hotmail.com> wrote in message <ijgoi4$j7g$1@fred.mathworks.com>...
>
> > Error in ==> efficient_subpixel_registration at 51
> > g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
> >
> > is it the problem of pixel size? thanks
>
> Please report the _full_ error message. We can't deduce from here what's happening. I can hypothesize that is had to do with odd sizes but I don't know...

??? Error using ==> times
Matrix dimensions must agree.

Error in ==> efficient_subpixel_registration at 51
g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);

is this the full error message? thanks

Subject: finding the shift

From: li

Date: 16 Feb, 2011 16:04:04

Message: 10 of 12

"Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <ijgrr5$pvv$1@fred.mathworks.com>...
> "li " <kiluajp@hotmail.com> wrote in message <ijgoi4$j7g$1@fred.mathworks.com>...
>
> > Error in ==> efficient_subpixel_registration at 51
> > g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
> >
> > is it the problem of pixel size? thanks
>
> Please report the _full_ error message. We can't deduce from here what's happening. I can hypothesize that is had to do with odd sizes but I don't know...

Is this the full error message????
 Error using ==> times
Matrix dimensions must agree.

Error in ==> efficient_subpixel_registration at 51
g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
what does it mean by odd size? thanks

Subject: finding the shift

From: Sean de

Date: 16 Feb, 2011 16:22:04

Message: 11 of 12

"li " <kiluajp@hotmail.com> wrote in message <ijgshk$c91$1@fred.mathworks.com>...
> "Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <ijgrr5$pvv$1@fred.mathworks.com>...
> > "li " <kiluajp@hotmail.com> wrote in message <ijgoi4$j7g$1@fred.mathworks.com>...
> >
> > > Error in ==> efficient_subpixel_registration at 51
> > > g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
> > >
> > > is it the problem of pixel size? thanks
> >
> > Please report the _full_ error message. We can't deduce from here what's happening. I can hypothesize that is had to do with odd sizes but I don't know...
>
> Is this the full error message????
> Error using ==> times
> Matrix dimensions must agree.
>
> Error in ==> efficient_subpixel_registration at 51
> g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
> what does it mean by odd size? thanks


Does it work if you zero pad your images with 1 post pixel? I.e.
I1 = padarray(I1,[1 1],0,'post');
I2 = padarray(I1,[1 1],0,'post');

Subject: finding the shift

From: li

Date: 16 Feb, 2011 16:34:04

Message: 12 of 12

"Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <ijgtjc$lah$1@fred.mathworks.com>...
> "li " <kiluajp@hotmail.com> wrote in message <ijgshk$c91$1@fred.mathworks.com>...
> > "Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <ijgrr5$pvv$1@fred.mathworks.com>...
> > > "li " <kiluajp@hotmail.com> wrote in message <ijgoi4$j7g$1@fred.mathworks.com>...
> > >
> > > > Error in ==> efficient_subpixel_registration at 51
> > > > g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
> > > >
> > > > is it the problem of pixel size? thanks
> > >
> > > Please report the _full_ error message. We can't deduce from here what's happening. I can hypothesize that is had to do with odd sizes but I don't know...
> >
> > Is this the full error message????
> > Error using ==> times
> > Matrix dimensions must agree.
> >
> > Error in ==> efficient_subpixel_registration at 51
> > g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
> > what does it mean by odd size? thanks
>
>
> Does it work if you zero pad your images with 1 post pixel? I.e.
> I1 = padarray(I1,[1 1],0,'post');
> I2 = padarray(I1,[1 1],0,'post');
no it seems I still have the same problem.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us