如何在MATLAB中绘制纹理映射的三角形? [英] How do I draw a texture-mapped triangle in MATLAB?

查看:136
本文介绍了如何在MATLAB中绘制纹理映射的三角形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在图像中的(u,v)坐标中有一个三角形。我想绘制这个三角形的三维坐标(X,Y,Z)纹理贴图与图像中的三角形。



这里, u,v,X,Y,Z 都是带有三个元素的矢量,代表三角形的三个角。 b

我有一个非常难看,缓慢且令人不满意的解决方案,其中我:


  1. image

  2. 用三点定义的转换将它转换为三维空间
  3. 用曲面绘制它
  4. 最后用AlphaData掩盖不属于三角形的所有内容

当然,这样做肯定有更简单的方法吗?

解决方案

我认为这是一个更好的解决方案,涉及两个步骤。首先,它提取图像的矩形部分,其中一半是用作纹理贴图的三角形部分,其中一半将被忽略。然后,这个纹理贴图被应用到一个三维曲面对象上,这个对象的点被调整为将它呈现为一个三角形而不是一个四边形。



例如,我会在这里展示,假设您有一个三角形的点在图像空间中被标记为原点(三角形顶点),点A和点B(如第一个

  x = [0.1 0.9 0.8];三维空间中的%[​​xorigin xA xB]坐标
y = [0.9 0.1 0.8];在三维空间中的%[​​yorigin yA yB]坐标
z = [0.1 0.1 0.9];三维空间中的%[​​zorigin zA zB]坐标
origin = [150 350];图像空间中三角形的%顶点
U = [300 -50]; %图像空间中从原点到点A的矢量
V = [50 -250]; %图像空间中从原点到点B的向量
img = imread('peppers.png'); %纹理贴图的示例图像




通过投影转换提取纹理贴图:



这一步使用



你想要的图像的三角形部分将位于图像,而另外的三角形填充物部分将位于左上角。请注意,这个额外的三角形可以延伸到图像之外,这会导致其中一部分默认填充黑色。下面是执行上述投影变换的代码:

  A =原点+ U; %点A 
B =原点+ V; %点B
C = B-U; %C
[nRows,nCols,nPages] = size(img); %图像尺寸
inputCorners = [原点; ...%输入空间的角坐标
A; ...
B; ...
C];
outputCorners = [1 nRows; ...%输出空间的角坐标
nCols nRows; ...
nCols 1; ...
1 1];
tform = maketform('projective',...%创建转换结构
inputCorners,...
outputCorners);
triTexture = imtransform(img,tform,'bicubic',...%转换图像
'xdata',[1 nCols],...
'ydata',[1 nRows ],...
'size',[nRows nCols]);

请注意,此代码将创建最终图像 triTexture 与输入图像的大小相同 img






绘制三角形纹理贴图表面:



绘制曲面现在非常简单,假设您已将 x,y,z 变量,以便原点的坐标位于第一个索引中,A点的坐标位于第二个索引中,B点的坐标是在第三个指数。现在,您可以创建包含两个B点副本的新的2 x 2表面坐标集合 X,Y,Z ,这会导致只有一半的表面被渲染(即,包含所需三角形图像的一半作为纹理图)。以下是执行此操作的代码:

  index = [3 3; 1 2];用于创建2乘2表面坐标的%Index 
X = x(index); %x表面的坐标
Y = y(索引); %y表面的坐标
Z = z(index); %z坐标表面
hSurface = surf(X,Y,Z,triTexture,...%绘制纹理贴图表面
'FaceColor','texturemap'...
' EdgeColor','none');
轴等于%在轴上使用等比例缩放
轴([0 1 0 1 0 1]); %设置轴限制
xlabel('x-axis'); %x轴标签
ylabel('y-axis'); %y轴标签
zlabel('z-axis'); %z轴标签

以下是生成的纹理映射三角形曲面,添加了插入以显示纹理贴图包含原始图像的正确三角部分:


I have a triangle in (u,v) coordinates in an image. I would like to draw this triangle at 3D coordinates (X,Y,Z) texture-mapped with the triangle in the image.

Here, u,v,X,Y,Z are all vectors with three elements representing the three corners of the triangle.

I have a very ugly, slow and unsatisfactory solution in which I:

  1. extract a rectangular part of the image
  2. transform it to 3D space with the transformation defined by the three points
  3. draw it with surface
  4. finally masking out everything that is not part of the triangle with AlphaData

Surely there must be an easier way of doing this?

解决方案

I have what I think is a better solution for you involving two steps. First, it extracts a rectangular part of your image, half of which is the triangular section to be used as a texture map and half of which will be ignored. Then this texture map is applied to a 3-D surface object whose points are adjusted to render it as a triangle instead of a quadrilateral.

For the example I will show here, I will use the following values for your various parameters, assuming you have a triangle whose points are labeled as the "origin" (triangle vertex), point "A", and point "B" in the image space (as in the first image below):

x = [0.1 0.9 0.8];   % [xorigin xA xB] coordinates in 3-D space
y = [0.9 0.1 0.8];   % [yorigin yA yB] coordinates in 3-D space
z = [0.1 0.1 0.9];   % [zorigin zA zB] coordinates in 3-D space
origin = [150 350];  % Vertex of triangle in image space
U = [300 -50];       % Vector from origin to point A in image space
V = [50 -250];       % Vector from origin to point B in image space
img = imread('peppers.png');  % Sample image for texture map


Extracting the texture map via projective transformation:

This step uses the Image Processing Toolbox functions maketform and imtransform to perform a projective transformation of the part of the image containing the triangle you want to use as a texture map. Note that since images have to be rectangular, an additional triangular section defined by points (O,B,C) has to be included.

The triangular part of the image you want will be in the lower right half of the image, while the additional triangular "filler" part will be in the upper left. Note that this additional triangle can extend outside of the image, which will cause part of it to be filled with black by default. Here's the code to perform the projective transform illustrated above:

A = origin+U;  % Point A
B = origin+V;  % Point B
C = B-U;       % Point C
[nRows, nCols, nPages] = size(img);  % Image dimensions
inputCorners = [origin; ...          % Corner coordinates of input space
                A; ...
                B; ...
                C];
outputCorners = [1 nRows; ...        % Corner coordinates of output space
                 nCols nRows; ...
                 nCols 1; ...
                 1 1];
tform = maketform('projective', ...  % Make the transformation structure
                  inputCorners, ...
                  outputCorners);
triTexture = imtransform(img,tform, 'bicubic', ...  % Transform the image
                         'xdata', [1 nCols], ...
                         'ydata', [1 nRows], ...
                         'size', [nRows nCols]);

Note that this code will create a final image triTexture that is the same size as the input image img.


Plotting the triangular texture-mapped surface:

Plotting the surface is now quite simple, assuming you've ordered the values in your x,y,z variables such that the coordinates for the origin point are in the first indices, the coordinates for point A are in the second indices, and the coordinates for point B are in the third indices. You can now create new sets of 2-by-2 surface coordinates X,Y,Z that contain two copies of point B, which causes only half of the surface to be rendered (i.e. the half containing the desired triangular image as a texture map). Here's the code to do this:

index = [3 3; 1 2];  % Index used to create 2-by-2 surface coordinates
X = x(index);        % x coordinates of surface
Y = y(index);        % y coordinates of surface
Z = z(index);        % z coordinates of surface
hSurface = surf(X, Y, Z, triTexture, ...  % Plot texture-mapped surface
                'FaceColor', 'texturemap', ...
                'EdgeColor', 'none');
axis equal            % Use equal scaling on axes
axis([0 1 0 1 0 1]);  % Set axes limits
xlabel('x-axis');     % x-axis label
ylabel('y-axis');     % y-axis label
zlabel('z-axis');     % z-axis label

And here's the resulting texture-mapped triangular surface it creates, with an inset added to show that the texture map contains the correct triangular part of the original image:

这篇关于如何在MATLAB中绘制纹理映射的三角形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