Texture mapping in MATLAB

后端 未结 2 1323
无人共我
无人共我 2021-01-02 05:14

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?

2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-02 05:30

    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:

    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:

    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.

提交回复
热议问题