1 /*=========================================================================
4 Module: $RCSfile: gdcmOrientation.cxx,v $
6 Date: $Date: 2005/07/24 02:34:42 $
7 Version: $Revision: 1.1 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
19 #include "gdcmOrientation.h"
24 //--------------------------------------------------------------------
25 // THERALYS Algorithm to determine the most similar basic orientation
27 // Transliterated from original Python code.
28 // Kept as close as possible to the original code
29 // in order to speed up any further modif of Python code :-(
30 //-----------------------------------------------------------------------
33 * \brief THERALYS' Algorithm to determine the most similar basic orientation
34 * (Axial, Coronal, Sagital) of the image
35 * \note Should be run on the first gdcm::File of a 'coherent' Serie
36 * @return orientation code
37 * @return orientation code
38 * # 0 : Not Applicable (neither 0020,0037 Image Orientation Patient
39 * # nor 0020,0032Image Position found )
43 * # -2 : Coronal invert
45 * # -3 : Sagital invert
47 * # -4 : Heart Axial invert
49 * # -5 : Heart Coronal invert
51 * # -6 : Heart Sagital invert
53 double Orientation::TypeOrientation( File *f )
56 bool succ = f->GetImageOrientationPatient( iop );
65 ori1.x = iop[0]; ori1.y = iop[1]; ori1.z = iop[2];
66 ori1.x = iop[3]; ori2.y = iop[4]; ori2.z = iop[5];
68 // two perpendicular vectors describe one plane
69 double dicPlane[6][2][3] =
70 { { {1, 0, 0 },{0, 1, 0 } }, // Axial
71 { {1, 0, 0 },{0, 0, -1 } }, // Coronal
72 { {0, 1, 0 },{0, 0, -1 } }, // Sagittal
73 { { 0.8, 0.5, 0.0 },{-0.1, 0.1 , -0.95 } }, // Axial - HEART
74 { { 0.8, 0.5, 0.0 },{-0.6674, 0.687, 0.1794} }, // Coronal - HEART
75 { {-0.1, 0.1, -0.95},{-0.6674, 0.687, 0.1794} } // Sagittal - HEART
81 Res res; // [ <result> , <memory of the last succes calcule> ]
84 for (int numDicPlane=0; numDicPlane<6; numDicPlane++)
88 refA.x = dicPlane[numDicPlane][0][0];
89 refA.y = dicPlane[numDicPlane][0][1];
90 refA.z = dicPlane[numDicPlane][0][2];
92 refB.x = dicPlane[numDicPlane][1][0];
93 refB.y = dicPlane[numDicPlane][1][1];
94 refB.z = dicPlane[numDicPlane][1][2];
95 res=VerfCriterion( i, CalculLikelyhood2Vec(refA,refB,ori1,ori2), res );
96 res=VerfCriterion( -i, CalculLikelyhood2Vec(refB,refA,ori1,ori2), res );
101 // res=[0,99999] ## [ <result> , <memory of the last succes calculus> ]
102 // for plane in dicPlane:
106 // res=self.VerfCriterion( i , self.CalculLikelyhood2Vec(refA,refB,ori1,ori2) , res )
107 // res=self.VerfCriterion( -i , self.CalculLikelyhood2Vec(refB,refA,ori1,ori2) , res )
114 Orientation::VerfCriterion(int typeCriterion, double criterionNew, Res const & in)
117 double criterion = in.second;
118 if (criterionNew < criterion)
120 res.first = criterionNew;
121 res.second = typeCriterion;
125 // criterion = res[1]
126 // # if criterionNew<0.1 and criterionNew<criterion:
127 // if criterionNew<criterion:
128 // criterion=criterionNew
129 // type=typeCriterion
130 // return [ type , criterion ]
135 inline double square_dist(vector3D const &v1, vector3D const & v2)
138 res = (v1.x - v2.x)*(v1.x - v2.x) +
139 (v1.y - v2.y)*(v1.y - v2.y) +
140 (v1.z - v2.z)*(v1.z - v2.z);
144 //------------------------- Purpose : -----------------------------------
145 //- This function determines the orientation similarity of two planes.
146 // Each plane is described by two vectors.
147 //------------------------- Parameters : --------------------------------
148 //- <refA> : - type : vector 3D (double)
149 //- <refB> : - type : vector 3D (double)
150 // - Description of the first plane
151 //- <ori1> : - type : vector 3D (double)
152 //- <ori2> : - type : vector 3D (double)
153 // - Description of the second plane
154 //------------------------- Return : ------------------------------------
155 // double : 0 if the planes are perpendicular. While the difference of
156 // the orientation between the planes are big more enlarge is
158 //------------------------- Other : -------------------------------------
159 // The calculus is based with vectors normalice
161 Orientation::CalculLikelyhood2Vec(vector3D const & refA, vector3D const & refB,
162 vector3D const & ori1, vector3D const & ori2 )
165 vector3D ori3 = ProductVectorial(ori1,ori2);
166 vector3D refC = ProductVectorial(refA,refB);
167 double res = square_dist(refC, ori3);
172 //------------------------- Purpose : -----------------------------------
173 //- Calculus of the poduct vectorial between two vectors 3D
174 //------------------------- Parameters : --------------------------------
175 //- <vec1> : - type : vector 3D (double)
176 //- <vec2> : - type : vector 3D (double)
177 //------------------------- Return : ------------------------------------
178 // (vec) : - Vector 3D
179 //------------------------- Other : -------------------------------------
181 Orientation::ProductVectorial(vector3D const & vec1, vector3D const & vec2)
184 vec3.x = vec1.y*vec2.z - vec1.z*vec2.y;
185 vec3.y = -( vec1.x*vec2.z - vec1.z*vec2.x);
186 vec3.z = vec1.x*vec2.y - vec1.y*vec2.x;
191 } // end namespace gdcm