Steve on Image Processing

February 28th, 2006

Spatial transformations: Where is the input image?

We've talked about using Image Processing Toolbox functions to define an affine transformation and apply it to points. Let's begin to explore transforming images.

First we have to answer a question that is often overlooked: Where is the input image? In other words, the input u-v space is a plane. Where does the image lie on the plane?

Contents

Image location in the plane

With the default spatial coordinates for images in MATLAB, the center of the upper-left image pixel is at (1, 1). Each pixel is a square with unit area, so the corner of the upper-left image pixel is at (0.5, 0.5). A 4-by-4 image looks like this on the plane:

pixel_centers_x = [1 4 4 1 1];
pixel_centers_y = [1 1 4 4 1];
pixel_edges_x   = [0.5 4.5 4.5 0.5 0.5];
pixel_edges_y   = [0.5 0.5 4.5 4.5 0.5];

plot(pixel_centers_x, pixel_centers_y);
hold on
plot(pixel_edges_x, pixel_edges_y, ':')

% Plot axes lines
c = [.7 .7 .7];
plot([-50 50], [0 0], 'color', c);
plot([0 0], [-50 50], 'color', c);

axis ij, axis equal
axis([-5 5 -5 5]);

legend({'Pixel centers', 'Pixel edges'})
title('Default image bounding rectangle location')
xlabel('u')
ylabel('v')
hold off

Rotation

A "pure" affine rotation rotates about the origin. This means it can move an image into a completely different quadrant from where it started.

theta = 3*pi/4;
A1 = [ cos(theta)  sin(theta)  0
      -sin(theta)  cos(theta)  0
       0           0           1];

tform1 = maketform('affine', A1);

[pixel_centers_x1, pixel_centers_y1] = tformfwd(tform1, ...
   pixel_centers_x, pixel_centers_y);
[pixel_edges_x1, pixel_edges_y1] = tformfwd(tform1, ...
   pixel_edges_x, pixel_edges_y);

plot(pixel_centers_x1, pixel_centers_y1);
hold on
plot(pixel_edges_x1, pixel_edges_y1, ':')

% Plot axes lines
c = [.7 .7 .7];
plot([-50 50], [0 0], 'color', c);
plot([0 0], [-50 50], 'color', c);

axis ij, axis equal
axis([-5 5 -5 5]);

legend({'Pixel centers', 'Pixel edges'})
title('Rotated image')
xlabel('x')
ylabel('y')
hold off

Scaling

A "pure" affine scaling also operates with respect to the origin. Since the image corner isn't exactly at the origin (by default), scaling with a scale factor greater than 1 not only increases the size of the pixels, but it also moves the corner of the image away from the origin.

A2 = [ 3  0  0
       0  3  0
       0  0  1];

tform2 = maketform('affine', A2);

[pixel_centers_x2, pixel_centers_y2] = tformfwd(tform2, ...
   pixel_centers_x, pixel_centers_y);
[pixel_edges_x2, pixel_edges_y2] = tformfwd(tform2, ...
   pixel_edges_x, pixel_edges_y);

plot(pixel_centers_x2, pixel_centers_y2);
hold on
plot(pixel_edges_x2, pixel_edges_y2, ':')

% Plot axes lines
c = [.7 .7 .7];
plot([-50 50], [0 0], 'color', c);
plot([0 0], [-50 50], 'color', c);

axis ij, axis equal
axis([-5 5 -5 5]);

legend({'Pixel centers', 'Pixel edges'})
title('Scaled image')
xlabel('x')
ylabel('y')
hold off

The center of the upper-left pixel is now at (3, 3), and the corner of the upper-left pixel is now at (1.5, 1.5).

When I discuss imtransform, I'll explain how it automatically takes care of these details so that most users don't have to worry about it. But if you want to understand how things work, or if imtransform's automatic procedure doesn't do exactly what you need, then you need to understand this information.


Get the MATLAB code

Published with MATLAB® 7.1

