MATLAB 中的纹理映射

发布于 2024-08-26 04:47:06 字数 64 浏览 15 评论 0 原文

我有 3D 空间中的点及其相应的 2D 图像点。如何利用 3D 点制作网格,然后对网格形成的三角形面进行纹理处理?

I have points in 3D space and their corresponding 2D image points. How can I make a mesh out of the 3D points, then texture the triangle faces formed by the mesh?

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

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

发布评论

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

评论(2

空袭的梦i 2024-09-02 04:47:06

请注意,您使用的函数 trisurf最初尝试使用返回 patch 对象的句柄。如果您查看'FaceColor' 补丁对象的属性,可以看到没有'texturemap'选项。该选项仅对 'FaceColor'< 有效表面对象的/code>属性。因此,您必须找到一种方法将三角形表面绘制为表面对象而不是补丁对象。有两种方法可以解决此问题:

如果您的数据位于统一网格中...

如果表面数据的坐标表示统一网格,使得 z 是一组矩形点,其范围为 < x 轴上的 code>xmin 到 xmax ,y 轴上的 yminymax ,您可以使用以下方式绘制它冲浪而不是trisurf

Z = ...  % N-by-M matrix of data
x = linspace(xmin, xmax, size(Z, 2));  % x-coordinates for columns of Z
y = linspace(ymin, ymax, size(Z, 1));  % y-coordinates for rows of Z
[X, Y] = meshgrid(x, y);               % Create meshes for x and y
C = imread('image1.jpg');              % Load RGB image
h = surf(X, Y, Z, flipdim(C, 1), ...   % Plot surface (flips rows of C, if needed)
         'FaceColor', 'texturemap', ...
         'EdgeColor', 'none');
axis equal

为了说明上面的结果代码中,我将数据初始化为 Z = Peaks;,使用内置示例图像 'peppers.png',并设置 xy 值从 1 到 16。这导致了以下纹理映射表面:

在此处输入图像描述

如果您的数据间隔不均匀...

如果您的数据间隔 不均匀...不规则间隔,您可以创建一组规则间隔的 XY 坐标(正如我上面使用 meshgrid),然后使用其中一个函数 griddataTriScatteredInterp 从不规则的 Z 值的规则网格>z 值。我在我对另一个SO问题的回答中讨论了如何使用这两个函数。这是您使用 TriScatteredInterp 发布的代码的改进版本(注意:从 R2013a 开始 scatteredInterpolant 是推荐的替代方案):

x = ...  % Scattered x data
y = ...  % Scattered y data
z = ...  % Scattered z data
xmin = min(x);
xmax = max(x);
ymin = min(y);
ymax = max(y);
F = TriScatteredInterp(x(:), y(:), z(:));  % Create interpolant
N = 50;  % Number of y values in uniform grid
M = 50;  % Number of x values in uniform grid
xu = linspace(xmin, xmax, M);         % Uniform x-coordinates
yu = linspace(ymin, ymax, N);         % Uniform y-coordinates
[X, Y] = meshgrid(xu, yu);            % Create meshes for xu and yu
Z = F(X, Y);                          % Evaluate interpolant (N-by-M matrix)
C = imread('image1.jpg');             % Load RGB image
h = surf(X, Y, Z, flipdim(C, 1), ...  % Plot surface
         'FaceColor', 'texturemap', ...
         'EdgeColor', 'none');
axis equal

在这种情况下,您必须首先选择N<的值/code> 和 M 表示矩阵 Z 的大小。为了说明上述代码的结果,我按如下方式初始化了 xyz 的数据,并使用了内置的在示例图像 'peppers.png' 中:

x = rand(1, 100)-0.5;  % 100 random values in the range -0.5 to 0.5
y = rand(1, 100)-0.5;  % 100 random values in the range -0.5 to 0.5
z = exp(-(x.^2+y.^2)./0.125);  % Values from a 2-D Gaussian distribution

这导致了以下纹理映射表面:

在此处输入图像描述

请注意,表面拐角附近有锯齿状边缘。这些地方的点太少,TriScatteredInterp 无法充分拟合插值曲面。因此,这些点的 Z 值为 nan,导致表面点未被绘制。

Note that the function trisurf that you were originally trying to use returns a handle to a patch object. If you look at the 'FaceColor' property for patch objects, you can see that there is no 'texturemap' option. That option is only valid for the 'FaceColor' property of surface objects. You will therefore have to find a way to plot your triangular surface as a surface object instead of a patch object. Here are two ways to approach this:

If your data is in a uniform grid...

If the coordinates of your surface data represent a uniform grid such that z is a rectangular set of points that span from xmin to xmax in the x-axis and ymin to ymax in the y-axis, you can plot it using surf instead of trisurf:

Z = ...  % N-by-M matrix of data
x = linspace(xmin, xmax, size(Z, 2));  % x-coordinates for columns of Z
y = linspace(ymin, ymax, size(Z, 1));  % y-coordinates for rows of Z
[X, Y] = meshgrid(x, y);               % Create meshes for x and y
C = imread('image1.jpg');              % Load RGB image
h = surf(X, Y, Z, flipdim(C, 1), ...   % Plot surface (flips rows of C, if needed)
         'FaceColor', 'texturemap', ...
         'EdgeColor', 'none');
axis equal

In order to illustrate the results of the above code, I initialized the data as Z = peaks;, used the built-in sample image 'peppers.png', and set the x and y values to span from 1 to 16. This resulted in the following texture-mapped surface:

enter image description here

If your data is non-uniformly spaced...

If your data are not regularly spaced, you can create a set of regularly-spaced X and Y coordinates (as I did above using meshgrid) and then use one of the functions griddata or TriScatteredInterp to interpolate a regular grid of Z values from your irregular set of z values. I discuss how to use these two functions in my answer to another SO question. Here's a refined version of the code you posted using TriScatteredInterp (Note: as of R2013a scatteredInterpolant is the recommended alternative):

x = ...  % Scattered x data
y = ...  % Scattered y data
z = ...  % Scattered z data
xmin = min(x);
xmax = max(x);
ymin = min(y);
ymax = max(y);
F = TriScatteredInterp(x(:), y(:), z(:));  % Create interpolant
N = 50;  % Number of y values in uniform grid
M = 50;  % Number of x values in uniform grid
xu = linspace(xmin, xmax, M);         % Uniform x-coordinates
yu = linspace(ymin, ymax, N);         % Uniform y-coordinates
[X, Y] = meshgrid(xu, yu);            % Create meshes for xu and yu
Z = F(X, Y);                          % Evaluate interpolant (N-by-M matrix)
C = imread('image1.jpg');             % Load RGB image
h = surf(X, Y, Z, flipdim(C, 1), ...  % Plot surface
         'FaceColor', 'texturemap', ...
         'EdgeColor', 'none');
axis equal

In this case, you have to first choose the values of N and M for the size of your matrix Z. In order to illustrate the results of the above code, I initialized the data for x, y, and z as follows and used the built-in sample image 'peppers.png':

x = rand(1, 100)-0.5;  % 100 random values in the range -0.5 to 0.5
y = rand(1, 100)-0.5;  % 100 random values in the range -0.5 to 0.5
z = exp(-(x.^2+y.^2)./0.125);  % Values from a 2-D Gaussian distribution

This resulted in the following texture-mapped surface:

enter image description here

Notice that there are jagged edges near the corners of the surface. These are places where there were too few points for TriScatteredInterp to adequately fit an interpolated surface. The Z values at these points are therefore nan, resulting in the surface point not being plotted.

一身仙ぐ女味 2024-09-02 04:47:06

如果您的纹理已经处于正确的几何形状中,您可以只使用常规的旧纹理映射。

纹理映射的 MathWorks 文档的链接:
http://www.mathworks。 com/access/helpdesk/help/techdoc/visualize/f0-18164.html#f0-9250

重新编辑:稍微更新了代码:

尝试这种方法(我刚刚让它工作)。

 a=imread('image.jpg');
 b=double(a)/255;

 [x,y,z]=peaks(30);  %# This is a surface maker that you do have
                     %# The matrix [x,y,z] is the representation of the surface.

 surf(x,y,z,b,'FaceColor','texturemap')  %# Try this with any image and you 
                                         %# should see a pretty explanatory 
                                         %# result. (Just copy and paste) ;)

因此 [x,y,z] 是“表面”,或者更确切地说是一个矩阵,其中包含表面上的许多 (x,y,z) 形式的点。请注意,图像被拉伸以适合表面。

If your texture is already in the proper geometry you can just use regular old texture mapping.

The link to the MathWorks documentation of texture mapping:
http://www.mathworks.com/access/helpdesk/help/techdoc/visualize/f0-18164.html#f0-9250

Re-EDIT: Updated the code a little:

Try this approach (I just got it to work).

 a=imread('image.jpg');
 b=double(a)/255;

 [x,y,z]=peaks(30);  %# This is a surface maker that you do have
                     %# The matrix [x,y,z] is the representation of the surface.

 surf(x,y,z,b,'FaceColor','texturemap')  %# Try this with any image and you 
                                         %# should see a pretty explanatory 
                                         %# result. (Just copy and paste) ;)

So [x,y,z] is the 'surface' or rather a matrix containing a number of points in the form (x,y,z) that are on the surface. Notice that the image is stretched to fit the surface.

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