Dav*_*fte 2 matlab image-processing
我正在尝试在matlab中旋转3轴上的图像.我使用函数rotx,roty,rotz来创建旋转矩阵,但我不知道如何使用.这些方法是否将中心点视为原点?
由于图像是来自3D世界的2D投影,因此如果您希望这样做,则需要将其中一个3D平面设置为0.我将假设z平面等于0,因此图像平放在z = 0平面上.
基本上......这样的事情,使用cameraman.tif图像.这就是它原来的样子:
这是它在3D中的样子.首先,加载图像,为图像中的(x,y)每个强度生成对.这是完成的meshgrid.执行此操作后,使用scatter绘制每个点的假设z = 0,并使每个点的颜色成为在图像坐标处看到的实际强度.但是,您只能在2D视角中看到这一点,因为scatter它自然是2D.要制作此3D,请更改相机视图,以便使用MATLAB的默认3D视图查看图像,然后添加一些内容,如标签和网格,以及反转y坐标,y因为图像的坐标向下是正向的:
%// 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
Run Code Online (Sandbox Code Playgroud)
我们得到这个:
但是,这仅适用于灰度图像.如果要在颜色上执行相同操作,则需要更改指定每个点颜色的方式.这只是通过提取红色,绿色和蓝色平面并将它们作为单个列放在颜色矩阵中作为第四个参数来完成.具体来说,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);
Run Code Online (Sandbox Code Playgroud)
所以现在我们有了这个,您只需要获取上一步中生成的X和Y坐标,并使用旋转矩阵旋转每个坐标.请记住,Z坐标全为零.
相对于要旋转点的每个轴定义了旋转矩阵.每个轴的旋转矩阵如下所示:

资料来源:维基百科
因此,只需将上面的解开坐标,将它们应用于旋转矩阵,然后使用这些新坐标并绘制点即可.请记住,对于图像坐标,y轴向下是正向的,因此顺时针方向旋转是正角度,逆时针旋转是负角度.
假设原点位于(x,y,z) = (0,0,0)(也是我们的情况)旋转3D点,它只是一个矩阵乘法:
Pout = R*P;
Run Code Online (Sandbox Code Playgroud)
P是一个3×1向量(x,y,z)分和Pout是旋转的输出矢量(也3×1).因此,如果你想为我们所有的点做这个,你必须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)];
Run Code Online (Sandbox Code Playgroud)
现在你完成了,旋转点:
Pout = Rx*[x_coord.'; y_coord.'; zeros(1,numel(x_coord))];
Run Code Online (Sandbox Code Playgroud)
完成后,请scatter使用这些新点进行调用.我会做的是打电话,scatter3因为这是专为3D点设计的,我还需要旋转相机才能正确看到事物:
scatter3(Pout(1,:), Pout(2,:), Pout(3,:), 2, repmat(double(im(:)), 1, 3)/255);
axis ij; xlabel('Columns'); ylabel('Rows');
view(-105, 35);
Run Code Online (Sandbox Code Playgroud)
如果您有彩色图像,请确保将第四个参数更改为我在本文开头所讨论的内容.
我们得到这个:
x这里的轴是列,旋转类似于想象一本平放在平面上的书z = 0并从书中打开一页.书的主干是x轴或列.
y-轴你做同样的事情,但使用不同的旋转矩阵.但是,为了更好地透视这种方式,我需要稍微改变相机角度:
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
Run Code Online (Sandbox Code Playgroud)
这就是我们得到的:
效果相同,但旋转轴已发生变化.这本书的主要内容是关于行而不是列.
z-轴这个非常温和.这应该具有在没有高度的桌子上旋转纸张的效果:
theta = pi/3; %// 60 degree rotation for example
Rz = [cos(theta) -sin(theta) 0; sin(theta) cos(theta) 0; 0 0 1];
Pout = Rz*[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');
Run Code Online (Sandbox Code Playgroud)
....和:
希望这足以让你开始.祝好运!