Texture map for a 2D grid

前端 未结 4 577
名媛妹妹
名媛妹妹 2021-02-06 15:56

I have a set of points [x,y]=meshgrid(1:N,1:M) defined on a regular 2D, N x M grid. I have another set of points [u,v] that are some defor

相关标签:
4条回答
  • 2021-02-06 16:28

    It seems that you can use tformfwd and tforminv with a small twist to get f.

    tformfwd transforms points from input space to output space. For example, to apply an affine transform to the point (u,v) = (5,3), you can do this:

    uv = [5 3];
    xy = tformfwd(tform, uv)
    

    This will out put the (x,y) coordinates given tform

    Similarly, tforminv transforms points from output space to input space. If we apply the inverse transformation to the point xy computed above, we should get back the original point.

    uvp = tforminv(tform, xy)
    uvp =
         5     3
    

    So, you can use this machinery to map points by the forward and inverse geometric transformation.

    If you are using R2013a and later, you can use the transformPointsForward and transformPointsInverse methods of the geometric transformation classes (e.g. affine2d, projective2d), and also consider imwarp.

    0 讨论(0)
  • 2021-02-06 16:45

    Assuming x, y, u and v are of the same size (MxN 2D matrices) and the image/texture you wish to map is I of size MxNx3 (three color channels), then you might find scatter useful:

    figure;
    scatter( u(:), v(:), 30, reshape( I, [], 3 ), 's', 'filled' );
    
    0 讨论(0)
  • 2021-02-06 16:47

    EDIT:

    Here is an example of texture mapping using the surface function:

    %# image and 2D grid of points of the same size as the image
    img = load('clown');    %# indexed color image
    [m,n] = size(img.X);
    [a,b] = meshgrid(1:n,1:m);
    
    %# initial grid (here 1/5-th the size, but could be anything)
    [X,Y] = meshgrid(linspace(1,n,n/5),linspace(1,m,m/5));
    
    %# resize image to fit this grid
    [C,map] = imresize(img.X, img.map, size(X), 'bicubic');
    
    %# deformed 2D points (we dont need to know f, just load U/V here)
    fx = @(x,y) sqrt(x);
    fy = @(x,y) y.^2;
    U = fx(X,Y);
    V = fy(X,Y);
    
    %# Z-coordinates: I'm using Z=0 for all points, but could be anything
    Z = zeros(size(U));
    %Z = peaks(max(size(U))); Z = Z(1:size(U,1),1:size(U,2)); view(3)
    
    %# show image as texture-mapped surface
    surface(U, V, Z, C, 'CDataMapping','direct', ...
        'FaceColor','texturemap', 'EdgeColor','none')
    colormap(map)
    axis ij tight off
    view(2)
    

    pic

    An alternative to using imresize is explicit interpolation (idea borrowed from @shoelzer):

    CC = ind2rgb(img.X, img.map);    %# convert to full truecolor
    C = zeros(size(X));
    for i=1:size(CC,3)
        C(:,:,i) = griddata(a,b, CC(:,:,i), X,Y, 'linear');
    end
    

    of course with this change, there is no need for the colormap/CDataMapping anymore...

    (Note: I think interp2 would be much faster here)


    Note that in the example above, I'm using an indexed color image with an associated colormap. The code can easily be adapted to work on grayscale or truecolor full RGB images. See this page for an explanation on the different image types.

    0 讨论(0)
  • 2021-02-06 16:48

    I think you are asking to get samples of the original texture at [u,v]. You can use interp2.

    Let's say that the texture samples are in z and you want new samples z2. To interpolate the original texture at [u,v], use:

    z2 = interp2(x,y,z,u,v);
    

    On the other hand, if you want to map the "deformed" texture back to a regularly spaced grid [x2,y2], use griddata:

    [x2,y2] = meshgrid(1:N2,1:M2);
    z2 = griddata(u,v,z,x2,y2);
    

    Update:

    Here's some example code showing how to do this with real data. Using normalized coordinates makes it easier.

    % get texture data
    load penny
    z = P;
    
    % define original grid based on image size
    [m,n] = size(z);
    [a,b] = meshgrid(linspace(0,1,n), linspace(0,1,m));
    
    % define new, differently sized grid
    m2 = 256;
    n2 = 256;
    [x,y] = meshgrid(linspace(0,1,n2), linspace(0,1,m2));
    
    % define deformed grid
    u = sqrt(x);
    v = y.^2;
    
    % sample the texture on the deformed grid
    z2 = interp2(a,b,z,u,v);
    
    % plot original and deformed texture
    figure
    subplot(2,1,1)
    surface(a,b,z,'EdgeColor','none')
    axis ij image off
    colormap gray
    title('original')
    subplot(2,1,2)
    surface(x,y,z2,'EdgeColor','none')
    axis ij image off
    colormap gray
    title('deformed')
    

    And this is the result:

    Plot of original and deformed texture

    0 讨论(0)
提交回复
热议问题