如何在 MATLAB 中绘制纹理映射三角形?

发布于 2024-08-21 17:36:28 字数 324 浏览 11 评论 0原文

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

这里,u,v,X,Y,Z 都是向量,其中三个元素代表三角形的三个角。

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

  1. 提取图像的矩形部分
  2. 使用由三个点定义的变换将其转换为 3D 空间
  3. 用曲面绘制它
  4. 最后用 遮盖掉不属于三角形的所有内容AlphaData

当然必须有一种更简单的方法来做到这一点吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚风撩人 2024-08-28 17:36:28

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

对于我将在此处展示的示例,我将为您的各种参数使用以下值,假设您有一个三角形,其点被标记为“原点”(三角形顶点)、点“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

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

此步骤使用 图像处理工具箱函数 maketformimtransform< /a> 对包含要用作纹理贴图的三角形的图像部分执行投影变换。请注意,由于图像必须是矩形,因此必须包含由点 (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]);

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

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

绘制表面现在非常简单,假设您已对 x,y,z 变量中的值进行排序,使得原点的坐标为在第一个索引中,A点的坐标在第二个索引中,B点的坐标在第三个索引中。现在,您可以创建新的 2×2 表面坐标 X,Y,Z 集,其中包含 B 点的两个副本,这会导致仅渲染表面的一半(即包含 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

这是它创建的结果纹理映射三角形表面,添加了一个插图以显示纹理映射包含原始图像的正确三角形部分

: sstatic.net/zJUms.jpg" rel="nofollow noreferrer">在此处输入图像描述

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.

enter image description here

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:

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文