[Insight-users] VectorImage Orientation from NRRD

Gordon Kindlmann gk at bwh.harvard.edu
Thu Oct 30 13:39:12 EDT 2008


Thanks for the link to the previous post about ITK using LPS- that is  
helpful.  I agree with you that better explicit documentation would  
be good.

The issue at stake is the combination of what coordinate frame does  
ITK use for orientation specification, and, is it okay for a file  
reader to automagically convert orientation specification in RAS to  
LPS.  Such a conversion can be surprising, and surprising usually  
isn't good.

It would be less surprising if "ITK uses LPS" was known far and  
wide.  Or, I was proposing that the automagic conversion be something  
that be turned off if so desired.  I have no idea what the API for  
that should be, so I was asking for tips, especially if there was  
something else analogous for another format.  So far no response.

More feedback from the main ITK developers would be very much  
appreciated.

Gordon

On Oct 30, 2008, at 11:31 AM, Luke Bloy wrote:

> I've been following this conversation and perhaps I'm missing the  
> issue. From what I can gather the discussion is about what world  
> coordinates the directional cosines, returned by  
> itkImage::GetDirection() is expressed in?
>
> I had a similar question a month or so ago and got this response  
> from Luis saying that ITK used the LPS world coordinate system  
> ( http://www.itk.org/pipermail/insight-users/2008-August/ 
> 027102.html ).  I think the choice of LPS should be better  
> documented then it is at the moment.
>
> But once that is made more clear, I don't see what the problem is?  
> It seems like having the filereaders bring the files directional  
> cosines matrix into the LPS world frame is the correct thing to do.  
> If we want to add the functionality of being able to grab the  
> location of a pixel in another world frame (RAS for example) then  
> it seems like the proper place to put this would be in
> TransformIndexToPhysicalPoint(), GetDirection() and GetOrigin().  
> They could take a flag specifying the desired frame of the output  
> and convert the internal LPS stored directional cosines into what  
> ever the user wanted. This way the functionality would be available  
> for all image types as opposed to only NRRD.
>
> -Luke
>
>
>
>
>
> Gordon Kindlmann wrote:
>>
>> This patch confuses two independent issues:
>>
>> 1) turning on ITK_USE_ORIENTED_IMAGE_DIRECTION.  It sounds like  
>> you're happy with this, specifically the resulting enhancements in  
>> orientation behavior to itkVectorImage.  Great.
>>
>> 2) itkNrrdImageIO.cxx's conversion of explicitly RAS orientation  
>> to the implicit LPS orientation of ITK.  You're understandably not  
>> happy with this.
>>
>> The patch you suggest confuses the issues by disabling (2) when  
>> (1) is off, but the two things are completely unrelated, so I'm  
>> not going to commit this.
>>
>> The real solution is to enable explicit run-time control of  
>> whether the RAS -> LPS orientation conversion happens inside  
>> itkNrrdImageIO.  This would replace how you used  
>> ITK_USE_ORIENTED_IMAGE_DIRECTION in your patch, with some new  
>> member variable (and would use "if ()" instead of "#ifndef").
>>
>> Before I try anything like that, though, I need others to comment on
>>
>> 1) Whether there are any existing examples of state variables in  
>> file input, so that at run-time users can vary the handling of  
>> data after its read from disk, and before its returned to ITK.
>>
>> 2) Documentation of ITK's use of LPS for 3-D orientation  
>> specification.  Is it really the policy, or not?
>>
>> Gordon
>>
>> On Oct 19, 2008, at 9:31 PM, Daniel Betz wrote:
>>
>>> Hello Gordon,
>>>
>>> as far as I can see are the following files affected
>>>
>>> itkNrrdImageIO.cxx
>>> itkNiftiImageIO.cxx
>>> itkAnalyzeImageIO.cxx
>>> itkGE4ImageIO.cxx
>>> itkGE5ImageIO.cxx
>>> itkGEAdwImageIO.cxx
>>> itkPolygonGroupSpatialObjectXMLFile.cxx
>>> itkSiemensVisionImageIO.cxx
>>>
>>>
>>> With the new oriented itk::Image it is actually very easy to get
>>> a file correctly loaded. With the commit to itkVectorImage.txx a
>>> few ours ago I need only three "#ifndef" in itkNrrdImageIO.cxx and
>>> my test program from the beginning of this thread passed.
>>>
>>> <diff>
>>> Index: Code/IO/itkNrrdImageIO.cxx
>>> ===================================================================
>>> RCS file: /cvsroot/Insight/Insight/Code/IO/itkNrrdImageIO.cxx,v
>>> retrieving revision 1.38
>>> diff -u -r1.38 itkNrrdImageIO.cxx
>>> --- Code/IO/itkNrrdImageIO.cxx  16 May 2007 19:44:55 -0000  1.38
>>> +++ Code/IO/itkNrrdImageIO.cxx  19 Oct 2008 23:48:47 -0000
>>> @@ -442,6 +442,7 @@
>>>        case nrrdSpacingStatusDirection:
>>>          if (AIR_EXISTS(spacing))
>>>            {
>>> +#ifndef ITK_USE_ORIENTED_IMAGE_DIRECTION
>>>            // only set info if we have something to set
>>>            switch (nrrd->space)
>>>              {
>>> @@ -464,6 +465,7 @@
>>>                // to LPS is well-defined
>>>                break;
>>>              }
>>> +#endif
>>>            this->SetSpacing(axii, spacing);
>>>
>>>            for (unsigned int saxi=0; saxi < nrrd->spaceDim; saxi++)
>>> @@ -496,6 +498,7 @@
>>>          {
>>>          spaceOrigin[saxi] = nrrd->spaceOrigin[saxi];
>>>          }
>>> +#ifndef ITK_USE_ORIENTED_IMAGE_DIRECTION
>>>        switch (nrrd->space)
>>>          {
>>>          // convert non-LPS coords into LPS coords, when we can
>>> @@ -514,6 +517,7 @@
>>>            // to LPS is well-defined
>>>            break;
>>>          }
>>> +#endif
>>>        for (unsigned int saxi=0; saxi < nrrd->spaceDim; saxi++)
>>>          {
>>>          this->SetOrigin(saxi, spaceOrigin[saxi]);
>>> @@ -641,13 +645,16 @@
>>>        case nrrdSpaceRightAnteriorSuperior:
>>>        case nrrdSpaceLeftAnteriorSuperior:
>>>        case nrrdSpaceLeftPosteriorSuperior:
>>> +#ifndef ITK_USE_ORIENTED_IMAGE_DIRECTION
>>>          // in all these cases we could convert
>>>          EncapsulateMetaData<std::string>(thisDic, std::string(key),
>>> -                                         std::string( airEnumStr 
>>> (nrrdSpace,
>>> nrrdSpaceLeftPosteriorSuperior )));
>>> +                                         std::string( airEnumStr 
>>> (nrrdSpace,
>>> +                                          
>>> nrrdSpaceLeftPosteriorSuperior )));
>>>          break;
>>>        default:
>>>          // we're not coming from a space for which the conversion
>>>          // to LPS is well-defined
>>> +#endif
>>>          EncapsulateMetaData<std::string>(thisDic, std::string(key),
>>>                                           std::string(val));
>>>          break;
>>> </diff>
>>>
>>> Regards
>>> Daniel Betz
>>>
>>
>> _______________________________________________
>> Insight-users mailing list
>> Insight-users at itk.org
>> http://www.itk.org/mailman/listinfo/insight-users



More information about the Insight-users mailing list