我有3D空间中的点及其对应的2D图像点。如何在3D点之外制作网格,然后对由网格形成的三角形面进行纹理处理?
最佳答案
请注意,您最初尝试使用的函数 trisurf
将返回补丁对象的句柄。如果查看 'FaceColor'
property for patch objects,可以看到没有'texturemap'
选项。该选项仅对 'FaceColor'
property of surface objects有效。因此,您将必须找到一种方法来绘制三角形表面作为表面对象而不是面片对象。这里有两种方法可以解决这个问题:
如果您的数据在统一的网格中...
如果表面数据的坐标表示一个统一的网格,使得z
是在x轴上从xmin
到xmax
,在y轴上从ymin
到ymax
的矩形点集,则可以使用 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'
,并将x
和y
的值设置为从1到16。这导致了下面的纹理映射表面:如果您的数据间隔不均匀...
如果您的数据不是规则间隔的,则可以创建一组规则间隔的
X
和Y
坐标(就像我在上面使用 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
在这种情况下,您必须首先选择
N
和M
的值作为矩阵Z
的大小。为了说明上述代码的结果,我按如下所示初始化了x
,y
和z
的数据,并使用了内置的示例图像'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
,导致未绘制表面点。