[Insight-developers] Spatial Orientation and DICOM

Gordon Kindlmann gk at bwh.harvard.edu
Wed Mar 2 17:08:33 EST 2005


hello,

I would be interested in seeing some discussion here about how these  
sorts of changes will or will not interact with the proposed extensions  
to itk::Image that were raised by Bill Lorensen at the recent NAMIC  
meeting in Salt Lake:

http://www.na-mic.org/Wiki/index.php/NAMIC_Wiki: 
Community_Coordinate_Systems

Specifically, with the coefficients in the direction cosines- does this  
set a precedent for the left-posterior-superior space of DICOM v3 to be  
the standard in ITK?

Gordon


On Mar 2, 2005, at 4:49 PM, Mathieu Malaterre wrote:

> Hello,
>
> 	A few weeks ago Kent Williams proposed a patch for the itkGDCMImageIO  
> that would allow passing the Spatial Orientation to ITK. After  
> discussion I would rather see this patch being done at the gdcm level,  
> at least for dealing with DICOM 'exceptions' (DICOM v3 vs ACR-NEMA for  
> example).
>
> 	Anyway I included the patch -basicalle Kent's one-. It will enhance  
> gdcm and give the gdcm::File a new method(*):
>
> void File::GetSpacialOrientation(SpacialOrientation terms[3])
>
> 	Where each terms can contains any of the following:
>
> enum SpacialOrientation {
>    CoordinateInvalid,
>    CoordinateRight,
>    CoordinateLeft,
>    CoordinatePosterior,    // back
>    CoordinateAnterior,     // front
>    CoordinateInferior,     // below
>    CoordinateSuperior      // above
> };
>
>
> 	Then from ITK level you only need to call this method and change from  
> gdcm::SpacialOrientation to itk::SpatialOrientation.
>
>
> Let me know what you think,
> Mathieu
> (*) It reuses the method
> void File::GetImageOrientationPatient( float iop[6]
> to retrieve the cosines from DICOM file.
> Index: gdcmFile.cxx
> ===================================================================
> RCS file: /cvs/public/gdcm/src/gdcmFile.cxx,v
> retrieving revision 1.228
> diff -u -3 -p -r1.228 gdcmFile.cxx
> --- gdcmFile.cxx	2 Mar 2005 17:18:32 -0000	1.228
> +++ gdcmFile.cxx	2 Mar 2005 21:48:25 -0000
> @@ -641,6 +641,93 @@ void File::GetImageOrientationPatient( f
>     }
>  }
>
> +inline unsigned Max3(float x, float y, float z)
> +{
> +  x = fabs(x);
> +  y = fabs(y);
> +  z = fabs(z);
> +  if(x > y && x > z)
> +    {
> +    return 0;
> +    }
> +  if(y > x && y > z)
> +    {
> +    return 1;
> +    }
> +  if(z > x && z > y)
> +    {
> +    return 2;
> +    }
> +  // they must all be equal, so just say x
> +  return 0;
> +}
> +
> +/**
> +  * \brief gets the info from 0020,0037 : Image Orientation Patient
> +  * and then determine the spacial orientation
> +  * @param  spatial orientation (3)enum aray to receive values
> +  * @return Spatial Orientation of patient (decoded DICOM cosine  
> values)
> +  */
> +void File::GetSpacialOrientation(SpacialOrientation terms[3])
> +{
> +   float cosines[6];
> +   // Read cosines value from file
> +   GetImageOrientationPatient(cosines);
> +
> +   int axes[9] = {0,0,0,0,0,0,0,0,0};
> +   int dominant_axis;
> +
> +   // figure out the dominant axis of the row
> +   dominant_axis = Max3(cosines[0],
> +                        cosines[1],
> +                        cosines[2]);
> +   axes[dominant_axis] = (cosines[dominant_axis] < 0 ? -1 : 1);
> +
> +   // figure the dominant axis of the column dimension
> +   dominant_axis = Max3(cosines[3],
> +                        cosines[4],
> +                        cosines[5]);
> +   axes[dominant_axis + 3] = (cosines[dominant_axis + 3] < 0 ? -1 :  
> 1);
> +
> +   // cross product to get slice direction
> +   axes[6] = axes[1] * axes[5] - axes[2] * axes[4];
> +   axes[7] = axes[2] * axes[3] - axes[0] * axes[5];
> +   axes[8] = axes[0] * axes[4] - axes[1] * axes[3];
> +
> +   //
> +   // swizzle up the spatial orientation.
> +   // this is based on the idea that SpatialOrientation in the  
> patient's
> +   // frame of reference.
> +   terms[0] = terms[1] = terms[2] = CoordinateInvalid;
> +   for(unsigned int i = 0; i < 3; i++)
> +   {
> +      if(axes[(i*3)] == 1)
> +      {
> +        terms[i] = CoordinateRight;
> +      }
> +      else if(axes[(i*3)] == -1)
> +      {
> +        terms[i] = CoordinateLeft;
> +      }
> +      else if(axes[(i*3)+1] == 1)
> +      {
> +        terms[i] = CoordinateAnterior;
> +      }
> +      else if(axes[(i*3)+1] == -1)
> +      {
> +        terms[i] = CoordinatePosterior;
> +      }
> +      else if(axes[(i*3)+2] == 1)
> +      {
> +        terms[i] = CoordinateInferior;
> +      }
> +      else if(axes[(i*3)+2] == -1)
> +      {
> +        terms[i] = CoordinateSuperior;
> +      }
> +   }
> +}
> +
>  /**
>   * \brief   Retrieve the number of Bits Stored (actually used)
>   *          (as opposed to number of Bits Allocated)
> Index: gdcmFile.h
> ===================================================================
> RCS file: /cvs/public/gdcm/src/gdcmFile.h,v
> retrieving revision 1.104
> diff -u -3 -p -r1.104 gdcmFile.h
> --- gdcmFile.h	15 Feb 2005 18:12:35 -0000	1.104
> +++ gdcmFile.h	2 Mar 2005 21:48:25 -0000
> @@ -73,6 +73,16 @@ enum ModalityType {
>     XC        // Photographic Imaging
>  };
>
> +// Enhance notion of spatial orientation for third party library
> +enum SpacialOrientation {
> +   CoordinateInvalid,
> +   CoordinateRight,
> +   CoordinateLeft,
> +   CoordinatePosterior,    // back
> +   CoordinateAnterior,     // front
> +   CoordinateInferior,     // below
> +   CoordinateSuperior      // above
> +};
>   
> / 
> /---------------------------------------------------------------------- 
> -------
>
>  /**
> @@ -119,6 +129,7 @@ public:
>     float GetZOrigin();
>
>     void GetImageOrientationPatient( float iop[6] );
> +   void GetSpacialOrientation(SpacialOrientation terms[3]);
>
>     int GetBitsStored();
>     int GetBitsAllocated();
> _______________________________________________
> Insight-developers mailing list
> Insight-developers at itk.org
> http://www.itk.org/mailman/listinfo/insight-developers



More information about the Insight-developers mailing list