imrotate won't work in this scenario,any other suggestions?

5 views (last 30 days)
I want to rotate an image at a pivot point(eg:at the center of the 1st feature, which is NOT the center of the image) without changing the size and shape of the image. I tried imrotate, but it won't work in this scenario. My intention is to stack similar features(eg:features 1 & 2) for each set.How to stack these similar features though? Your response on this regard is appreciated.
  4 Comments
John BG
John BG on 6 Jun 2016
this works, run example_imrotatex.m wuth imrotatex.m and the image in same folder.

Sign in to comment.

Accepted Answer

John BG
John BG on 3 Jun 2016
Chathu
there is a function in
that does the same as the following script, basically
1.- introduce rotation point
2.- 1st padarray
3.- 2nd padarray
4.- imrotate with circle showing furthest pixel radius
the script:
clc;clf;
% clear all
A=imread('countryside.jpg');
figure(1);imshow(A);
angle1=randi([1 359],1,1);
if angle<1
disp('choose angle > 1º');B4=A;
return; end;
% measure image size
[sy sx sz]=size(A);
% find image centre [xc yc]
xc=floor(sx/2);
yc=floor(sy/2);
% choose the point [x1 y1] to behave as Z rotation axis
[x1 y1]=ginput(1);
% visualize both [xc yc] and [x1 y1]
hold on;figure(1);plot(x1,y1,'r*','MarkerSize',10);
hold on;figure(1);plot(xc,yc,'ro','MarkerSize',10);
% make sure x1<>xc and y1<>yc
if (x1==xc)
x1=x1+2*(randi([0 1],1,1)-.5); end;
if (y1==yc)
y1=y1+2*(randi([0 1],1,1)-.5); end;
ks=0;
if (x1<xc & y1<yc) ks=1; end;
if (x1>xc & y1<yc) ks=2; end;
if (x1>xc & y1>yc) ks=3; end;
if (x1<xc & y1>yc) ks=4; end;
t=0:2*pi/100:2*pi;
switch ks
case 1 % x1<xc & y1<yc
D=norm([x1 y1]-[sx sy]);
% 1st pair of padding margins
dx=D+x1-sx;
alpha=atand((sx-x1)/(sy-y1));
s=(2*D^2-2*D^2*cosd(alpha))^.5;
dy=(s^2-(sx-x1)^2)^.5;
% dy=D+y1
dx=floor(dx);dy=floor(dy);
B=padarray(A,[dy,dx],'both');
figure(2);imshow(B);
[sby sbx sbz]=size(B);
hold on;figure(2);plot(x1+dx,y1+dy,'r*','MarkerSize',10);
hold on;figure(2);plot(xc+dx,yc+dy,'ro','MarkerSize',10);
% the origin has been displaced [-dx -dy]
% the point [x1 y1] to become rotation Z axis now has coordinates [dx+x1 +dy+y1]
% visualizing the outer rotation circle
x0d=D*cos(t); xd=x0d+dx+x1;
y0d=D*sin(t); yd=y0d+dy+y1;
hold all;figure(2);plot(xd,yd,'r','LineWidth',1.5);
% visualizing axes after 2nd padarray and origin displacement
hold all;figure(2);plot([1:1:sbx],ones(1,sbx).*(dy+y1),'w','LineWidth',1.5); % new x axis
hold all;figure(2);plot(ones(1,sby).*(dx+x1),[1:1:sby],'w','LineWidth',1.5); % new y axis
% calculating 2nd padarray margins
dx2=2*D-sbx;dx2=floor(dx2);
dy2=2*D-sby;dy2=floor(dy2);
B3=padarray(B,[dy2 dx2],50,'pre');
[sb3y sb3x sb3z]=size(B3);
figure(4);imshow(B3);
% visualizing initial image centre [xc yc] and and chosen rotation point [x1 y1]
hold all;figure(4);plot(x1+dx+dx2,y1+dy+dy2,'r*','MarkerSize',10);
hold all;figure(4);plot(xc+dx+dx2,yc+dy+dy2,'ro','MarkerSize',10);
% visualizing outer circle after 2nd padarray
xd2=xd+dx2;
yd2=yd+dy2;
hold all;figure(4);plot(xd2,yd2,'r','LineWidth',2.5);
% visualizing axes after 2nd padarray and origin displacement
hold all;figure(4);plot([1:1:sb3x],ones(1,sb3x).*(dy+y1+dy2),'w','LineWidth',1.5); % new x axis
hold all;figure(4);plot(ones(1,sb3y).*(dx+x1+dx2),[1:1:sb3y],'w','LineWidth',1.5); % new y axis
case 2 % x1>cx & y1<yx
D=norm([x1 y1]-[0 sy]);
% 1st pair of padding margins
dx=D-x1;
alpha=atand((sy-y1)/(sx-x1));
s=(2*D^2-2*D^2*cosd(alpha))^.5;
dy=(s^2-(sx-x1)^2)^.5;
dy=D-y1;
dx=floor(dx);dy=floor(dy);
B=padarray(A,[dy,dx],'pre');
figure(2);imshow(B);
[sby sbx sbz]=size(B);
hold on;figure(2);plot(x1+dx,y1+dy,'r*','MarkerSize',10);
hold on;figure(2);plot(xc+dx,yc+dy,'ro','MarkerSize',10);
% the origin has been displaced [-dx -dy]
% the point [x1 y1] to become rotation Z axis now has coordinates [dx+x1 +dy+y1]
% visualizing the outer rotation circle
x0d=D*cos(t); xd=x0d+dx+x1;
y0d=D*sin(t); yd=y0d+dy+y1;
hold all;figure(2);plot(xd,yd,'r','LineWidth',1.5);
% visualizing axes after 2nd padarray and origin displacement
hold all;figure(2);plot([1:1:sbx],ones(1,sbx).*(dy+y1),'w','LineWidth',1.5); % new x axis
hold all;figure(2);plot(ones(1,sby).*(dx+x1),[1:1:sby],'w','LineWidth',1.5); % new y axis
% calculating 2nd padarray margins
dx2=D-(sx-x1);dx2=floor(dx2);
dy2=D-(sy-y1);dy2=floor(dy2);
B3=padarray(B,[dy2 dx2],50,'post');
[sb3y sb3x sb3z]=size(B3);
figure(4);imshow(B3);
xc2=floor(sb3x/2);yc2=floor(sb3y/2);
% visualizing initial image centre [xc yc] and and chosen rotation point [x1 y1]
hold all;figure(4);plot(xc2,yc2,'r*','MarkerSize',10);
hold all;figure(4);plot(xc2-(x1-xc),yc2-(y1-yc),'ro','MarkerSize',10);
% visualizing outer circle after 2nd padarray
xd2=xd+xc2;
yd2=yd+yc2;
hold all;figure(4);plot(xd,yd,'r','LineWidth',2.5);
% visualizing axes after 2nd padarray and origin displacement
hold all;figure(4);plot([1:1:sb3x],ones(1,sb3x).*yc2,'w','LineWidth',1.5); % new x axis
hold all;figure(4);plot(ones(1,sb3y).*xc2,[1:1:sb3y],'w','LineWidth',1.5); % new y axis
case 3 % x1>xc & y1>yc
D=norm([x1 y1]-[0 0]);
% 1st pair of padding margins
dx=D-x1;
dy=D-y1;
dx=floor(dx);dy=floor(dy);
B=padarray(A,[dy dx],'pre');
figure(2);imshow(B);
[sby sbx sbz]=size(B);
hold on;figure(2);plot(x1+dx,y1+dy,'r*','MarkerSize',10);
hold on;figure(2);plot(xc+dx,yc+dy,'ro','MarkerSize',10);
x0d=D*cos(t); xd=x0d+dx+x1;
y0d=D*sin(t); yd=y0d+dy+y1;
hold all;figure(2);plot(xd,yd,'r','LineWidth',1.5);
% visualizing axes after 2nd padarray and origin displacement
hold all;figure(2);plot([1:1:sbx],ones(1,sbx).*(dy+y1),'w','LineWidth',1.5); % new x axis
hold all;figure(2);plot(ones(1,sby).*(dx+x1),[1:1:sby],'w','LineWidth',1.5); % new y axis
% calculating 2nd padarray margins
dx2=2*D-sbx;dx2=floor(dx2);
dy2=2*D-sby;dy2=floor(dy2);
B2=padarray(B,[0 dx2],50,'post');
figure(3);imshow(B2);
B3=padarray(B2,[dy2 0],100,'post');
[sb3y sb3x sb3z]=size(B3)
figure(4);imshow(B3);
xc2=floor(sb3x/2);yc2=floor(sb3y/2);
% visualizing initial image centre [xc yc] and and chosen rotation point [x1 y1]
hold all;figure(4);plot(xc2,yc2,'r*','MarkerSize',10)'
hold all;figure(4);plot(xc2-(x1-xc),yc2-(y1-yc),'ro','MarkerSize',10)'
% visualizing outer circle after 2nd padarray
xd2=x0d+xc2;
yd2=y0d+yc2'
hold all;figure(4);plot(xd2,yd2,'r','LineWidth',2.5)'
% visualizing axes after 2nd padarray and origin displacement
hold all;figure(4);plot([1:1:sb3x],ones(1,sb3x).*yc2,'w','LineWidth',1.5); % new x axis
hold all;figure(4);plot(ones(1,sb3y)*xc2,[1:1:sb3y],'w','LineWidth',1.5); % new y axis
case 4 % x1<xc & y1>yc
% D is distance between [x1 y1] and [xc yc], also D=pdist2([x1 y1],[sx 0])
D=norm([x1 y1]-[sx 0])
% 1st pair of padding margins
dx=D+x1-sx
alpha=atand((sx-x1)/y1)
s=(2*D^2-2*D^2*cosd(alpha))^.5
dy=(s^2-(sx-x1)^2)^.5
% dy=D-y1
dx=floor(dx);dy=floor(dy);
B=padarray(A,[dy,dx],'both');
figure(2);imshow(B)
[sby sbx sbz]=size(B)
hold on;figure(2);plot(x1+dx,y1+dy,'r*','MarkerSize',10)
hold on;figure(2);plot(xc+dx,yc+dy,'ro','MarkerSize',10)
% the origin has been displaced [-dx -dy]
% the point [x1 y1] to become rotation Z axis now has coordinates [dx+x1 +dy+y1]
% visualizing the outer rotation circle
x0d=D*cos(t); xd=x0d+dx+x1;
y0d=D*sin(t); yd=y0d+dy+y1;
hold all;figure(2);plot(xd,yd,'r','LineWidth',1.5);
% visualizing axes after 2nd padarray and origin displacement
hold all;figure(2);plot([1:1:sbx],ones(1,sbx).*(dy+y1),'w','LineWidth',1.5) % new x axis
hold all;figure(2);plot(ones(1,sby).*(dx+x1),[1:1:sby],'w','LineWidth',1.5) % new y axis
% calculating 2nd padarray margins
dx2=2*D-sbx;dx2=floor(dx2);
dy2=2*D-sby;dy2=floor(dy2);
B2=padarray(B,[0 dx2],50,'pre');
figure(3);imshow(B2);
B3=padarray(B2,[dy2 0],100,'post');
[sb3y sb3x sb3z]=size(B3)
figure(4);imshow(B3);
% visualizing initial image centre [xc yc] and and chosen rotation point [x1 y1]
hold all;figure(4);plot(x1+dx+dx2,y1+dy,'r*','MarkerSize',10)
hold all;figure(4);plot(xc+dx+dx2,yc+dy,'ro','MarkerSize',10)
% visualizing outer circle after 2nd padarray
xd2=xd+dx2
yd2=yd
hold all;figure(4);plot(xd2,yd2,'r','LineWidth',2.5)
% visualizing axes after 2nd padarray and origin displacement
hold all;figure(4);plot([1:1:sb3x],ones(1,sb3x).*(dy+y1),'w','LineWidth',1.5) % new x axis
hold all;figure(4);plot(ones(1,sb3y).*(dx+x1+dx2),[1:1:sb3y],'w','LineWidth',1.5) % new y axis
otherwise
disp('\nerror\n')
return
end
%
% imsave(B3)
imwrite(B3,'padded_image.jpg')
% padded image: B3
% size square containing padded image: [sb3x sby3]
% center padded image: [xc2 yc2]
% points outer circle centre before rotation [xd2 yd2]
% radius: D
B4=imrotate(B3,angle);
[sb4y sb4x sb4z]=size(B4);
figure(5);imshow(B4);
% visualizing initial image centre [xc yc] and and chosen rotation point [x1 y1]
hold all;figure(5);plot(floor(sb4x/2),floor(sb4y/2),'r*','MarkerSize',15);
% hold all;figure(5);plot(xc+dx+dx2,yc+dy,'ro','MarkerSize',10);
% visualizing outer circle after 2nd padarray
xd4=x0d+floor(sb4x/2);
yd4=y0d+floor(sb4y/2);
hold all;figure(5);plot(xd4,yd4,'r','LineWidth',2.5);
if angle>0 str1='CCW'; end;
if angle<0 str1='CW'; end;
figure(5);legend(['angle : ' num2str(angle) ' º ' str1],['Radius : ' num2str(floor(D)) ' pixels'],'Location','Northwest');
imwrite(B4,'im_padded_rotated.jpg');
If you find this answer of any help solving your question,
please click on the thumbs-up vote link, or mark is accepted answer
thanks in advance
John
  3 Comments
