我imrotate()一个图像,绘制两条线,旋转线并在原始图像中绘制它们,但是没有在MATLAB中得到预期的结果?

时间:2015-05-24 08:42:17

标签: matlab rotation translation image-rotation

我想做什么:

假设我有一张图像 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 以及绘制的两条线(两条中间红线对应ABCD):

The two middle lines correspond to AB and CD

然后我画出旋转的线条AfBf&原始图像中的CfDf (黑色粗体点对应于我完成旋转的中心):

IMAGE UPDATED enter image description here

问题:正如您所看到的, BlueZone 位于ABCD这两行中。但是当它向后旋转时会变成外面,如下图所示(红色箭头指向 BlueZone ):

enter image description here

更新添加了一个SNIPPET

由于我的问题尚未解决,我选择了导致问题的代码,我将其添加为以下代码段(存储在您可以下载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

4 个答案:

答案 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')