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

Bradley Lowekamp blowekamp at mail.nih.gov
Thu Feb 21 12:18:16 EST 2013


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> 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
> 
> 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/f50dc945/attachment.htm>


More information about the Insight-users mailing list