假设我有一张图像 I
,我使用imrotate
旋转 -45°(我得到 I_R
)。然后我画了两行 AB
和 CD
(parallels)。最后,我将两条线旋转回来( 45°)并将其绘制在原始图像 I
中。
我使用MATLAB函数 I
旋转 imrotate()
:
I_R = imrotate(I,-45);
从Matlab帮助中,我得到:B = imrotate(A,angle)围绕其中心点以逆时针方向旋转图像A角度。
但似乎
imrotate
为图片添加了翻译!我有 阅读内置matlab函数的代码,似乎它使用了一个 名为getOutputBound
的函数用于检查旋转后的图像是否会出现 适合图。这个翻译就是我要找的!!
四点 A,B,C,D
形成两条平行线AB
& CD
。
A = [x_A; u];
B = [x_B; u];
C = [x_A; d];
D = [x_B; d];
现在,我旋转两行,我使用我的函数 rotateTwoPoints()
,只需调用以下两行:
[Af,Bf] = rotateTwoPoints(A,B,-45,O,true);
[Cf,Df] = rotateTwoPoints(C,D,-45,O,true);
O
是旋转所围绕的原点。
O = [0;0]
我的意思是它是情节的起源。没有成功!O
选择I
图片的{strong>质心regionprops(I,"Centroid")
。这是错误的,因为质心不是中心。 O = floor(size(I)/2+0.5)'
或使用ceil
!但是当我画出结果线AfBf
&图片 CfDf
中的I
像这样:
plot([Af(1) Bf(1)],[Af(2) Bf(2)],'k');
plot([Cf(1) Df(1)],[Cf(2) Df(2)],'k');
我得到的结果不正确!
问题 :在 I_R 中,AB
& CD
包含我称之为 BlueZone 的内容(参见图3)。但旋转后线AfBf
& CfDf
不包括它!
以下是旋转后的图片 I_R 以及绘制的两条线(两条中间红线对应AB
和CD
):
然后我画出旋转的线条AfBf
&原始图像中的CfDf
我(黑色粗体点对应于我完成旋转的中心):
IMAGE UPDATED
问题:正如您所看到的, BlueZone 位于AB
和CD
这两行中。但是当它向后旋转时会变成外面,如下图所示(红色箭头指向 BlueZone ):
由于我的问题尚未解决,我选择了导致问题的代码,我将其添加为以下代码段(存储在您可以下载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:我正在使用MATLAB R2012b
答案 0 :(得分:1)
1)你有图像我
2)你将图像I绕其中心旋转(-45度)=> I_R是旋转图像
3)你在I_R (line1& line2)中绘制两条平行线
4)你相对于 imge I
的中心旋转线条步骤4错误您必须选择图像中心I_R作为旋转中心。
来自Matlab Docs:通过默认,imrotate创建一个足够大的输出图像,以包含整个原始图像。落在原始图像边界之外的像素在输出图像中设置为0并且为黑色背景。
>
来自评论: 1)您围绕“I”的中心点旋转图像 (-45degree)
2)当你使用imrotate执行此操作时,函数旋转和 翻译主图片并生成“I_R”,
3)所以中心点 I_R 的中心点是“我”+一些翻译的中心点!。
4)所以主要问题 是计算翻译量,
5)这样做可以使用:Calculating translation value and rotation angle of a rotated 2D image 或者:http://angeljohnsy.blogspot.com/2011/06/image-rotation.html 或
6)只是你可以 在原始图像上使用一些标记(例如在原始图像的中心标记),以查看它翻译了多少(或直接看到I_R的中心),并使用该中心旋转线条。
希望你能找到一些计算翻译的好方法 你可以编写自己的“image_rotation”脚本并不是那么难。
答案 1 :(得分:1)
我找到了解决方案!
嗯,内置函数imrotate
不仅默认情况下会旋转图像,还会进行平移,以便旋转图像适合图中。
解决方案是使用:
I_R = imrotate(I,-45,'nearest','crop');
这里的重要参数是'crop'(bbox):
B = imrotate(A,angle,method,bbox)旋转图像A,其中bbox 指定返回图像的大小。 bbox是一个文本字符串 可以具有以下值之一。默认值包含在中 大括号({})。
'裁剪'使输出图像B与输入图像A的大小相同,裁剪旋转的图像以适合
{'loose'}使输出图像B足够大 包含整个旋转的图像。 B通常大于A。
在函数imrotate here的帮助下。
答案 2 :(得分:0)
可能无法解决问题,但请尝试将矩阵定义为:
R=[ ...
cosd(t) -sind(t)
-sind(t) -cosd(t)
];
绘制图像时,需要注意y轴,自动从上到下。
答案 3 :(得分:0)
我可能会误解某些东西,但你要做的是转动一张照片,画两条线,然后将包括两条线在内的所有东西再次转回来,对吧?
如果是这样,我想最简单的方法就是使用car2pol将它们转换为极坐标。 http://se.mathworks.com/help/matlab/ref/cart2pol.html
那么转换线应该很容易。如果我误解了任何事情,请告诉我。
编辑: 我试着制作一些示例代码,显然我太累了,不能直接思考并且有一些错误,但我想这个想法很明确。另外请不要像我一样使用结构,我只是认为这是命名变量的最简单方法。
%% Load picture
close all
[pic] = dicomread('C0011866_00094.DCM');
%% Get four points
figure, imshow(pic,[]);
title('Select four points'); hold on;
[x,y] = ginput;
%% Plot the lines on top of the figure
hold on
plot(x(1:2),y(1:2),'b');
hold on
plot(x(3:4),y(3:4),'r');
%% Define the lines
%In cartesian coordinates
line1.start.cart = [x(1),y(1)];
line1.end.cart = [x(2),y(2)];
line2.start.cart = [x(3),y(3)];
line2.end.cart = [x(4),y(4)];
%Middle of picture
axises=axis;
center = [mean(axises(1:2)),mean(axises(3:4))];
plot(center(1),center(2),'ro')
%In polar coordinates from center [angle,radius]
[line1.start.pol(1),line1.start.pol(2)] = cart2pol(line1.start.cart(1)-center(1),line1.start.cart(2)-center(2));
[line1.end.pol(1),line1.end.pol(2)] = cart2pol(line1.end.cart(1)-center(1),line1.end.cart(2)-center(2));
[line2.start.pol(1),line2.start.pol(2)] = cart2pol(line2.start.cart(1)-center(1),line2.start.cart(2)-center(2));
[line2.end.pol(1),line2.end.pol(2)] = cart2pol(line2.end.cart(1)-center(1),line2.end.cart(2)-center(2));
%% Rotate the image a degrees
a = 10;
newpic = imrotate(pic,a);
%% Rotate the lines
line1.start.pol(1) = line1.start.pol(1) + a;
line1.end.pol(1) = line1.end.pol(1) + a;
line2.start.pol(1) = line2.start.pol(1) + a;
line2.end.pol(1) = line2.end.pol(1) + a;
%% Transform the coordinates back to cartesian
[line1.start.cart(1), line1.start.cart(2)] = pol2cart(line1.start.pol(1),line1.start.pol(2));
line1.start.cart = line1.start.cart+center;
line1.end.cart = line1.end.cart+center;
[line1.end.cart(1), line1.end.cart(2)] = pol2cart(line1.end.pol(1),line1.end.pol(2));
line2.start.cart = line2.start.cart+center;
line2.end.cart = line2.end.cart+center;
[line2.start.cart(1), line2.start.cart(2)] = pol2cart(line2.start.pol(1),line2.start.pol(2));
[line2.end.cart(1), line2.end.cart(2)] = pol2cart(line2.end.pol(1),line2.end.pol(2));
%% Plot it again
figure
imshow(newpic,[]);
hold on
plot([line1.start.cart(1),line1.end.cart(1)],[line1.start.cart(2),line1.end.cart(2)])
hold on
plot([line2.start.cart(1),line2.end.cart(1)],[line2.start.cart(2),line2.end.cart(2)])
hold on
plot(center(2),center(1),'ro')