【问题标题】:Texture mapping in MATLABMATLAB 中的纹理映射
【发布时间】:2010-03-21 18:00:16
【问题描述】:

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

【问题讨论】:

  • @srand:对您的问题进行重大修改时,通常最好保留原始材料,然后添加标题为“编辑”或“更新”的新材料。这样,答案就更有意义了。 ;)

标签: matlab plot interpolation texture-mapping geometry-surface


【解决方案1】:

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

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

如果您的表面数据的坐标表示一个统一的网格,使得z 是一组矩形点,在 x 轴上从 xminxmax,在 yminymax y 轴,您可以使用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. 这产生了以下纹理映射表面:

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

如果您的数据不是规则间隔的,您可以创建一组规则间隔的XY 坐标(就像我在上面使用meshgrid 所做的那样),然后使用其中一个函数griddata 或@ 987654329@ 从不规则的 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

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

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

【讨论】:

  • 我并不特别喜欢使用 trisurf,只要我得到某种网格,可以是补丁、曲面、网格等对象类型。关于补丁对象,您还需要了解哪些其他信息?
  • @srand:我用一些通用指南更新了我的答案,用于从数据中创建规则间隔点的表面,无论它可能是什么。
  • @srand:我忘记了 FLIPUD 只在二维数组上运行。我改用 FLIPDIM 修复了代码。
  • 我在 3d 空间中只有点,Z 必须是连续的吗?我用我的数据试了一下,它不能正常工作。 (见更新的代码)
  • @srand:我在我的答案中添加了您更新代码的改进版本。希望这对你想做的事情有用。
【解决方案2】:

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

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

【讨论】:

  • 正确几何是什么意思?我试过 [X, map] = rgb2ind(imread('image.jpg'), 128);颜色图(地图);但它没有给出我期望的结果。
  • 您用作“纹理”的图像将被投影到您的表面上。首先想象你的表面是完全平坦的。然后将图像“打印”到您的表面上,然后将表面拉伸并弯曲成形。
  • 什么是 SupBSpline?我想我没有。
  • SupBSpline 只是制作了一个很酷的表面。如果你不能使用它,你可以手工制作一个表面。
  • 你能给我一个表面的例子吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 2011-05-04
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多