Suppose I have an image I
that I rotate -45° using imrotate
(I get I_R
). Then I draw two lines AB
and CD
(parallels). Finally, I rotate the two lines back (45°) and draw them in the original image I
.
I rotate I
using the MATLAB function imrotate()
:
I_R = imrotate(I,-45);
From Matlab help, I get : B = imrotate(A,angle) rotates image A by angle degrees in a counterclockwise direction around its center point.
But it seems that
imrotate
add a translation to the image ! I have read the code of built-in matlab function, it seems that it uses a function calledgetOutputBound
to check if the rotated image will fit in the figure. This translation is what I am looking for !!
The four points A,B,C,D
form a two parallels lines AB
& CD
.
A = [x_A; u];
B = [x_B; u];
C = [x_A; d];
D = [x_B; d];
So now , I rotate the two lines, I use my function rotateTwoPoints()
, by simply calling the following two lines :
[Af,Bf] = rotateTwoPoints(A,B,-45,O,true);
[Cf,Df] = rotateTwoPoints(C,D,-45,O,true);
Where O
is the origin around which the rotation will be.
O = [0;0]
I mean it is the origin of the plot. No success !O
the centroid of the image I
using regionprops(I,"Centroid")
. It was wrong because the centroid is not a center. O = floor(size(I)/2+0.5)'
or using ceil
!But when I draw the resulting lines AfBf
& CfDf
in image I
like this :
plot([Af(1) Bf(1)],[Af(2) Bf(2)],'k');
plot([Cf(1) Df(1)],[Cf(2) Df(2)],'k');
I get a result that is not correct !
Problem : In I_R, the AB
& CD
contain what I call the BlueZone (see image 3). But the rotated back lines AfBf
& CfDf
do not cover it !
Here is the rotated image I_R and the two lines drawn (The two middle red lines correspond to AB
and CD
) :
I then draw the rotated lines AfBf
& CfDf
in original image I (the black bold point correspond to the center on which I have done the rotation) :
IMAGE UPDATED
Problem : As you can see the BlueZone was inside the two lines AB
and CD
. But when rotated back it become outside, as shown in the following image (red arrows point to BlueZone) :
Since my problem is not yet resolved , I selected the code that causes the problem and I add it as the following snippet (there is a variable stored in a file that you can download here) :
function Question()
% load image in I, the image is available online in the below link
load I ;
% rotate I with -45° using imrotate
I_R = imrotate(I,-45);
% some data
x_A = 3 ;
x_B = 79;
u = 24;
d = 44;
% some meaningful Points : A,B,C and D that form two lines AB and CD
% parallels
A = [x_A; u];
B = [x_B; u];
C = [x_A; d];
D = [x_B; d];
% figure 1 contain two subplots
figure(1);
% draw rotated image I_R
subplot(1,2,1), axis image, imagesc(I_R), hold on;
% draw two lines AB and CD in red in rotated image
plot([A(1) B(1)],[A(2) B(2)],'r');
plot([C(1) D(1)],[C(2) D(2)],'r');
title('I_R the rotated image with the two lines AB and CD');
% draw original image I
subplot(1,2,2), axis image, imagesc(I) , hold on;
% compute the middle of image I
axises=axis;
center = [mean(axises(1:2)),mean(axises(3:4))]';
% draw the center in red and as a point
plot(center(1),center(2),'ro');
% rotate the two lines, the result is the two lines AfBf and CfDf
[Af,Bf] = rotateTwoPoints(A,B,-45,center,true);
[Cf,Df] = rotateTwoPoints(C,D,-45,center,true);
% draw the rotated back lines in original image I
figure(1);
subplot(1,2,2);
plot([Af(1) Bf(1)],[Af(2) Bf(2)],'k');
plot([Cf(1) Df(1)],[Cf(2) Df(2)],'k');
title('the original image I with the two lines AfBf and CfDf');
function [Af,Bf] = rotateTwoPoints (A,B,t,Origin,isPlot)
% Definition of the rotation matrix (rotation around origin)
R=[ ...
cosd(t) -sind(t)
sind(t) cosd(t)
];
% translation
At = A - Origin;
Bt = B - Origin;
% rotation of the points A and B
Ar = R*At;
Br = R*Bt;
% translation
Af = Ar + Origin;
Bf = Br + Origin;
if isPlot == true
figure(100)
% Plot of the original line
plot(A(1),A(2),'k*', B(1),B(2),'b*');
line([A(1) B(1)],[A(2) B(2)], 'Color','r');
grid on
hold on
% Plot the Origin around which the rotation will be
plot(Origin(1),Origin(2),'k*','LineWidth',3);
% Plot of the rotated line
plot(Af(1),Af(2),'g*', Bf(1),Bf(2),'r*');
line([Af(1) Bf(1)],[Af(2) Bf(2)], 'Color','b');
legend('A','B','line AB','Origin','Af','Bf','line AfBf',['angle: ',num2str(t)],'Location','northeastoutside');
daspect([1 1 1])
end
PS: I am using MATLAB R2012b
I found the solution !
Well, what happens is that the built-in function imrotate
does not only rotate by default the image, but it does also a translation so that the rotated-image fit in the figure.
the solution is to use :
I_R = imrotate(I,-45,'nearest','crop');
the important parameter here is 'crop' (bbox) :
B = imrotate(A,angle,method,bbox) rotates image A, where bbox specifies the size of the returned image. bbox is a text string that can have one of the following values. The default value is enclosed in braces ({}).
'crop' Make output image B the same size as the input image A, cropping the rotated image to fit
{'loose'} Make output image B large enough to contain the entire rotated image. B is generally larger than A.
from the help of the function imrotate here.