10

我在 3D 空间中有点及其对应的 2D 图像点。如何从 3D 点制作网格,然后纹理由网格形成的三角形面?

4

2 回答 2

5

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

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

如果您的表面数据的坐标表示一个统一的网格,例如z一组矩形的点,这些点在 x 轴上从xmin到,在 y 轴上从 到 ,您可以使用而不是绘制它:xmaxyminymaxsurftrisurf

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),然后使用其中一个函数griddata或从您的不规则值集中TriScatteredInterp插入规则网格值。我在回答另一个 SO question时讨论了如何使用这两个函数。这是您使用发布的代码的精炼版本(注意:从 R2013a 开始,推荐替代方案):ZzTriScatteredInterpscatteredInterpolant

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和的值。为了说明上述代码的结果,我对、、 和的数据进行了如下初始化,并使用了内置的示例图像:MZxyz'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,导致未绘制表面点。

于 2010-03-21T20:37:04.243 回答
1

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

纹理映射的 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) 形式的许多点。请注意,图像被拉伸以适合表面。

于 2010-03-21T18:31:07.513 回答