John BG
John BG on 6 Jun 2016
I just received an email from your address mentioning an error. Would you please explain the error, how can i reproduce it, so i can fix it?
John
Chathu
Chathu on 8 Jun 2016
angle1=randi([1 359],1,1);
angle1 should be corrected as angle.
That's it and it works really well. Thank you so much John. Really appreciate your effort.

Sign in to comment.

More Answers (2)

Walter Roberson
Walter Roberson on 2 Jun 2016
Parent each image within its own hgtransform() . You can then construct appropriate rotation and translation matrices to rotate each of them around arbitrary points and move them around on the display.
This is a solution for the case where what you care about is what shows up on the display.
  3 Comments
Walter Roberson
Walter Roberson on 3 Jun 2016
Your requirement that the size and shape of the image not be altered makes it difficult to use imtransform or imwarp.
Consider, for example, a 400 x 800 grayscale image and a simple 90 degree rotation: your requirement is that the output would still be 400 x 800 but contain the rotated image. You can see that in order to do that, you would have to do the equivalent of
rotated_image = [zeros(400,300), rot90( imresize(Original_Image, [200 400]) ), zeros(400,300)]
This is likely to interfere with your attempts to match up anything other than the center point that you are rotating the image around.
Chathu
Chathu on 4 Jun 2016
Walter, thank you so much for your solution. I know, pivot point may be an issue as it is not the image's center.