23 Responses to “Spatial transformations: Where is the input image?”

  1. Tadd replied on :

    Steve,
    Can you do this example with an actual image? I have been trying to manipulate an image to find its velocity and spin rate. I have found the forward velocity but spin rate is illusive. I want to rotate the image and do some comparisons, but I want to rotate about a point I choose. I tried imrotate, but there is no origin option. I tried your above method, but my image has pixel depth and my images are logicals, so they can’t be manipulated like vectors. Any suggestions are greatly appreciated.
    Thanks,
    Tadd

  2. Steve replied on :

    Tadd - see the doc for the IPT function imtransform. I’ll be talking more about imtransform in future posts.

  3. Kelly replied on :

    Hi Steve,

    Is it possible to place a 128×128 image at the center of a 512×512 space? My image has pixel depth. I wish to place the smaller image on the 512×512 space, with the rest of the space set to 0 on the gray scale (black). Do I use imagesc?

    Many thanks,
    Kelly

  4. Steve replied on :

    Kelly - Try this: B = zeros(512,512,class(A)); B(192:319, 192:319) = A;

  5. Alon replied on :

    Hi Steve,

    I’m writing a gui that loads and manipulates images. I have an axes which is part of the figure. I’m loading images using the imread command, and I allow zooming with ‘zoom on/off’. My problem is that if the image I load is smaller then the axes, and I try to zoom in, the image is translated out, and I’m left with a blank (or nearly so) axes. Is there a way to ‘protect’ my image, and make sure it is always centered?

    Thanks,
    Alon.

  6. Steve replied on :

    Alon - I cannot reproduce the problem you describe. I suggest that you contact MathWorks technical support.

  7. Steve Webster replied on :

    Hi Steve

    I’m writing a gui for a program that allows users to choose images by clicking on them. The problem I’m having is that the callback for the axes on which the image is displayed doesn’t recognise a mouse click. How do I correct this?

    Many thanks.
    Steve.

  8. Steve replied on :

    Steve - Try setting the ButtonDownFcn of the image object instead of the axes object.

  9. Steve Webster replied on :

    Hi Steve

    Thank you. I did try ButtonDownFcn, as follows:

    image(img, ‘ButtonDownFcn’, ‘myfcn’);

    Works fine, but I have sixteen images. This doesn’t work:

    image(img, ‘ButtonDownFcn’, ‘myfcn(”this image”)’);

    function myfcn(str)
    disp(str)

    Neither does passing a variable. Tried various other things, including getting the current object. No luck. Can’t find any documentation on this. (Maybe a good tutorial? I can’t be the only person who has got totally stuck with this.) Anyway, I’m lost.

    Thank you. Steve

  10. Steve replied on :

    Steve - Troubleshooting GUI code is a bit beyond this blog. I suggest that you contact support (http://www.mathworks.com/contact_TS.html). You could also post a note to the MATLAB newsgroup (http://www.mathworks.com/matlabcentral/newsreader.shtml) asking for tutorial material.

  11. Ramiro Massol replied on :

    Hi Steve
    I appreciate very much your effort in creating and updating this blog. The problem I have is the following: I’m trying to create a GUI to allow the user to segment images based on pixel intensity. Images are acquired with microscopes and typically they have noise and the objects to segment vary a lot in intensity. I tried smoothing out the background first, then substract it from the whole image. After that I appied a log filter to improve the quality of the image and to enhance the difference of intensities at the edges of the objects. After this, I tried the edge command to define the outline of the objects. The whole algorithm, however, is not perfect or close to it because the background substraction sometimes eliminates weak objects or weak parts of objects creating artifacts later on the edge detection. I then read a lot about other segmenting methods, and it seems that the seed region-growing algorithms could in principle provide a more general way to find objects. The complication is how to set up the constrains of the growing region. I would really appreciate feedback on this and about segmentation in general. Best, Ramiro

  12. Steve replied on :

    Ramiro - It’s difficult to offer specific advice without seeing sample images and code. Without knowing more about the problem, I wouldn’t necessarily jump straight to assuming you need to use region growing. There are different ways to do background estimation, and different noise-smoothing preprocessing techniques. I doubt that the edge command would be directly useful in a segmentation problem such as you describe. Have you tried marker-based watershed segmentation? The Image Processing Toolbox has a shipping demo that is an example of this technique. Also, Digital Image Processing Using MATLAB has more information on segmentation, including some stuff about region growing.

  13. Ramiro Massol replied on :

    hi Steve,
    Sorry for my late response. Tell me how to send images to you so you can see the difficulty I’m experiencing in segmeting them.
    I wrote the code I used for the watershed segmentation:
    clear all,warning off
    [NAMEOFIMAGES, ORIGDATADIR, FILTERINDEX] = uigetfile(’*.tif’,'Tif Format (*.tif)’, ‘Select Clustered Image File’,'MultiSelect’,'off’);
    cd(ORIGDATADIR)
    i1 = imread(NAMEOFIMAGES);
    bkg = imopen(i1,strel(’disk’,50,8));
    i2 = imsubtract(i1,bkg);
    minsignal=7;
    i2 =i2 - minsignal;
    D = bwdist(~i2);
    D = -D;
    D(~i2) = -Inf;
    L = watershed(D);
    [B,L] = bwboundaries(logical(L),’noholes’);
    B=B(2:length(B));
    figure,imshow(i1)
    hold on
    for k = 1:length(B)
    boundary = B{k};
    plot(boundary(:,2), boundary(:,1), ‘r’, ‘LineWidth’, 2)
    end
    hold off

  14. Steve replied on :

    Ramiro - e-mail works for sending me a sample image. If you send me one, please let me know whether or not I can show it publicly on this blog.

  15. Jonathan replied on :

    Hi Steve, I appreciate the availability of your blog. I am trying to develop an algorithm that measures the distance automatically between the max pixel value of grid points in my image. I have used pixval and imdistline which both work fine, but I have a tremendous amount of data so I would like to automate the process. Thanks for any help you can give.

  16. Steve replied on :

    Jonathan - can you give me a little more detail? In particular, what characterizes the points between which you want to measure the distance? Send me a sample image if you like.

  17. Jonathan replied on :

    Steve-I have gaussian fit the the points in the image I emailed to you. I am trying to measure the distance from peak to peak of each point. The points are arranged in a pseudo-lattice structure. Thanks.

  18. Jiang replied on :

    Hi,Steve
    I like your blog very much. Now I am trying to develop a matlab code to recognize the vortex breakdown positions in many images, but the result is not good. I just wonder, could you give me some indication on this problem? Thank you very mcuh!

  19. Steve replied on :

    Jiang - no, sorry.

  20. Shimron Avner replied on :

    I’m getting the following error while using the function linewrap.m
    I’m not familiar with cellfun and all, so I wondered if you may have a quick solution to this
    Thanks
    Avner

    ??? Too many inputs.

    Error in ==> linewrap at 60
    c = cellfun(get_contents, tokens, ‘UniformOutput’, false);

  21. Steve replied on :

    Shimron - I wrote imcredit.m and linewrap.m using the R14sp3 release of MATLAB, which shipped in September 2005. linewrap uses a syntax of cellfun that wasn’t in earlier MATLAB releases.

  22. Priya S replied on :

    Hi Steve,
    Could you please let me know how I can save my files in the analyze format ?Is there any code that saves medical images in the analyze format?
    Thanks.

  23. Steve replied on :

    Priya - we don’t have a function for writing to the analyze format, and we currently have no plans to create one.


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.

  • Steve: Kezia—Try imrotate.
  • kezia: steve, how to perform rotation of structuring element by 15 degrees. kindly answer my question. thank u kezia...
  • Steve: Tasha—I only accept comments that are relevant to the particular blog post or are questions or comments...
  • Tasha: Steve,I send you a comment here but still didn’t get any reply yet.I did not see my comment posted here...
  • Steve: Carsten—Thanks for your input.
  • Carsten: Another vote for either imtranslate.m, or at least a blurb in the imtransform help why pure translation...
  • Loren Shure: If you look towards the end of the fftfilt program, you will see that there’s a check to see if...
  • Steve: Sonja—My imwritesize submission on the MATLAB Central File Exchange might be helpful. It was posted...
  • Steve: Grant—Sorry, but it won’t be for R2010a. That development deadline has already passed.
  • Sonja: My publisher is wanting images for a new book to be 300 dpi. Only 5 of the 19 images are 300, the rest are...

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