]> Creatis software - gdcm.git/blobdiff - src/gdcmOrientation.cxx
add std::string Orientation::GetOrientation ( File *f ) method, that
[gdcm.git] / src / gdcmOrientation.cxx
index 0516519d885638868f80357e8bf83a5bb05bc557..26f70d7abaee8d8d7dc05157b155549276ea2541 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmOrientation.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/09/16 16:47:56 $
-  Version:   $Revision: 1.7 $
+  Date:      $Date: 2005/09/21 16:39:53 $
+  Version:   $Revision: 1.11 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -60,7 +60,12 @@ double Orientation::TypeOrientation( File *f )
       gdcmErrorMacro( "No Image Orientation (0020,0037) found in the file, cannot proceed." )
       return 0;
    }
-
+/*
+std::cout << " iop : ";
+for(int i=0;i<6;i++)
+   std::cout << iop[i] << "  ";
+std::cout << std::endl;
+*/
    vector3D ori1;
    vector3D ori2;
 
@@ -69,9 +74,9 @@ double Orientation::TypeOrientation( File *f )
 
    // two perpendicular vectors describe one plane
    double dicPlane[6][2][3] =
-   { {  {1,    0,    0   },{0,       1,     0     }  }, // Axial
-     {  {1,    0,    0   },{0,       0,    -1     }  }, // Coronal
-     {  {0,    1,    0   },{0,       0,    -1     }  }, // Sagittal
+   { {  { 1,   0,    0   },{ 0,      1,     0     }  }, // Axial
+     {  { 1,   0,    0   },{ 0,      0,    -1     }  }, // Coronal
+     {  { 0,   1,    0   },{ 0,      0,    -1     }  }, // Sagittal
      {  { 0.8, 0.5,  0.0 },{-0.1,    0.1 , -0.95  }  }, // Axial - HEART
      {  { 0.8, 0.5,  0.0 },{-0.6674, 0.687, 0.1794}  }, // Coronal - HEART
      {  {-0.1, 0.1, -0.95},{-0.6674, 0.687, 0.1794}  }  // Sagittal - HEART
@@ -83,6 +88,10 @@ double Orientation::TypeOrientation( File *f )
    Res res;   // [ <result> , <memory of the last succes calcule> ]
    res.first = 0;
    res.second = 99999;
+
+ std::cout << "-------------- res : " << res.first << "|" << res.second 
+           << std::endl;
+
    for (int numDicPlane=0; numDicPlane<6; numDicPlane++)
    {
        ++i;
@@ -95,7 +104,11 @@ double Orientation::TypeOrientation( File *f )
        refB.y = dicPlane[numDicPlane][1][1]; 
        refB.z = dicPlane[numDicPlane][1][2];
        res=VerfCriterion(  i, CalculLikelyhood2Vec(refA,refB,ori1,ori2), res );
+ std::cout << "-------------- res : " << res.first << "|" << res.second 
+           << std::endl;
        res=VerfCriterion( -i, CalculLikelyhood2Vec(refB,refA,ori1,ori2), res );
+ std::cout << "-------------- res : " << res.first << "|" << res.second 
+           << std::endl;
    }
    return res.first;
 /*
@@ -115,11 +128,12 @@ Res
 Orientation::VerfCriterion(int typeCriterion, double criterionNew, Res const &in)
 {
    Res res;
+//   double type = in.first;
    double criterion = in.second;
-   if (criterionNew < criterion)
+   if (/*criterionNew < 0.1 && */criterionNew < criterion)
    {
-      res.first  = criterionNew;
-      res.second = typeCriterion;
+      res.first  = typeCriterion;
+      res.second = criterionNew;
    }
 /*
 //   type = res[0]
@@ -179,7 +193,7 @@ Orientation::CalculLikelyhood2Vec(vector3D const &refA, vector3D const &refB,
 // (vec) :    - Vector 3D
 //------------------------- Other : -------------------------------------
 vector3D
-Orientation::ProductVectorial(vector3D const & vec1, vector3D const & vec2)
+Orientation::ProductVectorial(vector3D const &vec1, vector3D const &vec2)
 {
    vector3D vec3;
    vec3.x =    vec1.y*vec2.z - vec1.z*vec2.y;
@@ -189,13 +203,10 @@ Orientation::ProductVectorial(vector3D const & vec1, vector3D const & vec2)
    return vec3;
 }
 
-} // end namespace gdcm
-
-
 
 
 // ---------------------------------------------------------------------------
-// Here is the original code, in Python, kindly supllied by THERALYS
+// Here is the original Python code, kindly supplied by THERALYS
 //
 // C++ code doesn't give good results
 // --> FIXME
@@ -260,7 +271,7 @@ try:
       res=self.VerfCriterion( -i , self.CalculLikelyhood2Vec(refB,refA,ori1,ori2) , res )
    return res[0]
 
-except KeyError:
+   except KeyError:
    return 0
 
 
@@ -331,3 +342,140 @@ except KeyError:
       return dic
 
 */
+
+
+// ------------------------------------------------------------------------
+/*
+2.2.2 Orientation of DICOM images
+
+
+http://www.dclunie.com/medical-image-faq/html/part2.html#DICOMOrientation
+says :
+
+A question that is frequently asked in comp.protocols.dicom is how to determine
+ which side of an image is which (e.g. left, right) and so on. 
+ The short answer is that for projection radiographs this is specified 
+ explicitly using the Patient Orientation attribute, and for cross-sectional 
+ images it needs to be derived from the Image Orientation (Patient) direction 
+ cosines. In the standard these are explained as follows:
+
+    * "C.7.6.1.1.1 Patient Orientation. 
+                The Patient Orientation (0020,0020) relative to the image 
+                plane shall be specified by two values that designate the 
+                anatomical direction of the positive row axis (left to right)
+                and the positive column axis (top to bottom). 
+                The first entry is the direction of the rows, given by the 
+                direction of the last pixel in the first row from the first 
+                pixel in that row. 
+                The second entry is the direction of the columns, given by 
+                the direction of the last pixel in the first column from the
+                first pixel in that column. 
+                Anatomical direction shall be designated by the capital 
+                letters: A (anterior), P (posterior), R (right),L (left), 
+                H (head), F (foot). 
+                Each value of the orientation attribute shall contain at 
+                least one of these characters. 
+                If refinements in the orientation descriptions are to be 
+                specified, then they shall be designated by one or two 
+                additional letters in each value. 
+                Within each value, the letters shall be ordered with the 
+                principal orientation designated in the first character."
+    * "C.7.6.2.1.1 Image Position And Image Orientation. 
+                The Image Position (0020,0032) specifies the x, y, and z 
+                coordinates of the upper left hand corner of the image; 
+                it is the center of the first voxel transmitted. 
+                Image Orientation (0020,0037) specifies the direction 
+                cosines of the first row and the first column with respect to
+                the patient. These Attributes shall be provided as a pair. 
+                Row value for the x, y, and z axes respectively followed by 
+                the Column value for the x, y, and z axes respectively. 
+                The direction of the axes is defined fully by the patient's 
+                orientation. 
+                The x-axis is increasing to the left hand sid of the patient.
+                The y-axis is increasing to the posterior side of the patient
+                The z-axis is increasing toward the head of the patient. 
+                The patient based coordinate system is a right handed system,
+                i.e. the vector cross product of a unit vector along the 
+                positive x-axis and a unit vector along the positive y-axis
+                is equal to a unit vector along the positive z-axis." 
+
+Some simple code to take one of the direction cosines (vectors) from the 
+Image Orientation (Patient) attribute and generate strings equivalent to one 
+of the values of Patient Orientation looks like this (noting that if the vector
+is not aligned exactly with one of the major axes, the resulting string will 
+have multiple letters in as described under "refinements" in C.7.6.1.1.1): 
+
+*/
+
+/**
+ * \brief computes the Patient Orientation relative to the image plane
+ *          from the 'Image Orientation (Patient)'
+ *          The first entry is the direction of the rows, given by the 
+ *          direction of the last pixel in the first row from the first 
+ *          pixel in that row. 
+ *          The second entry is the direction of the columns, given by 
+ *          the direction of the last pixel in the first column from the
+ *          first pixel in that column. 
+ *          Anatomical direction is designated by the capital 
+ *          letters: A (anterior), P (posterior), R (right),L (left), 
+ *          H (head), F (foot).
+ *          Refinements in the orientation descriptions are designated 
+ *          by one or two additional letters in each value.   
+ * @return orientation string as "rawOrientation\columnsOrientation"
+ */
+std::string Orientation::GetOrientation ( File *f )
+{
+   float iop[6];
+   if ( !f->GetImageOrientationPatient( iop ) )
+   return GDCM_UNFOUND;
+
+   std::string orientation;
+   orientation = GetSingleOrientation ( iop ) 
+               + "\\" 
+               + GetSingleOrientation ( iop + 3 );
+   return orientation;
+}
+
+
+std::string Orientation::GetSingleOrientation ( float *iop)
+{
+   std::string orientation;
+
+   char orientationX = iop[0] < 0 ? 'R' : 'L';
+   char orientationY = iop[1] < 0 ? 'A' : 'P';
+   char orientationZ = iop[2] < 0 ? 'F' : 'H';
+
+   double absX = iop[0];
+   if (absX < 0) absX = -absX;
+      double absY = iop[1];
+   if (absY < 0) absY = -absY;
+      double absZ = iop[2];
+   if (absZ < 0) absZ = -absZ;
+
+   for (int i=0; i<3; ++i) 
+   {
+      if (absX>.0001 && absX>absY && absX>absZ) 
+      {
+         orientation = orientation + orientationX;
+         absX=0;
+       }
+       else if (absY>.0001 && absY>absX && absY>absZ) 
+       {
+          orientation = orientation + orientationY;
+          absY=0;
+       }
+       else if (absZ>.0001 && absZ>absX && absZ>absY) 
+       {
+           orientation = orientation + orientationZ;
+           absZ=0;
+       }
+       else 
+          break;
+     }
+   return orientation;
+} 
+
+
+
+} // end namespace gdcm