Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkStaticIGTHelperFunctions.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 #include <itkVector.h>
15 
17  {
18  double returnValue;
19 
20  itk::Vector<double,3> point; //caution 5D-Tools: correct vector along the tool axis is needed
21  point[0] = rotationVector[0];
22  point[1] = rotationVector[1];
23  point[2] = rotationVector[2];
24 
25  //Quaternions used for rotations should alway be normalized, so just to be safe:
26  a.normalize();
27  b.normalize();
28 
29  itk::Matrix<double,3,3> rotMatrixA;
30  for(int i=0; i<3; i++) for(int j=0; j<3; j++) rotMatrixA[i][j] = a.rotation_matrix_transpose().transpose()[i][j];
31 
32  itk::Matrix<double,3,3> rotMatrixB;
33  for(int i=0; i<3; i++) for(int j=0; j<3; j++) rotMatrixB[i][j] = b.rotation_matrix_transpose().transpose()[i][j];
34 
35  itk::Vector<double,3> pt1 = rotMatrixA * point;
36  itk::Vector<double,3> pt2 = rotMatrixB * point;
37 
38  returnValue = (pt1[0]*pt2[0]+pt1[1]*pt2[1]+pt1[2]*pt2[2]) / ( sqrt(pow(pt1[0],2.0)+pow(pt1[1],2.0)+pow(pt1[2],2.0)) * sqrt(pow(pt2[0],2.0)+pow(pt2[1],2.0)+pow(pt2[2],2.0)));
39  returnValue = acos(returnValue) * 57.296; //57,296 = 180/Pi ; conversion to degrees
40 
41  return returnValue;
42  }
43 
45 {
46  //formula returnValue = 2 * acos ( a <dotproduct> b )
47  //(+ normalization because we need unit quaternions)
48  //derivation from here: https://fgiesen.wordpress.com/2013/01/07/small-note-on-quaternion-distance-metrics/
49  double returnValue = ((a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]) / (sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3])*sqrt(b[0] * b[0] + b[1] * b[1] + b[2] * b[2] + b[3] * b[3])));
50  returnValue = 2 * acos(returnValue);
51  return returnValue;
52 }
53 
54 itk::Matrix<double,3,3> mitk::StaticIGTHelperFunctions::ConvertEulerAnglesToRotationMatrix(double alpha, double beta, double gamma)
55 {
56  double PI = 3.141592653589793;
57  alpha = alpha * PI / 180;
58  beta = beta * PI / 180;
59  gamma = gamma * PI / 180;
60 
61  //convert angles to matrix:
62  itk::Matrix<double,3,3> matrix;
63 
64  /* x-Konvention (Z, X, Z)
65  matrix[0][0] = cos(alpha) * cos(gamma) - sin(alpha) * cos(beta) * sin(gamma);
66  matrix[0][1] = -cos(alpha) * sin(gamma)- sin(alpha) * cos(beta) * cos(gamma);
67  matrix[0][2] = sin(alpha) * sin(beta);
68 
69  matrix[1][0] = sin(alpha) * cos(gamma) + cos(alpha) * cos(beta) * sin(gamma);
70  matrix[1][1] = cos(alpha) * cos(beta) * cos(gamma) - sin(alpha) * sin(gamma);
71  matrix[1][2] = -cos(alpha) * sin(beta);
72 
73  matrix[2][0] = sin(beta) * sin(gamma);
74  matrix[2][1] = sin(beta) * cos(gamma);
75  matrix[2][2] = cos(beta);
76  */
77 
78  //Luftfahrtnorm (DIN 9300) (Yaw-Pitch-Roll, Z, Y, X)
79  matrix[0][0] = cos(beta) * cos(alpha);
80  matrix[0][1] = cos(beta) * sin(alpha);
81  matrix[0][2] = -sin(beta);
82 
83  matrix[1][0] = sin(gamma) * sin(beta) * cos(alpha) - cos(gamma) * sin(alpha) ;
84  matrix[1][1] = sin(gamma) * sin(beta) * sin(alpha) + cos(gamma) * cos(alpha);
85  matrix[1][2] = sin(gamma) * cos(beta);
86 
87  matrix[2][0] = cos(gamma) * sin(beta) * cos(alpha) + sin(gamma) * sin(alpha);
88  matrix[2][1] = cos(gamma) * sin(beta) * sin(alpha) - sin(gamma) * cos(alpha);
89  matrix[2][2] = cos(gamma) * cos(beta);
90 
91  return matrix;
92 }
93 
94 double mitk::StaticIGTHelperFunctions::ComputeFRE(mitk::PointSet::Pointer imageFiducials, mitk::PointSet::Pointer realWorldFiducials, vtkSmartPointer<vtkLandmarkTransform> transform)
95 {
96  if (imageFiducials->GetSize() != realWorldFiducials->GetSize())
97  {
98  MITK_WARN << "Cannot compute FRE, got different numbers of points (1: " << imageFiducials->GetSize() << " /2: " << realWorldFiducials->GetSize() << ")";
99  return -1;
100  }
101  double FRE = 0;
102  for (int i = 0; i < imageFiducials->GetSize(); i++)
103  {
104  itk::Point<double> current_image_fiducial_point = imageFiducials->GetPoint(i);
105  if (transform != nullptr)
106  {
107  current_image_fiducial_point = transform->TransformPoint(imageFiducials->GetPoint(i)[0], imageFiducials->GetPoint(i)[1], imageFiducials->GetPoint(i)[2]);
108  }
109  double cur_error_squared = current_image_fiducial_point.SquaredEuclideanDistanceTo(realWorldFiducials->GetPoint(i));
110  FRE += cur_error_squared;
111  }
112 
113  FRE = sqrt(FRE / (double)imageFiducials->GetSize());
114 
115  return FRE;
116 }
const mitk::ScalarType PI
#define MITK_WARN
Definition: mitkLogMacros.h:19
static double ComputeFRE(mitk::PointSet::Pointer imageFiducials, mitk::PointSet::Pointer realWorldFiducials, vtkSmartPointer< vtkLandmarkTransform > transform=nullptr)
Computes the fiducial registration error out of two sets of fiducials. The two sets must have the sam...
vnl_quaternion< ScalarType > Quaternion
static itk::Matrix< double, 3, 3 > ConvertEulerAnglesToRotationMatrix(double alpha, double beta, double gamma)
static double GetAngleBetweenTwoQuaterions(mitk::Quaternion a, mitk::Quaternion b, itk::Vector< double, 3 > rotationVector)