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

5 ビュー (過去 30 日間)
Chathu
Chathu 2016 年 6 月 2 日
コメント済み: Chathu 2016 年 6 月 8 日
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 件のコメント
John BG
John BG 2016 年 6 月 6 日
this works, run example_imrotatex.m wuth imrotatex.m and the image in same folder.
Chathu
Chathu 2016 年 6 月 8 日
Great! Thank you so much.

サインインしてコメントする。

採用された回答

John BG
John BG 2016 年 6 月 3 日
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 件のコメント
John BG
John BG 2016 年 6 月 6 日
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 2016 年 6 月 8 日
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.

サインインしてコメントする。

その他の回答 (2 件)

Walter Roberson
Walter Roberson 2016 年 6 月 2 日
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 件のコメント
Walter Roberson
Walter Roberson 2016 年 6 月 3 日
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 2016 年 6 月 4 日
Walter, thank you so much for your solution. I know, pivot point may be an issue as it is not the image's center.

サインインしてコメントする。


Image Analyst
Image Analyst 2016 年 6 月 3 日
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 件のコメント
Image Analyst
Image Analyst 2016 年 6 月 3 日
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 2016 年 6 月 4 日
Image Analyst, i know i should have post it before. I am sorry. But here you go.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeComputer Vision with Simulink についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by