Steve on Image Processing

February 14th, 2006

Spatial transformations: maketform, tformfwd, and tforminv

Several Image Processing Toolbox functions related to spatial transformations use "tform" structures. A tform structure has data and function handles needed for applying a spatial transformation in the forward or the inverse direction, and sometimes in both directions.

Contents

maketform

Function maketform has several syntaxes for constructing different types of tform structures. For example, you can construct an affine transform by providing an A matrix:

A = [2 0 0; 0 2 0; 0 0 1];  % Stretch by a factor of 2 in both directions.
tform = maketform('affine', A);

tformfwd

Toolbox function tformfwd transforms points from input space to output space. For example, to apply the affine transform above to the point (u,v) = (2,3), do this:

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

     4     6

tforminv

Function 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 =

     2     3

Introducing George

The spatial transformation functions imtransform, tformarray, tformfwd, tforminv, etc., were introduced to Image Processing Toolbox version 3 in 2001. While designing these functions, we almost always had input-space output-space diagrams on our whiteboards so we could keep our notation straight.

Because I have no drawing skills, I always drew a crude head-and-shoulders outline on these diagrams as the "image" being transformed. I started calling this figure "George." Here's what he looks like:

% http://blogs.mathworks.com/images/steve/37/george.mat
load george
plot(x,y), axis ij, axis equal, axis([-1 1 -1 1]), grid on

Why "George"? Well, any graduate of the Georgia Institute of Technology will recognize George's full name: George P. Burdell. If you don't know George and are curious, I'm sure Google will turn something up for you.

I like to use George to illustrate different affine transforms.

Scaling example

A1 = [2 0 0; 0 2 0; 0 0 1];
tform1 = maketform('affine', A1);
uv1 = tformfwd(tform1, [x y]);

subplot(1,2,1)
plot(x,y), axis ij, axis equal, axis([-2 2 -2 2]), grid on, title('George')

subplot(1,2,2)
plot(uv1(:,1), uv1(:,2)), axis ij, axis equal, axis([-2 2 -2 2])
grid on
title('Scaled by 2')

Rotation example

theta = pi/4;
A2 = [cos(theta) sin(theta) 0; -sin(theta) cos(theta) 0; 0 0 1];
tform2 = maketform('affine', A2);
uv2 = tformfwd(tform2, [x y]);

subplot(1,2,1)
plot(x,y), axis ij, axis equal, axis([-2 2 -2 2]), grid on, title('George')

subplot(1,2,2)
plot(uv2(:,1), uv2(:,2)), axis ij, axis equal, axis([-2 2 -2 2])
grid on
title('Rotated by 45\circ')

Translation example

A3 = [1 0 0; 0 1 0; 1 -1 1];
tform3 = maketform('affine', A3);
uv3 = tformfwd(tform3, [x y]);

subplot(1,2,1)
plot(x,y), axis ij, axis equal, axis([-2 2 -2 2]), grid on, title('George')

subplot(1,2,2)
plot(uv3(:,1), uv3(:,2)), axis ij, axis equal, axis([-2 2 -2 2])
grid on
title('Translated')


Get the MATLAB code

Published with MATLAB® 7.1

