Steve on Image Processing

June 13th, 2006

Spatial transformations: findbounds

I've written previously about how Image Processing Toolbox uses inverse mapping to implement spatial transforms. In this method, you set up a grid in output space. For each pixel in the output space grid, you use the inverse transform to determine the corresponding input space location, and you interpolate to get the input image pixel value at that point.

I've also written about the question of where to establish the grid in output space. If you don't somehow pay attention to the specific transformation, you might choose a grid that's too small:

Or your grid might be too big:

Or your grid might be in the wrong place completely:

To avoid these problems (and to avoid the tech support calls!), the function imtransform uses the function findbounds to determine automatically where to place the output grid and how big it should be.

findbounds first creates a grid of points. These points are located in input space at each corner of the image, as well as in between each corner and in the middle. It looks like this:

I = imread('rice.png');
h = imshow(I);
set(h,'AlphaData',0.3);
axis on, grid on
in_points = [ ...
    0.5000    0.5000
    0.5000  256.5000
  256.5000    0.5000
  256.5000  256.5000
    0.5000  128.5000
  128.5000    0.5000
  128.5000  128.5000
  128.5000  256.5000
  256.5000  128.5000];
hold on
plot(in_points(:,1), in_points(:,2), '.', 'MarkerSize', 18)
hold off

findbounds then calls tformfwd to transform these points into output space. (For this example I'm going to construct an affine tform struct that combines scaling, rotation, shear, and a large translation.)

tform = maketform('affine', ...
    [1.1067 -0.2341 0; 0.5872 1.1769 0; 1000 -300 1]);
out_points = tformfwd(tform, in_points)
out_points =

  1.0e+003 *

    1.0008   -0.2995
    1.1512    0.0018
    1.2842   -0.3595
    1.4345   -0.0582
    1.0760   -0.1489
    1.1425   -0.3295
    1.2177   -0.1789
    1.2928   -0.0282
    1.3593   -0.2088

plot(out_points(:,1), out_points(:,2), '.', 'MarkerSize', 18)
axis ij, axis image
grid on

The bounding box of the points in output space tells us where to put the output space grid.

When you call imtransform, you can use optional output arguments to determine where the image is located in output space.

[J,XData,YData] = imtransform(I, tform);
XData
XData =

  1.0e+003 *

    1.0017    1.4337

YData
YData =

 -358.7527    1.2473

You can use this information together with imshow to place the image in the right place on an axes that contains other X-Y data.

h = imshow(J,'XData',XData,'YData',YData);
set(h,'AlphaData',0.3)
hold on
plot(out_points(:,1), out_points(:,2), '.', 'MarkerSize', 18)
axis on
grid on
hold off
axis ij, axis image

So that's the method imtransform uses to determine where the output image should be in output space.

In a future posting I'll cover two more topics related to findbounds and imtransform:

  • What to do when there's no forward transform in the tform structure
  • The special problem of pure translation


Get the MATLAB code

Published with MATLAB® 7.2

12 Responses to “Spatial transformations: findbounds”

  1. Qi Chen replied on :

    Excellent explanation. I suggest to include this in the help documentation. I have struggled for understanding how imtransform works when reading the help file in matlab. I wasn’t clear until reading this.

  2. Steve replied on :

    Qi – Thanks for the suggestion.

  3. and replied on :

    i have a data set of points (10 points of the image in different places of the image) of an image that i’m interest to and i would like to know if there is a way to know where these points would be after a rotation .

  4. Steve replied on :

    And—The functions tformfwd and tforminv can be used to transform point locations. See my February 10, 2006 post.

  5. Zhenbo Wang replied on :

    Hi,Steve.
    Would you give a specific Example by using findbounds function,PLZ? I still don’t quite get it after reading the “findbounds” demo.

  6. Steve replied on :

    Zhenbo—Can you say more about what you are looking for? I gave a specific example in this post. Also, be aware that users generally don’t need to worry about calling findbounds directly. This post was intended to explain a little bit about what’s going on behind the scene.

  7. Tom replied on :

    Hi Steve,

    I wonder if I run into the limits of image transformation with the application.

    Based on 2 sets of 4 Ctrl points I establish a projective image transformation. (‘cp2tform’)
    I transform the image using ‘imtransform’. After some processing of the transformed image, I obtain new ctrl points for further processing. Using the inverse transformation I locate these new ctrl points on the original image (‘tforminv’). I control in and output space using the [xdata,ydata] output from ‘imtransform’.

    It all works fine, unless the projective transform reaches a relatively steep perspective angle (~60degrees). Transforming the image works fine but the inverse transformation of the ctrl points has an unexplained offset.

    The transformed ctrl points appear in the original image but with a slight error on perspective and location. It looks like the function lost some accuracy. Again the whole process works fine on images with less perspective.

    Have you encountered this phenomenon? Any idea what is causing it and better what can be done.

    Thanks! Great Blog!

  8. Henry replied on :

    Hi Steve,

    I am resizing an image with following two methods:
    1) makeform + imtransform
    2) imresize

    I = imread('pout.tif');
    size(I)
    sx = 5;
    sy = 7;
    % using makeform + imtransform
    T = [sx 0 0; 0 sy 0; 0 0 1];
    tform = maketform('affine', T);
    I2 = imtransform(I, tform);
    % using imresize
    I3 = imresize(I, 'scale', [sx sy]);
    size(I2)
    size(I3)
    

    When sx or sy is large (says > 2), the first method does not seem to return the correct dimension as 2nd method. Is this a limitation in imtransform? I need the first method for transformation beyond just scale. Appreciated that if you can help to clarify on the matter. Thank you.

    Regards,
    Henry.

  9. Steve replied on :

    Henry—imtransform automatically adjusts the output pixel grid spacing when the scale factor increases beyond a certain amount. To prevent this from happening, use the 'XYScale' optional input parameter (set it to 1).

  10. Henry replied on :

    Dear Steve,

    Many thanks for your clarification. It works perfectly fine now.

    Regards,
    Henry.

  11. ashwani replied on :

    the above example is good for rotation along z axis using x,y axis. but if i have to rotate image along x axis by varying z axis what code to be used

  12. Steve Eddins replied on :

    Ashwani—See this Wikipedia page for some information that might be useful.


MathWorks
Steve Eddins is a software development manager in the MATLAB and image processing areas at MathWorks. Steve coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

These postings are the author's and don't necessarily represent the opinions of The MathWorks.