在Matlab中在X,Y和Z轴上旋转图像

时间:2015-08-30 18:39:06

标签: matlab image-processing

我试图在matlab中将图像旋转到3轴上。 我使用函数rotx,roty,rotz来创建旋转矩阵,但我不知道如何使用。 这些方法是否将中心点视为原点?

1 个答案:

答案 0 :(得分:7)

由于图像是来自3D世界的2D投影,因此如果您希望这样做,则需要将其中一个3D平面设置为0。我将假设z - 平面等于0,因此图像平放在z = 0平面上。

基本上......使用cameraman.tif图片。这就是最初的样子:

enter image description here

这就是它在3D中的样子。首先,加载图像,为图像中的每个强度生成(x,y)对。这是通过meshgrid完成的。完成此操作后,使用scatter绘制假定z = 0的每个点,并使每个点的颜色成为图像坐标处的实际强度。但是,您只能在2D视角中看到这一点,因为scatter自然是2D。要制作此3D,请更改相机视图,以便使用MATLAB的默认3D视图查看图像,然后添加标签和网格等内容以及将y坐标反转为{{1图像的坐标向下是正向的:

y

我们得到了这个:

enter image description here

但是,这仅适用于灰度图像。如果要在颜色上执行相同操作,则需要更改指定每个点颜色的方式。这只是通过提取红色,绿色和蓝色平面并将它们作为单个列放在颜色矩阵中作为第四个参数来完成。具体来说,%// Load in the image im = imread('cameraman.tif'); %// Generate coordinates and unravel into a single vector [X,Y] = meshgrid(1:size(im,2), 1:size(im,1)); x_coord = X(:); y_coord = Y(:); %// Plot the image as a scatter plot scatter(x_coord, y_coord, 2, repmat(double(im(:)), 1, 3)/255); view(3); grid; xlabel('Columns'); ylabel('Rows'); axis ij 命令现在是:

scatter

现在我们有了这个,您只需要采用上一步中生成的red = reshape(im(:,:,1), [], 1); green = reshape(im(:,:,2), [], 1); blue = reshape(im(:,:,3), [], 1); scatter(x_coord, y_coord, 2, double([red green blue])/255); X坐标,并使用旋转矩阵旋转每个坐标。请记住,Y坐标全为零。

相对于要旋转点的每个轴定义了旋转矩阵。每个轴的旋转矩阵如下所示:

来源:Wikipedia

因此,只需要将上面的解开坐标,将它们应用于旋转矩阵,然后使用这些新坐标并绘制点。请记住,对于图像坐标,Z轴向下是正向,因此顺时针方向旋转为正角度,逆时针旋转为负角度。

要假设原点位于y(这也是我们的情况),要旋转3D点,它只是一个矩阵乘法:

(x,y,z) = (0,0,0)

Pout = R*P; P点的3 x 1向量,(x,y,z)是旋转的输出向量(也是3 x 1)。因此,如果您想对我们的所有点执行此操作,则必须将Pout放入P矩阵,其中3 x N是图像中的总像素数,请N,然后使用结果点作为R*P的输入。

我们可以展示当我们独立旋转每个轴时会发生什么。

scatter - 轴

首先为给定的旋转角度x创建x轴的旋转矩阵:

theta

现在你完成了,旋转点:

theta = pi/3; %// 60 degree rotation for example
Rx = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];

完成后,请使用这些新积分致电Pout = Rx*[x_coord.'; y_coord.'; zeros(1,numel(x_coord))]; 。我要做的是致电scatter,因为这是专为3D点设计的,我还需要旋转相机才能正确看到事情:

scatter3

如果您有彩色图像,请确保将第四个参数更改为我在本文开头所讨论的内容。

我们得到了这个:

enter image description here

这里的scatter3(Pout(1,:), Pout(2,:), Pout(3,:), 2, repmat(double(im(:)), 1, 3)/255); axis ij; xlabel('Columns'); ylabel('Rows'); view(-105, 35); 轴是列,旋转类似于想象一本书平放在x平面上并打开书中的页面。本书的主题是z = 0轴或列。

x - 轴

您使用不同的旋转矩阵执行相同的操作。但是,为了更好地透视这种方式,我需要稍微改变相机角度:

y

这就是我们得到的:

enter image description here

效果相同,但旋转轴已更改。书的主要内容是行,而不是列。

theta = pi/3; %// 60 degree rotation for example Ry = [cos(theta) 0 sin(theta); 0 1 0; -sin(theta) 0 cos(theta)]; Pout = Ry*[x_coord.'; y_coord.'; zeros(1,numel(x_coord))]; scatter3(Pout(1,:), Pout(2,:), Pout(3,:), 2, repmat(double(im(:)), 1, 3)/255); axis ij; xlabel('Columns'); ylabel('Rows'); view(5,30); %// Change camera angle so that you're looking at the x plane better - 轴

这个非常温和。这应该具有在没有高度的桌子上旋转纸张的效果:

z

....和:

enter image description here

希望这足以让你入门。祝你好运!