96 Responses to “Spatial transformations: maketform, tformfwd, and tforminv”

  1. Athaur replied on :

    Greetings

    I tried your code
    load george
    plot(x,y), axis ij, axis equal, axis([-1 1 -1 1]), grid on

    and error in using plot
    ??? Error using ==> plot
    Too many input arguments.
    What could cause it

    thanks

  2. Steve replied on :

    Athaur - I’d guess that there’s a problem in the way you typed the code into the command window. Perhaps you left a space between “plot” and “(x,y)”? Try putting the plot, axis, and grid calls on separate lines.

  3. K replied on :

    hi,

    i would like to do some image transformations (namely - translation,
    scaling and rotation). I have an input image that is always larger than
    the output that i want to produce (e.g. input[384,256],
    output[150,130]).

    i combined my translation, scaling and rotation values in a 3×3 matrix
    but i don’t know how to apply it now to the image. i found in help that
    i should use maketform function but I want to do all three
    transformation at once and i want the output image to be exactly the
    size specified.

    how do i do this?

    you can e-mail me as well if you like.

    thanks,
    K.

  4. Steve replied on :

    K - Use imtransform to perform the spatial transformation on your image. Look at the imtransform doc for details on the XData, YData, and Size parameters. These will give you all the control you need to get your output image in the right place, with the right size.

  5. sherwin replied on :

    im using maketform to perform shearing , but while taking the inverse to get back the original image image the size of image is more. what should i do so that that shearing can be reverseable ?? Plz help

  6. Steve replied on :

    Sherwin - send me code that illustrates the problem you are having.

  7. Mark replied on :

    the example of the translation only works if the image is a vector of points (like george).
    When one replaces george by the cameraman.tif image the translation does not work.
    What is am easy way to translate images?
    M.

  8. Steve replied on :

    Mark - yes, tformfwd and tforminv are for transforming points. Use imtransform to transform images.

  9. Damodar Magdum replied on :

    Dear Sir,

    The example u have given is very useful and informative.I am trying to run handwritten text but it shows error with message “Cell contents reference from a non-cell array object”.
    What is the solution for that?

    Thanking you

  10. Steve replied on :

    Damodar - I do not understand what you mean by “I am trying to run handwritten text.”

  11. Giancarlo replied on :

    Hi Steve,

    I have typed your code:

    load george
    plot(x,y), axis ij, axis equal, axis([-1 1 -1 1]), grid on

    and I have obtained this answer:

    ??? Error using ==> load
    Unable to read MAT file george.mat

    File may be corrupt.

    How is it possible?
    (I have downloaded george.mat from your site a lot of time!)

    thanks

    Giancarlo

  12. Steve replied on :

    Giancarlo - please try it again. I resaved the MAT-file using v6 format. Also note that the URL has changed.

  13. david replied on :

    hi steve
    i am trying to do some transformation(rotation tranlation scale) from 2×2 matrix(image) to 3×3 matrix (basically a plane). the idea is located a pixel from image in another coordinate system(x,y,z), from 2d to 3d
    how can i do it?
    thanks

  14. Steve replied on :

    David - use tformarray. It can transform multidimensional arrays along arbitrarily chosen dimensions. The number of input dimensions need not match the number of output dimensions. You’ll need to define a custom transformation using maketform.

  15. helga replied on :

    I wanted to transform one triangle to another using these functions , the code you wrote works for the vertices of the triangle , but do you have any idea about all of the inner points of the source triangle?suppos the source triangle is a part of an image and the goal is to map it to the new frameworkk which is also a triangle.
    thanks

  16. Steve replied on :

    Helga - Use imtransform to transform an image. See my collection of useful documentation links.

  17. Pranjal replied on :

    Sir,

    I’m trying to transform an image using the following affine transform equation:
    u = a0 + a1*x + a2*y;
    v = a3 + a4*x + a5*y;

    I define my matrix A = [a0 a1 a2; a3 a4 a5; 0 0 1];
    I perform the transformation on each output image pixel using the above equations and place the input pixel values at these newly obtained locations. My range for a0 and a3 is uniformly distributed between [-2.0 2.0] and the others between [-0.04 0.04].

    However my affine transformation seems to have jagged edges and I’m unable to remove these. Could you please help me on this.

    Sincerely,
    Pranjal

  18. Steve replied on :

    Pranjal - From your description, it sounds like you are doing your own image transformation, and that you are using something like nearest-neighbor interpolation. Try using imtransform instead, and select bilinear or bicubic interpolation.

  19. Pranjal replied on :

    Sir,

    Thankyou very much. I have tried imtransform and it works fine.

    Sincerely,
    Pranjal

  20. maha replied on :

    Hi
    and I’m student in computer since
    I have problem with my project….and I think you able to help me to reach the solution
    My problem is how to discover the features of the hand image in multi-scale space
    After detection and remove the blood and ridge from the image by using log filter
    I hope to be interested

  21. kamal replied on :

    hi
    I am a student in embedded systems.
    I have problem in my project. I think you can suggest me so that i can proceed to other stages of the project.

    Problem: I have to register two images, the main aim is to register the object in my image with the object in the other image.For example say image1 and image2 show palm (one of the objects in the image) in the image.Now I like to register only the object, palm. so is it possible to register the images pixel by pixel( i.e. to register the objects pixel by pixel so that it results in shearing, translation and rotation directly on the object ) if this is possible how can this be done.

  22. Steve replied on :

    Kamal - If you have pairs of corresponding points in the two images, then you can compute a spatial registration tranform using the Image Processing Toolbox function cp2tform. You are probably looking for a method that is more automatic. There are several automatic image registration contributions on the MATLAB Central File Exchange; you could give them a try.

  23. shalini replied on :

    hi steve…

    I tried your code
    load george
    plot(x,y), axis ij, axis equal, axis([-1 1 -1 1]), grid on

    and the error was

    Error using ==> load
    Unable to read file george: No such file or directory.

    Error in ==> imtransform at 44
    load george

    Is there any way to load our biomedical image for further transformations

  24. Steve replied on :

    Shalini - You have to download the file george.mat. The URL is given in this post. You can read image files using imread.

  25. Dave replied on :

    Hi, I’ve been looking to apply a transform between two images using correlated point pairs. I’ve noticed that the function cp2tform does this, but that maketform can also be used for this function when supplied with a set of input points and output points: maketform(’transformation’, U, X). What is the difference between these two functions when maketform is used in this way.

    Thanks,

    Dave

  26. Steve replied on :

    Dave - There’s no difference if you supply the minimum number of points needed to infer the transformation function. cp2tform is used when you have a lot of points, thus overspecifying the transformation. It computes a least-squares solution.

  27. Yuan-Liang Tang replied on :

    Hi Steve,
    While trying to understand how to perform affine transformation on an image using MATLAB, I came into the following problem: image A looks OK for the first coordinate
    translation (A starts at [-50 -100]). The second translation is actually an inverse process. However, image B does not start at [0.5 0.5]; it starts at [50 100], instead. Why is that? I’ve post this question in MATLAB Central, but there was no response. Thanks in advance.

    ———————————-

    im = double(imread(’lena.tif’));
    T = [1 0 0; 0 1 0; -50 -100 1] % Coordinate translation
    tform = maketform(’affine’, T);
    [A xdata ydata] = imtransform(im, tform, ‘bilinear’);
    figure, imshow(xdata, ydata, uint8(A)), title(’A');
    pixval on, axis on, axis([xdata(1) xdata(2) ydata(1) ydata(2)]);

    T = [ 1 0 0; 0 1 0; 50 100 1] % Inverse translation
    tform = maketform(’affine’, T);
    [B xdata ydata] = imtransform(A, tform, ‘bilinear’);
    figure, imshow(xdata, ydata, uint8(B)), title(’B');
    pixval on, axis on, axis([xdata(1) xdata(2) ydata(1) ydata(2)]);

    ——————————

  28. Steve replied on :

    Yuan-Liang - In your second call to imtransform, it looks like you haven’t passed in information about the coordinate system for the image A. Therefore, imtransform assumes A is in the “default” location, with its upper left pixel centered at (1,1).

    Look at the UData and VData input parameters to imtransform.

  29. HomamAlsun replied on :

    I do rotation on medical image(irm),and i want to rerotate this image rotated in the same angle,without any changes in the dimensions,but i can not do this.

  30. Steve replied on :

    Homam - What have you tried and why didn’t it work for you?

  31. gehad replied on :

    i really need this information as it is very important for me in my study

  32. Steve replied on :

    Gehad—What information?

  33. samin replied on :

    Hi,
    I am trying to write a code for translation and rotation of image. I tried following code for rotating my image but it doesn’t give me the translated image even though it shows the right xdata and ydata. I am not sure why it is happening. thanks.

    I=imread(’IMoriginal.jpg’);
    imagesc(I); colormap gray;

    A = [1 0 0; 0 1 0; 50 50 1];
    T = maketform(’affine’, A);
    [B,xdata,ydata]=imtransform(I, T)
    figure; imagesc(B)

  34. Michael V replied on :

    I am writing a code for automatic image registration of multi frame tiff images. I created a code for manual selection of control points. My images have 5 black registration points, I can find the centroids of them but what I need is to set a limit on the pixel count. For instance I use bwlabel and I get 55-112 points depending on the intensity range I use some of the labels are on 3-5 pixel points, the registration dots are much larger. Can I set a minimum required pixel count for bwlabel??? Please Help!!! thanks

    mike

  35. Steve replied on :

    Michael—Use the function bwareaopen.

  36. Michael V replied on :

    thanks I found it just after I posted the comment. You are very helpful. i used Identifying Round Objects post. how can I output only the round object centroid coordinates.

  37. Michael V replied on :

    Nevermind I got it. thanks

  38. Steve replied on :

    Samin—See my July 7, 2006 post on translation confusion.

  39. Anand replied on :

    Hi Steve,

    I am having some problems using imtransform and tformfwd.
    I have to extract a section of an image(a square region) after rotating the image(aligning its axis with the horizontal and vertical axis). When I use imtransform, the size changes and therefore I am unable to find the coordinates of a particular reference point after transformation. Plz help

  40. Steve replied on :

    Anand—Please review my various “spatial transformations” posts between January and August of 2006. (See the blog archives.) The posts cover various coordinate system issues. Or look at the documentation for imtransform, especially the information about the optional output arguments XData and YData. These arguments define the coordinate system for the output image.

  41. liya replied on :

    I am trying to register two or more images which are sub pixel shifted, rotated, using affine transform on a common grid,but I am not able to get it is there any other method so that I can transfer all these pixels from multiple low resolution images to a single grid

  42. Mara Yale replied on :

    Liya - Here’s a reference for an algorithm to do what you want using phase correlation.

    B.S. Reddy, B.N. Chatterji, An FFT-based technique for translation, rotation and scale-invariant image registration, IEEE Transactions on Image Processing 5 (1996) 1266–1271.

  43. Robin replied on :

    Hi Steve,
    I am working on registering of a t2 wieghted mri image onto a histology image of the spinal cord.The dimensions of the histology image(which i am using as the base image for imaage registration) is , while the unregistered image is a part of the mri image which i have extracted using bwboundaries and cropim. The dimensions of the unregistered image is and is not fixed as we use cropim.Now whenever i try to register the image using the inbuilt registration tool cpselect and imtransform i do not get the desired effect.I am using a affine transformation. Plz could you guide me in the right direction ?

  44. Robin replied on :

    The dimensions of the base image is 318×442 double and that of the unregistered image is 36×38 double.

  45. Steve replied on :

    Robin—Since you didn’t say exactly what you tried to do, or what undesired effect you received, I can’t guess what might be wrong. You might want to take a look at the three “Image Registration” demos in the Image Processing Toolbox. You can find them here.

  46. ivan replied on :

    I have been working on a coordinate transformation, i was wondering if u might have complete blocks for simulink for the transformations.

  47. Steve replied on :

    Ivan—See the Video and Image Processing Blockset.

  48. Mari replied on :

    Dear Steve,
    I have a video sequence of a man walking. I know how to extract the contour of this man from every frame. Now I should save these boundaries in a similar format (imagine that I want to center the shapes and pile up them). Any idea?
    My problem can also be seen in this way: you have “George” and “translatedGeorge” and you want to check if they correspond to the same person, so you have to find a transformation T (if it exists) that gives George=T*translatedGeorge
    Can you suggest me any approach?
    Thanks for your helpfulness.

  49. Steve replied on :

    Mari—No, I don’t any suggestions for you.

  50. Ram replied on :

    Hi,I have a small doubt.I have got a binary image.I have to distort the image using the distortion function x’=0.5*x+x*x/255 and y’=0.5*y+y*y/255;and image size is 255 by 255.how to do the distortion using above function? i mean how to display image using the distorted coordinates? Somehow if i can have a function to display with the given coordinates then can we do it?and wt is that function?Thanks

  51. Ram replied on :

    continued for the above…where x,y are the original coordinates and x’,y’ are the transformed coordinates

  52. Steve replied on :

    Ram—See my blog entry for today (March 31, 2008).

  53. Jon Hauris replied on :

    Steve, Can you please provide some tutorial on how stereo maps are constructed. For example, the Mars Rovers and USC’s “Stanely” (that won the first DARPA Grand Challenge) both constructed stereo maps used to guide the vehicles. I would like to learn the algorithms, how the maps are constructed, and how they are used. Thanks, Jon

  54. Steve replied on :

    Jon—I’m sorry, but I’m not familiar with stereo map algorithms.

  55. Ram replied on :

    Thank you steve,but i have doubt that- maketform(’affine’,[.5 0 0; .5 1.5 0; 100 200 1]); how do u define this matrix[.5 0 0; .5 1.5 0; 100 200 1]? is it standard matrix or randomly chosen or how it relates to the distortion function that i have? sorry if it too silly question..many thanks..

  56. Ram replied on :

    if i have transform like x->a*x+x*x then how do we define the matrix?

  57. Steve replied on :

    Ram—The documentation for maketform includes the affine transform equation that relates input-space and output-space coordinates. As for what the terms mean, there is a tremendous amount of information available online about affine transforms. For a discussion that’s specific to both MATLAB and image processing, see section 5.11 of Digital Image Processing Using MATLAB.

  58. sri replied on :

    Hi Steve,
    I need to change x,y co ordinates of a given image to x’,y’ according to a distortion function given by
    x’=a*x+((1+a)x*x)/L and y’=a*y+((1+a)y*y)/L where a is any scalar between 0 and 1 and L=256. Can you please help me out. Thanks.

  59. Sladjan replied on :

    Hi Steve,

    Is it possible to make rotation and translation together?
    This should to save calculation time in my opinion.
    I tried like this:

    XForm = [cos(Phi) -sin(Phi); sin(Phi) cos(Phi); TX TY];
    tform = maketform(’affine’, XForm);
    TX and TY - translation vectors
    Phi - rotation angle

    but now i don’t know what is the first operation in the maketform function, rotation and than translation or translation and than rotation?

    Thanks Sladjan

  60. Steve replied on :

    Sri—See my post about defining custom transformations.

  61. Steve replied on :

    Sladjan—The equation showing how the affine transform matrix is used is in the reference page for maketform. You can take a look how your matrix gets applied with that equation to see the order of things. In general, rotation and translation are both affine transforms, and the composition of two affine transforms is also affine. You form the composition by multiplying the two affine matrices together.

  62. Steve replied on :

    Ram—x->a*x+x*x is not an affine transformation. You’ll have to do it using a custom transformation.

  63. krishnamoorthy replied on :

    Hi Steve,
    I want to transform a image one position into correct rectangular position.AT what algorithm use it pls reply to me

  64. Steve replied on :

    Krishnamoorthy—Your question is pretty vague. You might find the imtransform, maketform, and cp2tform functions to be helpful. Also, look at the image registration demos on the Image Processing Toolbox demos page.

  65. Andrea replied on :

    Hi,
    I have an image,named ‘I’, that I’d like transform from pixel coordiantes to UTM coordianates. For do this, I know some points of image called GPC(ground control points). For example the pixel (x=50,y=50) correspond with UTM coordinates 4900000 370000.
    First of all, I use cp2tform in this way:
    geo_aug07 = cp2tform(XY,xy,’projective’);
    where XY is pixel matrix end xy is UTM matrix. XY=[ 50 50, … …,… …] xy=[4900000 370000,… ….,…. ….] geo_aug07 is a structure.
    Then, I use imtransform in this way:
    [I_proj3,XX,YY] = imtransform(I,geo_aug07);
    where I is input image, I_proj3 is output image. using imshow (XX,YY,I_proj3) I have an output image according to projective transformation. In this image I can see each pixel with the respective coordinate UTM.
    The geometry end the size are different between I end I_proj3. size(I_proj3)>size(I).
    Now my problem is to obtain from output image an image like the input image(with the same size) where each pixel is matched with UTM coordinate obtained form output image. For do this I think to use an inverse function of imtransform, but I don’t know how works.
    Does exist an inverse Matlab function of imtransform?
    Thanks

  66. Steve replied on :

    Andrea—Assuming your spatial transformation has an inverse, you would form a tform struct with the inverse transformation and then use imtransform to apply it.

  67. Andrea replied on :

    I formed an inverse tform struct with fliptform and then I apply imtransform. The result is not correct. why? is it possibile that does not exist an inverse trasformation of imtransform?

  68. Steve replied on :

    Andrea—What’s not correct about it?

  69. Leonardo replied on :

    Hi Steve,

    When doing an image transformation with some predefined coefficients, I end up with some of the output pixel coordinates going in to the negative field. I am using a relation like this to map the pixels: I2(x,y,:)=I1(u,v,:)and I get the error for negative indexes.
    1-How can I deal with the negative indexes?
    2-What do you think is the best way to interpolate the pixels?

    Best,
    Leonardo

  70. Steve replied on :

    Leonardo—I think the best way to handle questions 1 and 2 is to use imtransform. But if you want to implement the spatial image transform yourself, you have a variety of choices. There is no “best” answer to either question. For input-space coordinates outside the defined image boundary, for example, you could assume the image pixels are zero, or you could use the nearest image pixel on the boundary. For interpolation, you have many choices. Bilinear interpolation is probably most common, although bicubic interpolation is now the default in many applications, including the Image Processing Toolbox. And there are circumstances in which nearest neighbor would be best.

  71. Omar replied on :

    Hi Steve,
    when using tformfwd to find corresponding points in the new space, the resulting co-ordinates from tformfwd do not match the transformed image display (using for instance datacursor to select a couple of points). As an example, I’m working on the following piece of code:

    tTransf = eye(3);
    NormMat = [0.6851 -0.3149; -0.3149 0.6851];
    tTransf(1:2,1:2)= NormMat;
    tform=maketform(’affine’,tTransf);
    new_im = imtransform(im,tform);

    The problems occur when I call:
    new_pt = tformfwd(tform, pt);

    The co-ordinates given by new_pt do not match the diplayed point!!!I should add that in my work, I have not control over NormMat, it is computed iteratively. But I have noted that tformfwd work fine when the values in NormMat are all positive.
    Any suggestion please ?

  72. Steve replied on :

    Omar—You didn’t say how you are displaying the image, so I can only guess at the problem. The function imtransform will by default compute the result only within the bounding box of the transformed image. This has the implicit effect of removing translations. Try getting the using the xdata, ydata as additional output arguments from imtransform and then passing them to imshow. For more info, see my posts on translation confusion and on controlling the input- and output-space grids.

  73. Ash replied on :

    Hi Steve,

    I have an image which i have captured at an angle. Basically a perspective distorted image.

    How can i use maketform to bring it back to a rectangular shape.

    I tried imtransform with some parameters and managed to get it to turn a little. But i get the same result when i use imresize to some specific size.

    Kindly help
    Thanks
    Ash

  74. Steve replied on :

    Ash—Try using cp2tform and cpselect.

  75. Ash replied on :

    Hi Steve,

    Tried using cp2tform and cpselect. But i dont have a base image. I need to just remove the projective distortion. I’ll try again.
    Thanks
    Ash

  76. omar replied on :

    Hi Steve,
    Many thanks for your reply.
    It is not the display that I’m after. I just used it to check my results.
    What I’m trying to do, is to track a point, say Pt, in the original image, which is transformed into NPt in the transformed space. Using the function tformfwd(tform, Pt) alone has given me some correct results and in cases, completely wrong results. So I’ve written this little piece of code (as an example):

    im = imread(’pout.tif’);
    mat = [-0.4218 0.7922; 0.9157 0.7922];
    tTransf = eye(3);
    tTransf(1:2,1:2) = mat;
    tform=maketform(’affine’,tTransf);
    [new_im xdata ydata] = imtransform(im,tform);
    figure(1); imshow(im);
    figure(2); imshow(new_im);
    Pt = [116 93];
    NPt = tformfwd(tform, Pt);
    NPt = NPt + [1 1] - [xdata(1) ydata(1)];

    Pt here is the left eye of the kid. That code seems to be working fine when the elements of mat are smaller than one.

    As an example where I’ve got wrong results, I simply change mat to mat = [3 -1; 2 -2] and run the code again. That code no longer produces correct results.

    What do you reckon?

    Regards
    Omar

  77. Steve replied on :

    Omar—I don’t see anything wrong. I tried the following code:

    mat = [3 -1; 2 -2];
    tTransf = eye(3);
    tTransf(1:2,1:2) = mat;
    tform = maketform('affine', tTransf);
    im = imread('pout.tif');
    [new_im xdata ydata] = imtransform(im, tform);
    Pt = [116 93];
    NPt = tformfwd(tform, Pt);
    imshow(new_im, 'XData', xdata, 'YData', ydata);
    hold on
    axis on
    plot(NPt(1), NPt(2), 'y*')
    

    And here’s the result:

    Looks like the point is being plotted in the correct location.

  78. omar replied on :

    Hi Steve,
    The display is correct as you have demonstrated.
    But I want to access the pixel new_im(NPt) (precisely, new_im (NPt(2), NPt(1) ), for some processing operations in its neighbourhood, also in the context of my work the location of NPt has to be as precise as possible, otherwise my algorithm wouldn’t converge.

    In the example above, NPt = tformfwd(tform, Pt) returns (534 -302) which is out of the range of new_im. To solve the problem, in my first example I used the formula NPt = NPt + [1 1] - [xdata(1) ydata(1)]; as follows:

    [new_im xdata ydata] = imtransform(im,tform);
    Pt = [116 93];
    NPt = tformfwd(tform, Pt);
    NPt = NPt + [1 1] - [xdata(1) ydata(1)];

    which is working fine and removes the translation effect. However, for mat = [3 -1; 2 -2] that trick does not work. I’ve also noticed that in the second example when mat = [3 -1; 2 -2], xdata is equal to [50 1302.5] and ydata is equal to [-822 -3], leading to an imgae of size 820 x 1254, where the transformed new_im is of size 583×923.

    I wonder if there is a scaling factor (in addition to translation) I have to take care of ?

    Having said that, my question is about how to access new_im at NPt, when the computed NPt is out of range.
    Regards
    Omar

  79. Steve replied on :

    Omar—The computed NPt is not out of range. It is exactly where your own defined transformation took it. To determine how to convert NPt into image pixel coordinates, you need to use both [xdata(1) ydata(1)] and [xdata(2) ydata(2)], because there is potentially a scale factor applied by imtransform in order to keep the output image size from growing too much. You can control this directly by using the XYScale parameter when you call imtransform.

  80. Amalia replied on :

    Hello,

    I have a random displacement field with vectors corresponding to each pixel in an image and I want to ask if it’s possible to apply that field directly to an image using imtransform? I understand that I might have to create a tform using ‘custom’ option. Do you know if such a thing is possible?
    Thank you,
    A

  81. Steve replied on :

    Amalia—Yes, that is possible and can be fun. See my post about defining and applying custom transformations.

  82. Malik replied on :

    Steve,
    Function findbounds returns slightly different results form those of XDATA and YDATA in imtransform. The relative difference is up to %0.25.

  83. Steve replied on :

    Malik—Once the bounds are determined in output space, you have to establish a grid of output-space pixel locations at which to compute output image pixels. Since the grid is regularly spaced, the border pixels might not line up exactly with the output of findbounds. That means that XData and YData have to be adjusted to match the output pixel grid. See the subfunction recompute_output_bounds inside imtransform, as well as the code that calls it.

  84. Tomy replied on :

    Steve,
    I need to use a image transform in which the output would be a bigger resized image not only by expanding pixels forward out the original one but also expanding them in the inner direction in case of holes. Being more understandable, the code would generate a ring with greater perimeter and smaller hole than a ring used as an input image.

  85. Steve replied on :

    Tomy—What is the question?

  86. Tomy replied on :

    Sorry, I’ve submitted the comment before finish it.

    The transformation would be similar to the output given by the imopen function but, for the application I am developing I need to keep as much as pixel resolution as possible. I’ve tried with different functions but noone match the results I’m looking for. could you give me any suggestion about the topic?

    Thanks in advance.

  87. Steve replied on :

    Tomy—I don’t see any connection between your image transform description and imopen. Regarding the pixel resolution, you might want to look at my post about controlling the input and output grids with imtransform.

  88. Tomy replied on :

    Steve,
    Probably I was not clear enought in the explanation of my question, so let me show you in a simple way the transformation I am looking for:

    Suposse I have a squared ring as shown next,

    %    ________17_______
    %   |      _____      |
    %   |     |     |     |5
    %   |     |     |3    |
    %   |     |__5__|     |  2*(5+17) units of outer perimeter
    %   |_________________|  2*(3+5) units of inner perimeter
    

    The function I am trying to design should out a result similar to the next figure,

    %   _________20_________
    %  |                    |
    %  |        ____        |6
    %  |       |    |2      |
    %  |       |_4__|       |
    %  |                    |  2*(6+20) units of outer perimeter
    %  |____________________|  2*(2+4) units of inner perimeter
    

    The main problem I have is that I don’t know how to remap the image in order to obtain those results.
    I though in determining the euclidean distance from the image pixels to the background and try to expand the evaluated pixels towards the direcction where such distance is minimum but I dont know how to expand/contract the pixels according with the object boundary location in a coherent way.
    Maybe there is no relation with the imopen funtcion I mentioned in the last question but I’ve shown by using the imdilate the results are quite similar as I need, however, the output image is blurred.

    Thanks

  89. Tomy replied on :

    I’m really sorry but the squared rings have not been shown as I wanted.
    The first ring had a 44u of outer perimeter and 16u of inner perimeter,the second one is 52u of outer perimeter and 12u of inner. This is just an example for explaining what the function should do.

  90. Steve replied on :

    Tomy—I can’t help you with your remapping function definition, but once you get that worked out, take a look at my post on custom spatial transformations.

  91. Xiaohong Zhang replied on :

    Dear Steve:

    I had wrote the following codes:
    {
    xscale = 5;
    yscale = 5;

    rotation = 30;
    oldimg = imread(’house.bmp’);

    theta = rotation*pi/180;
    As = [xscale 0; 0 yscale];
    Ath = [cos(theta) -sin(theta);sin(theta) cos(theta)];
    A = Ath*As;

    T = eye(3,3);
    T(1:2,1:2)=A;
    tform=maketform(’affine’,T);
    newimg = imtransform(oldimg,tform);
    size(newimg)
    figure,imshow(newimg);
    }

    My problem is as follows:

    As xscale>=2 and yscale>=2, the size of the transfomed image is not the one I expected. In the above example, the size of the origin image is 256X256, however, the new image size is 513X513.

  92. Steve replied on :

    imtransform has logic in it that automatic adjusts the size (in X-Y space) of the output pixels in order to keep the dimensions of the output image from growing too large.

    To prevent this automatic (and unexpected) adjustment of the output pixel size, specify the ‘XYScale’ parameter to be 1, like this:

    newimg = imtransform(oldimg, tform, 'XYScale', 1);
    
  93. qureshi replied on :

    when i follow ur code for rotation i got errors in matlab mentioned at the end ?

    My code is

    for th=-90:90;
    x(th+181)=cos((th*pi)/180)*(8-(0.33*((th*pi)/180))*((th*pi)/180));
    y(th+181)=sin((th*pi)/180)*(8-(0.33*((th*pi)/180))*((th*pi)/180));
    end
     plot(x,y), axis ij, axis equal, axis([-15 15 -15 15]), grid on
     theta = pi/4;
    A2 = [cos(theta) sin(theta) 0; -sin(theta) cos(theta) 0; 0 0 1];
    tform2 = maketform('affine', A2);
    
     uv = tformfwd(tform2, [x y]) %% after the execution of    %%this  line  
    
    and the error appears to be in MATLAB are
    
    ??? Error using ==> tform>checkCoordinates at 141
    Function TFORMFWD: SIZE(U) is inconsistent with T.ndims_in.
    
    Error in ==> tform at 42
        [U, D] = checkCoordinates( f, P, A{1} );
    
    Error in ==> tformfwd at 68
    varargout = tform('fwd', nargout, varargin{:});
    

    Any suggestions ?

  94. Steve replied on :

    Qureshi—You are calling tformfwd incorrectly. It is expecting its second input to have two columns, but you are passing it [x y], which is a 542-element row vector. You’ve got a bug in your indexing offset (181 is wrong), and you are computing x and y as row vectors instead of column vectors. And there’s no need for that for-loop. Consider doing something like this:

    th = (-90:90)';
    th_r = th*pi/180;
    x = cos(th_r)*(8-0.33*th_r.^2);
    y = sin(th_r)*(8-0.33*th_r.^2);
    
  95. qur replied on :

    Hi steve

    Is it to possible to shift the subpixels in an image ? if possible how ?. Does matlab provide any algorithm for subpixels shifting?

    Regards

  96. Steve replied on :

    Qur—Do you mean subpixel translation? Then yes, you can do that with imtransform and an affine transformation. Be sure to look at this post before you try it, though.

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Steve Eddins manages the Image & Geospatial development team at The MathWorks and coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

  • Sana: hi steve, could you explain to me how i would be able to use the dir function, to do a loop through a directory...
  • Nishtha: Sir, I have preprocessed the image in following steps: [1] adaptive histogram equalization [2] thresholding...
  • Kristof: I also strongly support the idea. I have just recently bumped into the problem that im2single was not...
  • Steve: David—I’ m glad you found it useful!
  • David Lalejini: I found your example very useful for finding connected nodes in a large set of input pairs. I start...
  • tommy: Dear Steve, I have a question,please if you are kind to help me regarding the accumulator array dimensions of...
  • Steve: Abc—I don’t know how to distinguish the faces. You might try posting your question in the MATLAB...
  • Manju: well if we have a few ovals within each other like in a cell how do we measure the distance from the center...
  • Steve: Manju—What do you mean? How is each region defined?
  • Manju: if we have 2-3 regions within each other how do we measure the regions of each one?

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