7 #include "PlusConfigure.h" 12 #include "itkLandmarkBasedTransformInitializer.h" 15 #include "vtkObjectFactory.h" 16 #include "vtkIGSIOTransformRepository.h" 17 #include "vtkXMLUtilities.h" 40 vtkSmartPointer<vtkPoints> definedLandmarks = vtkSmartPointer<vtkPoints>::New();
43 vtkSmartPointer<vtkPoints> recordedLandmarks = vtkSmartPointer<vtkPoints>::New();
63 LOG_TRACE(
"vtkPlusPhantomLandmarkRegistrationAlgo::Register" );
66 std::vector< itk::Point<double, 3> > fixedPoints;
67 std::vector< itk::Point<double, 3> > movingPoints;
73 itk::Point<double, 3> fixedPoint( fixedPointArray );
77 itk::Point<double, 3> movingPoint( movingPointArray );
79 fixedPoints.push_back( fixedPoint );
80 movingPoints.push_back( movingPoint );
85 LOG_DEBUG(
"Phantom point " <<
i <<
": Defined: " << fixedPoints[
i] <<
" Recorded: " << movingPoints[
i] );
89 auto transform = itk::VersorRigid3DTransform<double>::New();
90 transform->SetIdentity();
92 auto initializer = itk::LandmarkBasedTransformInitializer< itk::VersorRigid3DTransform<double>, itk::Image<short, 3>, itk::Image<short, 3> >
::New();
93 initializer->SetTransform( transform );
94 initializer->SetFixedLandmarks( fixedPoints );
95 initializer->SetMovingLandmarks( movingPoints );
96 initializer->InitializeTransform();
99 vtkSmartPointer<vtkMatrix4x4> phantomToReferenceTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
100 phantomToReferenceTransformMatrix->Identity();
102 itk::Matrix<double, 3, 3> transformMatrix = transform->GetMatrix();
103 for (
int i = 0;
i < transformMatrix.RowDimensions; ++
i )
105 for (
int j = 0; j < transformMatrix.ColumnDimensions; ++j )
107 phantomToReferenceTransformMatrix->SetElement(
i, j, transformMatrix[
i][j] );
110 itk::Vector<double, 3> transformOffset = transform->GetOffset();
111 for (
unsigned int j = 0; j < transformOffset.GetNumberOfComponents(); ++j )
113 phantomToReferenceTransformMatrix->SetElement( j, 3, transformOffset[j] );
116 std::ostringstream osPhantomToReferenceTransformMatrix;
117 phantomToReferenceTransformMatrix->Print( osPhantomToReferenceTransformMatrix );
119 LOG_DEBUG(
"PhantomToReferenceTransformMatrix:\n" << osPhantomToReferenceTransformMatrix.str().c_str() );
125 LOG_ERROR(
"Failed to compute registration error!" );
130 if ( aTransformRepository )
134 aTransformRepository->SetTransformPersistent( phantomToReferenceTransformName,
true );
135 aTransformRepository->SetTransformDate( phantomToReferenceTransformName, vtkIGSIOAccurateTimer::GetInstance()->GetDateAndTimeString().c_str() );
136 aTransformRepository->SetTransformError( phantomToReferenceTransformName, this->
RegistrationErrorMm );
140 LOG_INFO(
"Transform repository object is NULL, cannot save results into it" );
151 LOG_TRACE(
"vtkPlusPhantomLandmarkRegistrationAlgo::ReadConfiguration" );
153 XML_FIND_NESTED_ELEMENT_REQUIRED( phantomDefinition, aConfig,
"PhantomDefinition" );
160 XML_FIND_NESTED_ELEMENT_REQUIRED( geometry, phantomDefinition,
"Geometry" );
163 vtkXMLDataElement* landmarks = geometry->FindNestedElementWithName(
"Landmarks" );
164 if ( landmarks == NULL )
166 if( geometry->FindNestedElementWithName(
"Planes" ) == NULL )
168 LOG_ERROR(
"No Planes or Landmarks found in configuration file found, registration is not possible!" );
173 LOG_WARNING(
"No Landmarks found in configuration file found, perform Landmark Registration" );
179 int numberOfLandmarks = landmarks->GetNumberOfNestedElements();
182 for (
int i = 0;
i < numberOfLandmarks; ++
i )
184 vtkXMLDataElement* landmark = landmarks->GetNestedElement(
i );
185 if ( ( landmark == NULL ) || ( STRCASECMP(
"Landmark", landmark->GetName() ) ) )
187 LOG_WARNING(
"Invalid landmark definition found" );
191 const char* landmarkName = landmark->GetAttribute(
"Name" );
192 if ( landmarkName == NULL )
194 LOG_WARNING(
"Invalid landmark name (landmark #" <<
i + 1 <<
")" );
198 double landmarkPosition[4] = {0, 0, 0, 1};
199 if ( ! landmark->GetVectorAttribute(
"Position", 3, landmarkPosition ) )
201 LOG_WARNING(
"Invalid landmark position (landmark #" <<
i + 1 <<
")" );
212 LOG_ERROR(
"No valid landmarks were found!" );
228 LOG_TRACE(
"vtkPlusPhantomLandmarkRegistrationAlgo::ComputeError" );
230 double sumDistance = 0.0;
235 double definedLandmark_Phantom[4] = {0, 0, 0, 1.0};
253 double referencePointArray_Phantom[4] = {0, 0, 0, 1};
254 double otherPointArray_Phantom[4] = {0, 0, 0, 1};
255 double minimumDistanceMm = DBL_MAX;
264 double distanceMm = sqrt( vtkMath::Distance2BetweenPoints( referencePointArray_Phantom, otherPointArray_Phantom ) );
265 if( distanceMm < minimumDistanceMm )
267 minimumDistanceMm = distanceMm;
271 return minimumDistanceMm;
278 double landmarksAverage_Phantom[4] = {0, 0, 0, 1};
282 landmarksAverage_Reference[0] = tempPtr[0];
283 landmarksAverage_Reference[1] = tempPtr[1];
284 landmarksAverage_Reference[2] = tempPtr[2];
291 double definedLandmarkPoint_Phantom[4] = {0, 0, 0, 1};
293 for (
int landmarkIndex = 0; landmarkIndex < numberOfLandmarks; landmarkIndex++ )
296 landmarksCentroid_Phantom[0] += definedLandmarkPoint_Phantom[0];
297 landmarksCentroid_Phantom[1] += definedLandmarkPoint_Phantom[1];
298 landmarksCentroid_Phantom[2] += definedLandmarkPoint_Phantom[2];
300 landmarksCentroid_Phantom[0] = landmarksCentroid_Phantom[0] / numberOfLandmarks;
301 landmarksCentroid_Phantom[1] = landmarksCentroid_Phantom[1] / numberOfLandmarks;
302 landmarksCentroid_Phantom[2] = landmarksCentroid_Phantom[2] / numberOfLandmarks;
310 double centroid_Phantom[4] = {0, 0, 0, 1};
311 double viewNormalVector_Reference[4] = {0, 0, 0, 1};
314 viewNormalVector_Reference[0] = cameraPosition_Reference[0] - centroid_Phantom[0];
315 viewNormalVector_Reference[1] = cameraPosition_Reference[1] - centroid_Phantom[1];
316 viewNormalVector_Reference[2] = cameraPosition_Reference[2] - centroid_Phantom[2];
318 vtkMath::Normalize( viewNormalVector_Reference );
319 const double CAMERA_DISTANCE_FROM_CENTROID = 500;
320 centroid_Phantom[0] = centroid_Phantom[0] + CAMERA_DISTANCE_FROM_CENTROID * viewNormalVector_Reference[0];
321 centroid_Phantom[1] = centroid_Phantom[1] + CAMERA_DISTANCE_FROM_CENTROID * viewNormalVector_Reference[1];
322 centroid_Phantom[2] = centroid_Phantom[2] + CAMERA_DISTANCE_FROM_CENTROID * viewNormalVector_Reference[2];
326 cameraPosition_Reference[0] = tempPtr[0];
327 cameraPosition_Reference[1] = tempPtr[1];
328 cameraPosition_Reference[2] = tempPtr[2];
338 cameraPosition_Reference[0] = tempPtr[0];
339 cameraPosition_Reference[1] = tempPtr[1];
340 cameraPosition_Reference[2] = tempPtr[2];
347 double recordedLandmarkPoint_Phantom[4] = {0, 0, 0, 1};
350 vtkSmartPointer<vtkMatrix4x4> referenceToPhantomTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
353 for (
int landmarkIndex = 0; landmarkIndex < numberOfLandmarks; landmarkIndex++ )
357 tempPtr = referenceToPhantomTransformMatrix->MultiplyDoublePoint( recordedLandmarkPoint_Phantom );
358 LOG_INFO(
"RecordedLandmark_Phantom " << landmarkIndex <<
" (" << tempPtr[0] <<
", " << tempPtr[1] <<
", " << tempPtr[2] <<
")" );
void GetDefinedLandmark_Reference(int index, double cameraPosition_Reference[4])
void PrintRecordedLandmarks_Phantom()
char * ReferenceCoordinateFrame
virtual void SetRecordedLandmarks_Reference(vtkPoints *)
double GetMinimunDistanceBetweenTwoLandmarksMm()
virtual void SetDefinedLandmarks_Phantom(vtkPoints *)
double RegistrationErrorMm
static vtkPlusPhantomLandmarkRegistrationAlgo * New()
vtkPoints * DefinedLandmarks_Phantom
PlusStatus ComputeError()
PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
vtkStandardNewMacro(vtkPlusPhantomLandmarkRegistrationAlgo)
void GetLandmarkCameraPosition_Reference(int index, double cameraPosition_Reference[4])
char * PhantomCoordinateFrame
vtkPoints * RecordedLandmarks_Reference
static std::string ConfigurationElementName
void GetDefinedLandmarksCentroid_Reference(double landmarksAverage_Reference[4])
Landmark registration to determine the Phantom pose relative to the attached marker (PhantomReference...
virtual ~vtkPlusPhantomLandmarkRegistrationAlgo()
vtkMatrix4x4 * PhantomToReferenceTransformMatrix
PlusStatus LandmarkRegister(vtkIGSIOTransformRepository *aTransformRepository=NULL)
vtkPlusPhantomLandmarkRegistrationAlgo()
std::vector< std::string > DefinedLandmarkNames
void GetDefinedLandmarksCentroid_Phantom(double landmarksCentroid_Phantom[4])
virtual void SetPhantomToReferenceTransformMatrix(vtkMatrix4x4 *)
char * StylusTipCoordinateFrame