Texture map for a 2D grid

冷暖自知 提交于 2020-01-12 03:49:07

问题


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 deformation of the original grid, i.e [u,v]=f(x,y)' (however I do not have the actual f that caused the deformation). How can I map a texture to the "deformed" grid defined by u,v? i.e., given an image with aspect-ratio N/M how can I map it to the deformed grid?


回答1:


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:




回答2:


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)

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.




回答3:


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' );



回答4:


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.



来源:https://stackoverflow.com/questions/16239667/texture-map-for-a-2d-grid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!