2D texture map

I have a set of points [x,y]=meshgrid(1:N,1:M) defined on a regular 2D, N x M grid. I have one more set of points [u,v] , which are some deformation of the original mesh, ie [u,v]=f(x,y)' (however, I don’t have the actual f causing the deformation). How can I match a texture to a β€œwarped” mesh defined by u,v ? that is, given an image with an N/M aspect ratio, how can I match it to a deformed mesh?

+4
source share
4 answers

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

Say the texture samples are in z , and you need new z2 samples. To interpolate the original texture in [u,v] , use:

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

On the other hand, if you want to map the β€œwarped” texture back onto the spaced grid [x2,y2] , use griddata :

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

Update:

Here is a sample code showing how to do this with real data. Using normalized coordinates makes the process 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

+6
source

EDIT:

Here is an example of mapping textures using surface :

 %# 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 taken 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, colormap / CDataMapping is no longer needed ...

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


Please note that in the above example, I am using an indexed color image with the corresponding color code. The code can be easily adapted to work with full images in RGB format. See this page for an explanation of the different types of images.

+4
source

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

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

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

This will print the given coordinates (x, y) tform

Similarly, tforminv converts points from the output space to the input space. If we apply the inverse transformation to the point xy calculated above, we must return the starting point.

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

Thus, you can use this mechanism to match points using direct and inverse geometric transforms.

If you use R2013a and later, you can use the transformPointsForward and transformPointsInverse methods for geometric transformation classes (e.g. affine2d, projective2d), as well as consider imwarp .

+1
source

Assuming that x , y , u and v are the same size ( MxN 2D matrices), and the image / texture you want to display is I MxNx3 sized (three color channels), then you may find scatter useful:

 figure; scatter( u(:), v(:), 30, reshape( I, [], 3 ), 's', 'filled' ); 
+1
source

All Articles