MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkStaticIGTHelperFunctions.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
14#include <itkVector.h>
15
16double mitk::StaticIGTHelperFunctions::GetAngleBetweenTwoQuaterions(mitk::Quaternion a, mitk::Quaternion b, itk::Vector<double,3> rotationVector)
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
44double mitk::StaticIGTHelperFunctions::GetAngleBetweenTwoQuaterions(mitk::Quaternion a, mitk::Quaternion b)
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
54itk::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
94double 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}
MITKIGTBASE_EXPORT double GetAngleBetweenTwoQuaterions(mitk::Quaternion a, mitk::Quaternion b, itk::Vector< double, 3 > rotationVector)
MITKIGTBASE_EXPORT 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...
MITKIGTBASE_EXPORT itk::Matrix< double, 3, 3 > ConvertEulerAnglesToRotationMatrix(double alpha, double beta, double gamma)