[Insight-users] Bug in interaction between SetDirection and SetOrigin/SetSpacing methods in ITKImage?

Alex Taylor Alex.Taylor at mathworks.com
Thu Feb 21 12:44:28 EST 2013


Bradley,

Thanks for getting back to me so quickly. I appreciate it. The use case of a diagonal unit vector specification for SetDirection makes sense, I can see the wisdom in specifying the spacing in {AlongRows,AlongColumns} order instead of entangling it with X,Y.

I would still have favored a consistent ordering between SetSpacing and SetOrigin. I struggled to find the bug in my code when defining my world coordinate system, I tried putting both origin and spacing in {row,column}, then {x,y} order, but it didn't occur to me that one would be one way and the other would be the other way.  I feel like the documentation should explicitly mention the conventions expected by SetSpacing and SetOrigin, I had to turn to TransformPhysicalPointToContinuousIndex to figure out what was going on.

Thanks,

Alex.

From: Bradley Lowekamp <blowekamp at mail.nih.gov<mailto:blowekamp at mail.nih.gov>>
Date: Thursday, February 21, 2013 12:18 PM
To: Alex Taylor <Alex.Taylor at mathworks.com<mailto:Alex.Taylor at mathworks.com>>
Cc: "insight-users at itk.org<mailto:insight-users at itk.org>" <insight-users at itk.org<mailto:insight-users at itk.org>>
Subject: Re: [Insight-users] Bug in interaction between SetDirection and SetOrigin/SetSpacing methods in ITKImage?

Hello Alex,

I don't believe this is a bug.

Consider the alternative to the current behavior,  that is what you expected the behavior to be. Consider the 2D case where the direction is a 45 degree rotation. If the spacing was specified in world space, then the image grid would be stretched in the diagonal and the pixels would not be square. You may need to draw a picture to visualize this.

Brad

On Feb 21, 2013, at 11:57 AM, Alex Taylor <Alex.Taylor at mathworks.com<mailto:Alex.Taylor at mathworks.com>> wrote:

All,

I'm seeing something I wouldn't have expected after using the SetDirection method of the ITKImage object to switch the orientation of the X/Y axes. What I believe I'm seeing is that SetOrigin expects the origin to be specified in the Xworld,Yworld system established by SetDirection, while SetSpacing expects the spacing to be specified as {SpacingAlongRows,SpacingAlongColumns}. This feels like an inconsistent design. I'm curious whether this was an intention design decision or a bug that will be fixed in a future release. Here is an example set of reproduction steps.

In the reproduction steps below, I define a 3x3 Image in which X rows parallel to rows and Y runs parallel to columns. I want the origin to be at world X,Y location (1,4). I want an X spacing of 1 and Y spacing of 4. There is an ambiguity in the documentation and interface in ITK Image whether the numeric array inputs for Spacing and Origin are in Row,Column or X,Y order. Either would be fine, but I wouldn't have expected that one would be row,column and the other would be X,Y.

When I execute the code below, I see the following output:

Continuous index at world location (1,4):  [0, 0]
Continuous index at world location (2,4):  [0, 1]
Continuous index at world location (1,8):  [1, 0]
Continuous index at world location (2,8):  [1, 1]

I take this as a verification that I have defined my intended coordinate system, but that it was necessary to use SetSpacing in a way I wouldn't have expected.

Is this a bug I should report or is this the intended design?

Thanks,

Alex Taylor


#include "mex.h"
#include "matrix.h"
#include "itkImage.h"

/* Define a 3 row, 3 column image. Set Y direction to parallel to rows, and X direction to be parallel to columns. Define center of first pixel (origin) to be at world X,Y location (1,4). Define X spacing to be 1
   and Y spacing to be 4. */

    typedef itk::Image<double,2> imageType;
    imageType::Pointer image = imageType::New();

    imageType::IndexType start;
    imageType::SizeType  size;
    for (mwSize i = 0; i < 2; ++i)
    {
        start[i] = 0;
        size[i]  = 3;
   }
    imageType::RegionType region;
    region.SetSize(size);
    region.SetIndex(start);
    image->SetRegions(region);

    typedef imageType::DirectionType DirectionType;
    DirectionType axisDirection = image->GetDirection();
    axisDirection[0][0] = 0;
    axisDirection[0][1] = 1;
    axisDirection[1][0] = 1;
    axisDirection[1][1] = 0;
    image->SetDirection(axisDirection);

    double origin[2] = {1,4};
    double spacing[2] = {4,1};
    // THIS IS WHAT I BELIEVE IS A BUG. I WOULD HAVE THOUGHT SPACING WOULD BE IN X,Y ORDER, OR BE CONSISTENT WITH THE DEFINITION OF ORIGIN AT A MINIMUM.

    // Flip X and Y axis orientation so that X goes across rows and Y goes across columns
    image->SetDirection(axisDirection);
    image->SetOrigin(origin);
    image->SetSpacing(spacing);

    itk::ContinuousIndex< double, 2 > pixelIndex;
    imageType::PointType worldPointOfInterest;
    worldPointOfInterest[0] = 1;      // x position of the pixel
    worldPointOfInterest[1] = 4;      // y position of the pixel
    image->TransformPhysicalPointToContinuousIndex(worldPointOfInterest,pixelIndex);

    std::cout << "Continuous index at world location (1,4):  " << pixelIndex << std::endl;

    worldPointOfInterest[0] = 2;      // x position of the pixel
    worldPointOfInterest[1] = 4;      // y position of the pixel
    image->TransformPhysicalPointToContinuousIndex(worldPointOfInterest,pixelIndex);

    std::cout << "Continuous index at world location (2,4):  " << pixelIndex << std::endl;

    worldPointOfInterest[0] = 1;      // x position of the pixel
    worldPointOfInterest[1] = 8;      // y position of the pixel
    image->TransformPhysicalPointToContinuousIndex(worldPointOfInterest,pixelIndex);


    std::cout << "Continuous index at world location (1,8):  " << pixelIndex << std::endl;

    worldPointOfInterest[0] = 2;      // x position of the pixel
    worldPointOfInterest[1] = 8;      // y position of the pixel
    image->TransformPhysicalPointToContinuousIndex(worldPointOfInterest,pixelIndex);

    std::cout << "Continuous index at world location (2,8):  " << pixelIndex << std::endl;
_____________________________________
Powered by www.kitware.com<http://www.kitware.com>

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://www.itk.org/mailman/listinfo/insight-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130221/fde97755/attachment.htm>


More information about the Insight-users mailing list