Image Alignment Code in MATLAB

I've been trying everything I can find, but I can't seem to come up with a code that aligns my images very well. I have been using the pressure taps on the image to align the images manually, so using those again would be great. I've gotten to within a few pixels, but I need it to be with at least pixel accuracy, ideally subpixel accuracy. Here's an example of one of the codes that seems to do semi well.
img1 = 255-mean(imread('01_wing.png'),3);
img2 = 255-mean(imread('02_wing.png'),3);
c = normxcorr2(img2,img1);
[y x] = find(c==max(c(:)));
y = y-size(img2,1);
x = x-size(img2,2);
TFORM = maketform('affine',[1 0 x;0 1 y; 0 0 1]');
NEWimg2 = imtransform(img2,TFORM,'xdata',[1 size(img1,2)],'ydata',[1 size(img1,1)]);
I've attached the wing images in a zip file. The image below is an example of the pressure taps not aligning correctly.
What should I do differently?

1 Commento

Joe
Joe il 25 Ott 2013
I found the function cpcorr() very useful to fine-tune control points I had selected elsewhere before using Matt J's solution. Another solution I found was to takemy control points I found using corners(), refine them with cpcorr(), and finally plug them into fitgeotrans(). Hopefully this helps someone as much as it helped me!

Accedi per commentare.

 Risposta accettata

Matt J
Matt J il 15 Ott 2013
Modificato: Matt J il 15 Ott 2013

0 voti

If you can extract the coordinates of the pressure taps in each image e.g., using regionprops(...,'WeightedCentroid'), then you could try using
to find the transformation that aligns them.
Even better would be if you already knew the 2D coordinates of the pressure taps with high accuracy in some prior template image. Then you could register both '01_wing.png' and '02_wing.png' to that.

11 Commenti

Joe
Joe il 15 Ott 2013
As I understand it, it looks like if I have the XY coordinates of the pressure taps, this function will take those, compare them, and then find an appropriate transformation?
Matt J
Matt J il 15 Ott 2013
Modificato: Matt J il 15 Ott 2013
Yes, it will find the rotation and translation (and optionally also a global scaling) that relates them.
For a given pressure tap in image A, however, you do need to know/determine in advance its corresponding partner in image B, but that looks easy in your case.
Accuracy-wise, it would be better to have more than 4 taps. The more the better.
Joe
Joe il 15 Ott 2013
Oh, don't worry. There's somewhere around 80 in the entire image.
I was using corner() to find the points previously, do you know of another function that might be more accurate? I'm satisfied with the accuracy for now, but subpixel accuracy like the regionprops(...'Centroid') gives would be wonderful.
Matt J
Matt J il 15 Ott 2013
Modificato: Matt J il 15 Ott 2013
Not sure I understand the question. If regionprops gives what you already consider exceptional accuracy, why not use that? Also, the 'WeightedCentroid' option would be even more accurate.
Joe
Joe il 15 Ott 2013
That's true, I had forgotten about 'WeightedCentroid.' My reason for wanting to use the corner() function is mainly because I have been having problems turning my image into a binary image.
Matt J
Matt J il 15 Ott 2013
Modificato: Matt J il 15 Ott 2013
Notice also that it is not necessary to measure the coordinates of the taps with sub-pixel accuracy in order to obtain sub-pixel alignment. Below for example is a simulation in which the 80 coordinates in B contain errors of more than 3 pixels, but the alignment is accurate to 0.82 pixels.
Atrue(2,1:80)=1:80; %coordinates image 1
A=Atrue+rand(size(Atrue));
Btrue(2,1:80)=(1:80)-5; %coordinates image 2
B= Btrue+randn(size(Btrue));
[~,Bfit]=absor(A,B); %register A to B
err=@(a,b) max(sqrt(dot(a-b,a-b))); %max error function
And then at the command line
>> err(B,Btrue) %measurement error
ans =
3.1219
>> err(Bfit,Btrue) %alignment error
ans =
0.8152
Matt J
Matt J il 15 Ott 2013
My reason for wanting to use the corner() function is mainly because I have been having problems turning my image into a binary image.
Don't understand why. The pressure taps in your posted image appear to have very distinct intensities from the background. I'd imagine a simple thresholding operation would give you your binary image.
Joe
Joe il 25 Ott 2013
After playing around with the solutions for the last week or so, yours turned out to be the most accurate. Thanks!
Hi, How do I apply the rotational and transormation matrix from absor() to make my points align?
Matt J
Matt J il 16 Mag 2022
If you have the Image Processing Toolbox, you could use imwarp. However, if you have the toolbox, you needn't have used absor. You could have used fitgeotrans from the very beginning. See also,
Thank you for your help.

Accedi per commentare.

Più risposte (2)

Image Analyst
Image Analyst il 11 Ott 2013

0 voti

Why not use imregister()? It's in the Image Processing Toolbox.

8 Commenti

Joe
Joe il 12 Ott 2013
That method works really well! But I'm still getting a slight offset. Do you know of any way to make it a bit more accurate? Or if there's a function that finds control points and uses those instead of intensity values?
Other than increasing resolution to reduce the quantization error, I don't know of a way to improve on imregister. Can you increase the spatial and intensity resolution at all?
Joe
Joe il 12 Ott 2013
Unfortunately, I'm stuck with the images I have. Would there be a way to use imregister to find intensity based control points?
Why do you think they're not right? Take what it gives you and try to shift it a pixel in all 8 directions. Is any of those directions better than that it suggested?
Joe
Joe il 14 Ott 2013
It's aligning the images that have 35 pressure taps about 3 pixels across. Shifting them manually semi works, but not all of the images are off by the same amount.
So did you just say that you were able to manually shift an image that gave a better alignment than the shift that imregister() gave? I'd like to see your images and code that proves it.
Joe
Joe il 15 Ott 2013
Sure, I'll post it when I get back to my school computer tonight. Thanks for all of your help by the way! I've been reading your post history in other image alignment questions too!
Matt J
Matt J il 15 Ott 2013
Modificato: Matt J il 15 Ott 2013
I can imagine imregister() having difficulty if the pressure taps in image A do not have any initial overlap with the taps in image B. The initial gradient of the registration metric will be zero in that case and the algorithm won't be able to move.
With normxcorr2, you would hopefully be able to obtain that initial overlap, but since the taps are so small, it is unclear.

Accedi per commentare.

Eric
Eric il 15 Ott 2013
Here's what works well for me:
2. Register the gradients of the images, not the images themselves.
Here's my code:
%Load data
im1Orig = double(imread('01_wing.png'));
im2Orig = double(imread('02_wing.png'));
%Calculate gradients
im1 = imgradient(im1Orig);
im2 = imgradient(im2Orig);
%Get registration values
[output, Greg] = dftregistration(fft2(im1),fft2(im2),50);
%Translate image
imOut = TranslateImage(im2, output(3), output(4),'method','Fourier');
I get a row shift of -0.36 pixels and a column shift of +3.06 pixels. My function TranslateImage is basically:
img_out = TranslateImage(img_in, rowshift, colshift)
%%Create frequency space sampling vectors
[numrows, numcols] = size(img_in);
[n,m] = meshgrid(-fix(numcols/2):fix((numcols-1)/2),-fix(numrows/2):fix((numrows-1)/2));
m = m/numrows;
n = n/numcols;
%%Perform translation in the Fourier domain
img_fft = fftshift(fft2(ifftshift(double(img_in))));%Cast the input image to a double
shiftOtf = exp(-1i*2*pi*m*rowshift) .* exp(-1i*2*pi*n*colshift);
img_fft_trans = img_fft .* shiftOtf;
img_out = real(fftshift(ifft2(ifftshift(img_fft_trans))));
return
end
For monomodal image registration with pure translation, there are many algorithms that work better than imregister().
Good luck,
Eric

1 Commento

Eric
Eric il 15 Ott 2013
I should point out that pure translation doesn't appear to be totally valid for these images, but it's close. Some of the features line up very well, while others are still off by a pixel.
-Eric

Accedi per commentare.

Community Treasure Hunt

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

Start Hunting!

Translated by