如何在MATLAB中绘制纹理贴图三角形?

Pet*_*ter 4 matlab geometry rendering texture-mapping geometry-surface

(u,v)在图像的坐标中有一个三角形.我想在3D坐标处绘制这个三角形,(X,Y,Z)用图像中的三角形进行纹理映射.

这里,u,v,X,Y,Z所有具有三个元素的向量代表三角形的三个角.

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

  1. 提取图像的矩形部分
  2. 使用由三个点定义的变换将其转换为3D空间
  3. 用表面画它
  4. 最后用AlphaData掩盖不属于三角形的所有东西

当然必须有一种更简单的方法吗?

gno*_*ice 13

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

对于我将在此处显示的示例,我将对您的各种参数使用以下值,假设您有一个三角形,其点标记为"原点"(三角形顶点),点"A"和点"B"在图像空间(如下面的第一张图片):

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
Run Code Online (Sandbox Code Playgroud)


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

该步骤使用图像处理工具箱功能maketformimtransform执行包含要作为纹理贴图使用三角形的图像的一部分的投影变换.请注意,由于图像必须是矩形,(O,B,C)因此必须包含由点定义的附加三角形截面.

在此输入图像描述

您想要的图像的三角形部分将位于图像的右下半部分,而附加的三角形"填充"部分将位于左上角.请注意,此附加三角形可以延伸到图像外部,这将导致其中一部分默认情况下填充黑色.这是执行上述投影变换的代码:

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]);
Run Code Online (Sandbox Code Playgroud)

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


绘制三角形纹理映射表面:

绘制曲面现在非常简单,假设您已经对x,y,z变量中的值进行了排序,使得原点的坐标位于第一个索引中,点A的坐标位于第二个索引中,而点B的坐标是在第三个指数.您现在可以创建新的2×2曲面坐标集X,Y,Z,其中包含两个点B的副本,这将导致仅渲染一半曲面(即,包含所需三角形图像的一半作为纹理贴图).这是执行此操作的代码:

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
Run Code Online (Sandbox Code Playgroud)

这里是它创建的纹理映射三角形表面,添加了一个插图,表明纹理贴图包含原始图像的正确三角形部分:

在此输入图像描述