Sign in to comment.


Image Analyst
Image Analyst on 3 Jun 2016
Exactly what does "without changing the size and shape of the image" mean to you? And why is that necessary?
When you rotate an image, say a rectangle, it will become a rotated rectangle, like a diamond shape. However since images can't be diamond shapes, it will pad the "blank" space that got uncovered with zeros. The corners rotated up and down will now make the image have more rows than before. So you can either enlarge the canvass, or clip/crop the canvass to make it have the same number of rows and columns as the original. imrotate() can either enlarge the canvass or crop it, depending on what you pass in for the input.
We don't know what you mean. Please clarify. To rotate about some point that is not at the center of the image, you might want to use padarray() to enlarge the canvass first so that the center or rotation is the center of the new, enlarged canvass. That's the easiest way though not the most memory efficient.
  3 Comments
Image Analyst
Image Analyst on 3 Jun 2016
You can see from all the responses here just how confusing your explanations are. You might make things a LOT clearer by just posting your image and saying what "feature" you want to rotate around and why. And if there are, say, 5 features in the image, which do you consider to be the first? And what is a "feature" to you? To most people, a feature is something like the area, perimeter, intensity, centroid or some other measurement of an object region. Like if you have a photo of nuts and bolts, the "objects" would be the nuts and bolts and the "features" would be the area and brightness and Euler number. But it kind of sounds like you may be calling the whole object a "feature" which is contrary to standard nomenclature. Rotating around the first feature, say, area, would not make sense. Rotating around the first bolt would make sense but you'd have to define which bolt is the "first" bolt. Again, post a picture.
Chathu
Chathu on 4 Jun 2016
Image Analyst, i know i should have post it before. I am sorry. But here you go.

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!