MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkFloatingImageToUltrasoundRegistrationFilter.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 <itkScalableAffineTransform.h>
15#include <itkScalableAffineTransform.hxx>
16
17
20 m_Segmentation(nullptr),
21 m_TransformMarkerCSToSensorCS(mitk::AffineTransform3D::New()),
22 m_TransformMarkerCSToFloatingImageCS(mitk::AffineTransform3D::New()),
23 m_TransformUSimageCSToTrackingCS(mitk::AffineTransform3D::New()),
24 m_TransformCTimageIndexToWorld(mitk::AffineTransform3D::New()),
25 m_TrackedUltrasoundActive(false)
26{
27 m_SurfaceGeometry = mitk::Geometry3D::New();
28 m_PointSet = nullptr;
29 m_CTimage = mitk::Image::New();
30}
31
35
37{
38 //The following calculations are related to the 3mm | 15mm fiducial configuration
39
40 m_TransformMarkerCSToSensorCS = mitk::AffineTransform3D::New();
41
42 if (useNdiTracker) // Use the NDI disc tracker for performing the CT-to-US registration:
43 {
44 MITK_INFO << "Use NDI disc tracker for performing the CT-to-US-registration";
45 mitk::Vector3D translationNDI;
46 translationNDI[0] = 15.000;
47 translationNDI[1] = 8.000;
48 translationNDI[2] = -2.500; // use -2.500 instead of 0.000 for the z translation if working with v2 of the
49 // sensor adapter.
50
51 m_TransformMarkerCSToSensorCS->SetOffset(translationNDI);
52
53 // Quaternion (x, y, z, r) --> n = (0,0,1) --> q(0,0,sin(90°),cos(90°))
54 mitk::Quaternion qNDI(0, 0, 1, 0); // corresponding to a rotation of 180° around the normal z-axis.
55 // .transpose() is needed for changing the rows and the columns of the returned rotation_matrix_transpose
56 vnl_matrix_fixed<double, 3, 3> vnl_rotation = qNDI.rotation_matrix_transpose().transpose(); // :-)
57 mitk::Matrix3D rotationMatrix;
58
59 for (int i = 0; i < 3; ++i) {
60 for (int j = 0; j < 3; ++j) {
61 rotationMatrix[i][j] = vnl_rotation[i][j];
62 }
63 }
64
65 m_TransformMarkerCSToSensorCS->SetMatrix(rotationMatrix);
66 }
67 else // Use the polhemus RX2 tracker for performing the CT-to-US registration:
68 {
69 MITK_INFO << "Use Polhemus RX2 tracker for performing the CT-to-US-registration";
70 mitk::Vector3D translationPolhemus;
71 translationPolhemus[0] = -18.175;
72 translationPolhemus[1] = 15.000;
73 translationPolhemus[2] = 10.501; // considering a distance from the base plate of 0.315 inch and not 0.313 inch
74 // use 10.501 instead of 8.001 for the z translation if working with v2 of the
75 // sensor adapter.
76
77 m_TransformMarkerCSToSensorCS->SetOffset(translationPolhemus);
78
79 // Quaternion (x, y, z, r) --> n = (1,0,0) --> q(sin(90°),0,0,cos(90°))
80 mitk::Quaternion q1(1, 0, 0, 0); // corresponding to a rotation of 180° around the normal x-axis.
81 // .transpose() is needed for changing the rows and the columns of the returned rotation_matrix_transpose
82 vnl_matrix_fixed<double, 3, 3> vnl_rotation = q1.rotation_matrix_transpose().transpose(); // :-)
83 mitk::Matrix3D rotationMatrix;
84
85 for (int i = 0; i < 3; ++i) {
86 for (int j = 0; j < 3; ++j) {
87 rotationMatrix[i][j] = vnl_rotation[i][j];
88 }
89 }
90
91 m_TransformMarkerCSToSensorCS->SetMatrix(rotationMatrix);
92 }
93 //The transformation from the sensor-CS to the marker-CS is calculated now.
94}
95
96void mitk::FloatingImageToUltrasoundRegistrationFilter::SetSegmentation(mitk::DataNode::Pointer segmentationNode, mitk::Image::Pointer ctimage)
97{
98 m_Segmentation = segmentationNode;
99 m_TransformCTimageIndexToWorld = m_Segmentation->GetData()->GetGeometry()->GetIndexToWorldTransform();
100 m_CTimage = ctimage;
101}
102
104{
105 m_Surface = surfaceNode;
106 m_SurfaceGeometry = m_Surface->GetData()->GetGeometry();
107}
108
110{
111 m_PointSet = pointSetNode;
112}
113
115{
116 m_TransformMarkerCSToFloatingImageCS = transform;
117}
118
120{
121 m_TransformUSimageCSToTrackingCS = transform;
122}
123
125{
126 Superclass::GenerateData();
127
128 if (m_TrackedUltrasoundActive)
129 {
130 MITK_WARN << "The CT-to-US-registration is not supported by tracked ultrasound, yet.";
131 return;
132 }
133
134 //IMPORTANT --- Hard coded --- First device = EM-Sensor | eventually second device = needle
135 mitk::NavigationData::Pointer transformSensorCSToTracking = this->GetOutput(0);
136
137 // cancel, if the EM-sensor is currently not being tracked
138 if (!transformSensorCSToTracking->IsDataValid())
139 {
140 return;
141 }
142
143 //We start the transformation with a new transform:
144 mitk::AffineTransform3D::Pointer totalTransformation = mitk::AffineTransform3D::New();
145 totalTransformation->SetIdentity();
146 //Compose it with the inverse transform of marker-CS to floating image-CS:
147 totalTransformation->Compose(this->GetInverseTransform(m_TransformMarkerCSToFloatingImageCS));
148 //Compose this with the inverse transform of EM-sensor-CS to marker-CS:
149 totalTransformation->Compose(m_TransformMarkerCSToSensorCS);
150 //Compose this with the transform of the sensor-CS to Tracking-CS:
151 totalTransformation->Compose(transformSensorCSToTracking->GetAffineTransform3D());
152 //Compose this with the inverse transform of USimage-CS to tracking-CS:
153 totalTransformation->Modified();
154
155 //Finally, set the total transformation (from floatingImage-CS to US-image-CS
156 // to the selected floatingImageSurface:
157
158 //m_Segmentation->GetData()->GetGeometry()->SetIndexToWorldTransform(totalTransformation);
159 //m_Segmentation->Modified();
160
161 //m_CTimage->GetGeometry()->SetIndexToWorldTransform(totalTransformation);
162 //m_CTimage->Modified();
163
164 m_Surface->GetData()->GetGeometry()->SetIndexToWorldTransform(totalTransformation);
165 m_Surface->Modified();
166
167 m_PointSet->GetData()->GetGeometry()->SetIndexToWorldTransform(totalTransformation);
168 m_PointSet->Modified();
169}
170
171mitk::AffineTransform3D::Pointer mitk::FloatingImageToUltrasoundRegistrationFilter::GetInverseTransform(mitk::AffineTransform3D::Pointer transform)
172{
173 mitk::AffineTransform3D::Pointer inverseTransform = mitk::AffineTransform3D::New();
174 mitk::AffineTransform3D::Pointer inverse = dynamic_cast<mitk::AffineTransform3D*>(transform->GetInverseTransform().GetPointer());
175
176 //itk::SmartPointer<itk::ScalableAffineTransform<mitk::ScalarType, 3U>> inverse = dynamic_cast<itk::ScalableAffineTransform<mitk::ScalarType, 3U>*> (transform->GetInverseTransform().GetPointer()); //itkScalableAffineTransform_hxx
177
178 if (inverse.IsNull())
179 {
180 MITK_WARN << "Could not get inverse transform of mitk::AffineTransform3D. Returning nullptr";
181 return nullptr;
182 }
183
184 inverseTransform->SetOffset(inverse->GetOffset());
185 inverseTransform->SetMatrix(inverse->GetMatrix());
186
187 return inverseTransform;
188}
void SetTransformUSimageCSToTrackingCS(mitk::AffineTransform3D::Pointer transform)
void SetSegmentation(mitk::DataNode::Pointer segmentationNode, mitk::Image::Pointer ctimage)
void SetTransformMarkerCSToFloatingImageCS(mitk::AffineTransform3D::Pointer transform)
mitk::AffineTransform3D::Pointer GetInverseTransform(mitk::AffineTransform3D::Pointer transform)
Basis for filters that want to leave the navigation data untouched.
IGT Exceptions.