]> Creatis software - gdcm.git/blobdiff - src/gdcmOrientation.cxx
ENH: Refactorize code, from PrintFile into the class, to allow user to reuse the...
[gdcm.git] / src / gdcmOrientation.cxx
index 26f70d7abaee8d8d7dc05157b155549276ea2541..5516c6bd857207d99974677418d8d7a36fb630a9 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmOrientation.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/09/21 16:39:53 $
-  Version:   $Revision: 1.11 $
+  Date:      $Date: 2005/10/01 19:39:16 $
+  Version:   $Revision: 1.15 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -51,21 +51,42 @@ namespace gdcm
  *   #   6 : Heart Sagital
  *   #  -6 : Heart Sagital invert
  */
-double Orientation::TypeOrientation( File *f )
+
+static const char  *OrientationTypeStrings[] = { 
+  "Not Applicable",
+  "Axial",
+  "Coronal",
+  "Sagital",
+  "Heart Axial",
+  "Heart Coronal",
+  "Heart Sagital",
+  "Axial invert",
+  "Coronal invert",
+  "Sagital invert",
+  "Heart Axial invert",
+  "Heart Coronal invert",
+  "Heart Sagital invert",
+  NULL
+};
+
+const char* Orientation::GetOrientationTypeString(OrientationType const o)
+{
+  int k = (int)o;
+  if (k < 0) 
+       k = -k + 6;
+
+  return OrientationTypeStrings[k];
+}
+
+OrientationType Orientation::GetOrientationType( File *f )
 {
    float iop[6];
    bool succ = f->GetImageOrientationPatient( iop );
    if ( !succ )
    {
-      gdcmErrorMacro( "No Image Orientation (0020,0037) found in the file, cannot proceed." )
-      return 0;
+      gdcmErrorMacro( "No Image Orientation (0020,0037)/(0020,0032) found in the file, cannot proceed." )
+      return NotApplicable;
    }
-/*
-std::cout << " iop : ";
-for(int i=0;i<6;i++)
-   std::cout << iop[i] << "  ";
-std::cout << std::endl;
-*/
    vector3D ori1;
    vector3D ori2;
 
@@ -89,9 +110,6 @@ std::cout << std::endl;
    res.first = 0;
    res.second = 99999;
 
- std::cout << "-------------- res : " << res.first << "|" << res.second 
-           << std::endl;
-
    for (int numDicPlane=0; numDicPlane<6; numDicPlane++)
    {
        ++i;
@@ -104,46 +122,25 @@ std::cout << std::endl;
        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;
-/*
-//  i=0
-//  res=[0,99999]  ## [ <result> , <memory of the last succes calculus> ]
-//  for plane in dicPlane:
-//      i=i+1
-//      refA=plane[0]
-//      refB=plane[1]
-//      res=self.VerfCriterion(  i , self.CalculLikelyhood2Vec(refA,refB,ori1,ori2) , res )
-//      res=self.VerfCriterion( -i , self.CalculLikelyhood2Vec(refB,refA,ori1,ori2) , res )
-//  return res[0]
-*/
+   gdcmAssertMacro( res.first <= 6 && res.first >= -6);
+   return (OrientationType)res.first;
 }
 
 Res 
 Orientation::VerfCriterion(int typeCriterion, double criterionNew, Res const &in)
 {
    Res res;
-//   double type = in.first;
+   double type = in.first;
    double criterion = in.second;
    if (/*criterionNew < 0.1 && */criterionNew < criterion)
    {
-      res.first  = typeCriterion;
-      res.second = criterionNew;
+      type      = typeCriterion;
+      criterion = criterionNew;
    }
-/*
-//   type = res[0]
-//   criterion = res[1]
-// #     if criterionNew<0.1 and criterionNew<criterion:
-//   if criterionNew<criterion:
-//      criterion=criterionNew
-//      type=typeCriterion
-//   return [ type , criterion ]
-*/
+   res.first  = type;
+   res.second = criterion;
    return res;
 } 
 
@@ -354,13 +351,13 @@ 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 
+ 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 
+                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). 
@@ -382,18 +379,19 @@ A question that is frequently asked in comp.protocols.dicom is how to determine
                 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; 
