Why is imrotate not rotating an image about its center point?

20 visualizzazioni (ultimi 30 giorni)
Based on imrotate documentation, it rotates the image around its center point. If so why do I get the following result when I rotate my initial image I2D (256x256)to get I2DT? The dot is the center point in the original image. Shouldn't be at the same location? I have found the transformation matrix between the original and the rotated image using imregform. Even though I only applied rotation there is still a translation between the two images. The first two elements of the 3rd row in transformation matrix are nowhere near zero.
I have also tried to rotate the original image with imrotate having the 'crop' option on. This is the result:
Now it looks like the image is rotating about the center point, but the transformation matrix (found using imregform) indicates that there is still some translation. How could this be?
Please help! I'm very confused.
Thank you.
Bahar
  2 Commenti
Bahar
Bahar il 6 Mag 2015
Modificato: Image Analyst il 6 Mag 2015
here is the code:
I2D = zeros(256, 256);
i0 = 40;
for i = 71:230
I2D(i-15,i0:i+10) = 1;
end
I2D(128:130,128:130)=0;
I2DT = imrotate(I2D, 13); % or
%I2DT = imrotate(I2D, 13, 'crop');
imshowpair(I2D, I2DT); title('original and transformed image');
[optimizer, metric] = imregconfig('monomodal');
tform = imregtform(I2DT,I2D,'affine',optimizer,metric);
Tmatrix = tform.T;

Accedi per commentare.

Risposta accettata

Alex Taylor
Alex Taylor il 11 Mag 2015
Modificato: Alex Taylor il 12 Mag 2015
The answer is everything here is working fine, imrotate IS rotating about the center of the input image, and imregtform is correctly recovering the registration that maps the moving image to the fixed image. The issues we have here are artifacts of coordinate system conventions and the way imshowpair is being used.
To start, take a look at the result of overlaying the registered image from your example with the original image:
I2D = zeros(256, 256);
i0 = 40;
for i = 71:230
I2D(i-15,i0:i+10) = 1;
end
I2D(128:130,128:130)=0;
I2DT = imrotate(I2D, 13); % or
%I2DT = imrotate(I2D, 13, 'crop');
imshowpair(I2D, I2DT);
title('original and transformed image');
[optimizer, metric] = imregconfig('monomodal');
tform = imregtform(I2DT,I2D,'affine',optimizer,metric);
Tmatrix = tform.T;
I2DT_reg = imwarp(I2DT,tform,'OutputView',imref2d(size(I2D)));
figure, imshowpair(I2DT_reg,I2D)
Looks good right?
Here are a couple of observations that might be helpful:
1) Rotation about the center of an image is NOT defined by an elemental affine matrix with a zero translation, except for the special case where the center of the input image is aligned with the origin (0,0). In all other orientations of the input image, including the default coordinate system assumed by MATLAB in IMROTATE in which the first pixel is centered at location 1,1 and the last pixel is centered at Colmax,Rowmax, this is not the case.
One way to define an equivalent affine operation to what imrotate is doing is to create a composite affine transformation in which you do three operations: 1) Translate the center of the image to the origin. 2) Rotate by desired angle. 3) Translate the center of the image back to it's original location.
Rdefault = imref2d(size(I2D)); % The default coordinate system used by imrotate
tX = mean(Rdefault.XWorldLimits);
tY = mean(Rdefault.YWorldLimits);
tTranslationToCenterAtOrigin = [1 0 0; 0 1 0; -tX -tY,1];
theta = 10;
tRotation = [cosd(theta) -sind(theta) 0; sind(theta) cosd(theta) 0; 0 0 1];
tTranslationBackToOriginalCenter = [1 0 0; 0 1 0; tX tY,1];
tformCenteredRotation = tTranslationToCenterAtOrigin*tRotation*tTranslationBackToOriginalCenter;
tformCenteredRotation = affine2d(tformCenteredRotation);
[out,Rout] = imwarp(I2D,tformCenteredRotation);
imshow(out,Rout)
Note that this transformation has a translation component, and that this is expected.
2) When you are testing the center of rotation and visualizing this using imshowpair, the reason the centers don't line up is that you aren't passing sufficient spatial referencing information to imshowpair. By default, imshowpair aligns the upper left corners of two input image unless the optional spatial referencing arguments are passed in which defined where each image is. That is why it appears that the center is not preserved.
  2 Commenti
Mohammad Al Nagdawi
Mohammad Al Nagdawi il 17 Dic 2018
please Matlab add this code your library :)
thanks for such a great answer.

Accedi per commentare.

Più risposte (1)

Walter Roberson
Walter Roberson il 8 Mag 2015
imrotate() without 'crop' produces a large result array unless the angle is a multiple of 90 degrees. imshowpair() applied to two images of different size pads the bottom right of the smaller matrix with 0's so they can both be shown. The mismatch of center points on the graph is an artifact of the way you are displaying the images.
I do not currently have an explanation for why you see a translation when you rotate with crop. What is your output Tmatrix ?
  1 Commento
Bahar
Bahar il 8 Mag 2015
Modificato: Walter Roberson il 8 Mag 2015
When I use 'crop' I get this transformation matrix:
0.974478146494730 -0.224777928631732 0
0.224991998375191 0.974234600153450 0
-25.6118025361859 32.2277300573225 1
(-25 and 32 translation along y and x)
Here is a better version of that code:
close all; clear; clc;
I2D = zeros(256, 256);
i0 = 40;
for i = 71:230
I2D(i-15,i0:i+10) = 1;
end
I2D(128:130,128:130)=0;
% rotating the image clockwise
I2D_rot = imrotate(I2D,-13,'bilinear');
subplot(3,3,1)
imshow(I2D); title('original image')
subplot(3,3,2)
imshow(I2D_rot); title('rotated image');
subplot(3,3,3)
imshowpair(I2D, I2D_rot); title('montage')
% finding transformation matrix
[optimizer1, metric1] = imregconfig('monomodal');
tform1 = imregtform(I2D_rot,I2D,'affine',optimizer1,metric1);
Tmatrix1 = tform1.T;
% rotating the image clockwise and cropping
I2DT_rot_cropped = imrotate(I2D,-13,'crop');
subplot(3,3,4)
imshow(I2D); title('original image')
subplot(3,3,5)
imshow(I2DT_rot_cropped); title('rotated cropped image')
subplot(3,3,6)
imshowpair(I2D, I2DT_rot_cropped);title('montage');
% finding transformation matrix
[optimizer2, metric2] = imregconfig('monomodal');
tform2 = imregtform(I2DT_rot_cropped,I2D,'affine',optimizer2,metric2);
Tmatrix2 = tform2.T;
% rotating the image using transformation matrix and imwarp
rot_matrix = [cosd(13) sind(13) 0; -sind(13) cosd(13) 0; 0 0 1];
T_rot = affine2d(rot_matrix);
I2D_rot_trans = imwarp(I2D, T_rot);
subplot(3,3,7)
imshow(I2D); title('original image')
subplot(3,3,8)
imshow(I2D_rot_trans); title('rotated image by transformation');
subplot(3,3,9)
imshowpair(I2D, I2D_rot_trans);title('montage')
% finding transformation matrix
[optimizer3, metric3] = imregconfig('monomodal');
tform3 = imregtform(I2D_rot_trans,I2D,'affine',optimizer3,metric3);
Tmatrix3 = tform3.T;

Accedi per commentare.

Community Treasure Hunt

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

Start Hunting!

Translated by