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

最佳答案

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

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

如果表面数据的坐标表示一个统一的网格,使得z是在x轴上从xminxmax,在y轴上从yminymax的矩形点集,则可以使用 surf 而不是 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。这导致了下面的纹理映射表面:

matlab - MATLAB中的纹理映射-LMLPHP

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

如果您的数据不是规则间隔的,则可以创建一组规则间隔的XY坐标(就像我在上面使用 meshgrid 所做的那样),然后使用函数 griddata TriScatteredInterp 从不规则中插入规则的Z值网格一组z值。我讨论了如何在my answer to another SO question中使用这两个函数。这是您使用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

在这种情况下,您必须首先选择NM的值作为矩阵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

这导致了以下纹理贴图表面:

matlab - MATLAB中的纹理映射-LMLPHP

请注意,曲面拐角附近有锯齿状的边缘。在这些地方,TriScatteredInterp的点太少,不足以完全适合插值曲面。因此,这些点处的Z值为 nan ,导致未绘制表面点。

10-08 09:24
查看更多