+                The "Image Position (Patient)" (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. 
+                The "Image Orientation (Patient)" (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 x-axis is increasing to the left hand side 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 
@@ -421,7 +419,8 @@ have multiple letters in as described under "refinements" in C.7.6.1.1.1):
  *          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.   
+ *          by one or two additional letters in each value.
+ *          Use it when "Patient Orientation" (0020,0020) is not found 
  * @return orientation string as "rawOrientation\columnsOrientation"
  */
 std::string Orientation::GetOrientation ( File *f )
@@ -477,5 +476,210 @@ std::string Orientation::GetSingleOrientation ( float *iop)
 } 
 
 
+/*-------------------------------------------------------------------
+
+Some more stuff, from XMedcon
+
+---> Personal remark from JPRx :
+--> patient_position (0x0018,0x5100) can be "HFS ", "FFS ", "HFP ", "FFP " 
+--> the cosines may ahave any value -1< <+1, for MR images !
+
+enum patient_slice_orientation_type
+  {
+    patient_slice_orientation_unknown = 0,
+    supine_headfirst_transaxial,
+    supine_headfirst_sagittal,
+    supine_headfirst_coronal,
+    supine_feetfirst_transaxial,
+    supine_feetfirst_sagittal,
+    supine_feetfirst_coronal,
+    prone_headfirst_transaxial,
+    prone_headfirst_sagittal,
+    prone_headfirst_coronal,
+    prone_feetfirst_transaxial,
+    prone_feetfirst_sagittal,
+    prone_feetfirst_coronal
+  };
+
+void GetImageOrientationPatient(gdcm::File &h,F32 image_orientation_patient[6])
+{
+  h.GetImageOrientationPatient(image_orientation_patient);
+}
+
+#if 0
+//
+// this is all completely cribbed from the xmedcon library, since
+// we're trying to do what it does, mostly.
+patient_slice_orientation_type
+GetPatSliceOrient(gdcm::File &h)
+{
+  F32 image_orientation_patient[6];
+
+  // protected, do it the hard way
+  //  h.GetImageOrientationPatient(image_orientation_patient);
+  GetImageOrientationPatient(h,image_orientation_patient);
+
+  enum { headfirst, feetfirst } patient_orientation;
+  enum { supine, prone } patient_rotation;
+  enum { transaxial, sagittal, coronal } slice_orientation;
+
+  std::string patient_position = h.GetEntryByNumber(0x0018,0x5100);
+  if(patient_position == "gdcm::Unfound")
+    {
+    patient_position = "HF";
+    }
+  if(patient_position.find("HF") != std::string::npos)
+    {
+    patient_orientation = headfirst;
+    }
+  else if(patient_position.find("FF") != std::string::npos)
+    {
+    patient_orientation = feetfirst;
+    }
+
+  if(patient_position.find("S") != std::string::npos)
+    {
+    patient_rotation = supine;
+    }
+  else if(patient_position.find("P") != std::string::npos)
+    {
+    patient_rotation = prone;
+    }
+
+  if((image_orientation_patient[0] == 1 || image_orientation_patient[0] == -1) &&
+     (image_orientation_patient[4] == +1 || image_orientation_patient[4] == -1))
+    {
+    slice_orientation = transaxial;
+    }
+  else if((image_orientation_patient[1] == 1 || image_orientation_patient[1] == -1) &&
+          (image_orientation_patient[5] == +1 || image_orientation_patient[5] == -1))
+    {
+    slice_orientation = sagittal;
+    }
+  else if((image_orientation_patient[0] == 1 || image_orientation_patient[0] == -1) &&
+          (image_orientation_patient[5] == +1 || image_orientation_patient[5] == -1))
+    {
+    slice_orientation = coronal;
+    }
+  //
+  // combine results
+  patient_slice_orientation_type patient_slice_orientation = 
+    patient_slice_orientation_unknown;
+  switch (patient_rotation) 
+    {
+    case supine:
+      switch (patient_orientation) 
+        {
+        case headfirst:
+          switch (slice_orientation) 
+            {
+            case transaxial:
+              patient_slice_orientation = supine_headfirst_transaxial;
+              break;
+            case sagittal:
+              patient_slice_orientation = supine_headfirst_sagittal;
+              break;
+            case coronal:
+              patient_slice_orientation = supine_headfirst_coronal;
+              break;
+            }
+          break;
+        case feetfirst:
+          switch (slice_orientation) 
+            {
+            case transaxial:
+              patient_slice_orientation = supine_feetfirst_transaxial;
+              break;
+            case sagittal:
+              patient_slice_orientation = supine_feetfirst_sagittal;
+              break;
+            case coronal:
+              patient_slice_orientation = supine_feetfirst_coronal;
+              break;
+            }
+          break;
+        }
+      break;
+    case prone:
+      switch (patient_orientation) 
+        {
+        case headfirst:
+          switch (slice_orientation) 
+            {
+            case transaxial:
+              patient_slice_orientation = prone_headfirst_transaxial;
+              break;
+            case sagittal:
+              patient_slice_orientation = prone_headfirst_sagittal;
+              break;
+            case coronal:
+              patient_slice_orientation = prone_headfirst_coronal;
+              break;
+            }
+          break;
+        case feetfirst:
+          switch (slice_orientation) 
+            {
+            case transaxial:
+              patient_slice_orientation = prone_feetfirst_transaxial;
+              break;
+            case sagittal:
+              patient_slice_orientation = prone_feetfirst_sagittal;
+              break;
+            case coronal:
+              patient_slice_orientation = prone_feetfirst_coronal;
+              break;
+            }
+          break;
+        }
+      break;
+    }
+  if(patient_slice_orientation != patient_slice_orientation_unknown)
+    return patient_slice_orientation;
+  //
+  // this is what xmedcon does
+  if ((image_orientation_patient[0] == +1)   &&
+      (image_orientation_patient[4] == +1))   
+    patient_slice_orientation = supine_headfirst_transaxial;
+  else if ((image_orientation_patient[0] == -1)   &&
+           (image_orientation_patient[4] == +1))   
+    patient_slice_orientation = supine_feetfirst_transaxial;
+  else if ((image_orientation_patient[0] == -1)   &&
+           (image_orientation_patient[4] == -1))   
+    patient_slice_orientation = prone_headfirst_transaxial;
+  else if ((image_orientation_patient[0] == +1)   &&
+           (image_orientation_patient[4] == -1))   
+    patient_slice_orientation = prone_feetfirst_transaxial;
+
+  else if ((image_orientation_patient[1] == +1)   &&
+           (image_orientation_patient[5] == -1))   
+    patient_slice_orientation = supine_headfirst_sagittal;
+  else if ((image_orientation_patient[1] == +1)   &&
+           (image_orientation_patient[5] == +1))   
+    patient_slice_orientation = supine_feetfirst_sagittal;
+  else if ((image_orientation_patient[1] == -1)   &&
+           (image_orientation_patient[5] == -1))   
+    patient_slice_orientation = prone_headfirst_sagittal;
+  else if ((image_orientation_patient[1] == -1)   &&
+           (image_orientation_patient[5] == +1))   
+    patient_slice_orientation = prone_feetfirst_sagittal;
+
+  else if ((image_orientation_patient[0] == +1)   &&
+           (image_orientation_patient[5] == -1))   
+    patient_slice_orientation = supine_headfirst_coronal;
+  else if ((image_orientation_patient[0] == -1)   &&
+           (image_orientation_patient[5] == +1))   
+    patient_slice_orientation = supine_feetfirst_coronal;
+  else if ((image_orientation_patient[0] == -1)   &&
+           (image_orientation_patient[5] == -1))   
+    patient_slice_orientation = prone_headfirst_coronal;
+  else if ((image_orientation_patient[0] == +1)   &&
+           (image_orientation_patient[5] == +1))   
+    patient_slice_orientation = prone_feetfirst_coronal;
+  return patient_slice_orientation;
+}
+#else
+
+-------------------------------------------------------------------------*/
 
 } // end namespace gdcm