70 m_SourcePoints.clear();
71 mitk::PointSet::PointType mitkSourcePoint;
72 TransformInitializerType::LandmarkPointType lPoint;
74 for (mitk::PointSet::PointsContainer::ConstIterator it = mitkSourcePointSet->GetPointSet()->GetPoints()->Begin();
75 it != mitkSourcePointSet->GetPointSet()->GetPoints()->End(); ++it)
77 mitk::FillVector3D(lPoint, it->Value().GetElement(0), it->Value().GetElement(1), it->Value().GetElement(2));
78 m_SourcePoints.push_back(lPoint);
81 if (m_SourcePoints.size() < 3)
83 itkExceptionMacro(
"SourcePointSet must contain at least 3 points");
86 if (this->IsInitialized())
87 this->InitializeLandmarkTransform(m_SourcePoints, m_TargetPoints);
93 m_TargetPoints.clear();
94 TransformInitializerType::LandmarkPointType lPoint;
95 for (mitk::PointSet::PointsContainer::ConstIterator it = mitkTargetPointSet->GetPointSet()->GetPoints()->Begin();
96 it != mitkTargetPointSet->GetPointSet()->GetPoints()->End(); ++it)
98 mitk::FillVector3D(lPoint, it->Value().GetElement(0), it->Value().GetElement(1), it->Value().GetElement(2));
99 m_TargetPoints.push_back(lPoint);
102 if (m_TargetPoints.size() < 3)
104 itkExceptionMacro(
"TargetPointSet must contain at least 3 points");
107 if (this->IsInitialized())
108 this->InitializeLandmarkTransform(m_SourcePoints, m_TargetPoints);
152 m_ErrorMin = itk::NumericTraits<mitk::ScalarType>::max();
153 m_ErrorMax = itk::NumericTraits<mitk::ScalarType>::min();
156 for (std::vector<mitk::ScalarType>::size_type i = 0; i < vector.size(); i++)
158 m_ErrorMean += vector[i];
159 m_ErrorRMS += pow(vector[i],2);
160 if(vector[i] < m_ErrorMin)
161 m_ErrorMin = vector[i];
162 if(vector[i] > m_ErrorMax)
163 m_ErrorMax = vector[i];
164 if(fabs(vector[i]) > fabs(m_ErrorAbsMax))
165 m_ErrorAbsMax = vector[i];
167 m_ErrorMean /= vector.size();
168 m_ErrorRMS = sqrt(m_ErrorRMS/vector.size());
172 for (std::vector<mitk::ScalarType>::size_type i = 0; i < vector.size(); i++)
173 m_ErrorStdDev += pow(vector[i] - m_ErrorMean, 2);
175 if(vector.size() > 1)
176 m_ErrorStdDev = sqrt(m_ErrorStdDev / (vector.size() - 1.0));
183 this->CreateOutputsForAllInputs();
185 TransformInitializerType::LandmarkPointType lPointIn, lPointOut;
188 for (
unsigned int i = 0; i < this->GetNumberOfOutputs() ; ++i)
197 output->SetDataValid(
false);
200 output->
Graft(input);
202 if (this->IsInitialized() ==
false)
206 tempCoordinate = input->GetPosition();
207 lPointIn[0] = tempCoordinate[0];
208 lPointIn[1] = tempCoordinate[1];
209 lPointIn[2] = tempCoordinate[2];
213 tempCoordinate[0] = lPointOut[0];
214 tempCoordinate[1] = lPointOut[1];
215 tempCoordinate[2] = lPointOut[2];
216 output->SetPosition(tempCoordinate);
220 vnl_quaternion<double>
const vnlQuatIn(quatIn.x(), quatIn.y(), quatIn.z(), quatIn.r());
221 m_QuatTransform->SetRotation(vnlQuatIn);
223 m_QuatLandmarkTransform->SetMatrix(m_LandmarkTransform->GetMatrix());
225 m_QuatLandmarkTransform->Compose(m_QuatTransform,
true);
227 vnl_quaternion<double> vnlQuatOut = m_QuatLandmarkTransform->GetRotation();
229 output->SetOrientation(quatOut);
230 output->SetDataValid(
true);
243 Superclass::PrintSelf(os, indent);
245 os << indent << this->GetNameOfClass() <<
":\n";
246 os << indent << m_SourcePoints.size() <<
" SourcePoints exist: \n";
247 itk::Indent nextIndent = indent.GetNextIndent();
249 for (LandmarkPointContainer::const_iterator it = m_SourcePoints.begin(); it != m_SourcePoints.end(); ++it)
251 os << nextIndent <<
"Point " << i++ <<
": [";
252 os << it->GetElement(0);
253 for (
unsigned int i = 1; i < TransformInitializerType::LandmarkPointType::GetPointDimension(); ++i)
255 os <<
", " << it->GetElement(i);
260 os << indent << m_TargetPoints.size() <<
" TargetPoints exist: \n";
262 for (LandmarkPointContainer::const_iterator it = m_TargetPoints.begin(); it != m_TargetPoints.end(); ++it)
264 os << nextIndent <<
"Point " << i++ <<
": [";
265 os << it->GetElement(0);
266 for (
unsigned int i = 1; i < TransformInitializerType::LandmarkPointType::GetPointDimension(); ++i)
268 os <<
", " << it->GetElement(i);
272 os << indent <<
"Landmarktransform initialized: " << this->IsInitialized() <<
"\n";
273 if (this->IsInitialized() ==
true)
274 m_LandmarkTransform->Print(os, nextIndent);
275 os << indent <<
"Registration error statistics:\n";
276 os << nextIndent <<
"FRE: " << this->GetFRE() <<
"\n";
277 os << nextIndent <<
"FRE std.dev.: " << this->GetFREStdDev() <<
"\n";
278 os << nextIndent <<
"FRE RMS: " << this->GetRMSError() <<
"\n";
279 os << nextIndent <<
"Minimum registration error: " << this->GetMinError() <<
"\n";
280 os << nextIndent <<
"Maximum registration error: " << this->GetMaxError() <<
"\n";
281 os << nextIndent <<
"Absolute Maximum registration error: " << this->GetAbsMaxError() <<
"\n";
293 if (sources.size() < 6 || targets.size() < 6)
298 typedef itk::PointSet<mitk::ScalarType, 3> PointSetType;
300 typedef itk::EuclideanDistancePointMetric< PointSetType, PointSetType> MetricType;
302 typedef itk::PointSetToPointSetRegistrationMethod< PointSetType, PointSetType > RegistrationType;
305 PointSetType::Pointer sourcePointSet = PointSetType::New();
307 for (LandmarkPointContainer::const_iterator it = sources.begin(); it != sources.end(); ++it)
309 PointSetType::PointType doublePoint;
310 mitk::itk2vtk(*it, doublePoint);
311 sourcePointSet->SetPoint(i++, doublePoint );
315 PointSetType::Pointer targetPointSet = PointSetType::New();
316 for (LandmarkPointContainer::const_iterator it = targets.begin(); it != targets.end(); ++it)
318 PointSetType::PointType doublePoint;
319 mitk::itk2vtk(*it, doublePoint);
320 targetPointSet->SetPoint(i++, doublePoint );
323 TransformType::Pointer transform = TransformType::New();
324 transform->SetIdentity();
326 itk::LevenbergMarquardtOptimizer::Pointer optimizer = itk::LevenbergMarquardtOptimizer::New();
327 optimizer->SetUseCostFunctionGradient(
false);
329 RegistrationType::Pointer registration = RegistrationType::New();
332 itk::LevenbergMarquardtOptimizer::ScalesType scales(transform->GetNumberOfParameters());
333 const double translationScale = 5000;
334 const double rotationScale = 1.0;
335 scales[0] = 1.0 / rotationScale;
336 scales[1] = 1.0 / rotationScale;
337 scales[2] = 1.0 / rotationScale;
338 scales[3] = 1.0 / translationScale;
339 scales[4] = 1.0 / translationScale;
340 scales[5] = 1.0 / translationScale;
342 unsigned long numberOfIterations = 80000;
343 double gradientTolerance = 1e-10;
344 double valueTolerance = 1e-10;
345 double epsilonFunction = 1e-10;
346 optimizer->SetScales( scales );
347 optimizer->SetNumberOfIterations( numberOfIterations );
348 optimizer->SetValueTolerance( valueTolerance );
349 optimizer->SetGradientTolerance( gradientTolerance );
350 optimizer->SetEpsilonFunction( epsilonFunction );
353 registration->SetInitialTransformParameters( transform->GetParameters() );
357 MetricType::Pointer metric = MetricType::New();
359 registration->SetMetric( metric );
360 registration->SetOptimizer( optimizer );
361 registration->SetTransform( transform );
362 registration->SetFixedPointSet( targetPointSet );
363 registration->SetMovingPointSet( sourcePointSet );
368 registration->Update();
370 catch( itk::ExceptionObject & e )
372 MITK_INFO <<
"Exception caught during ICP optimization: " << e;
376 MITK_INFO <<
"ICP successful: Solution = " << transform->GetParameters() << std::endl;
377 MITK_INFO <<
"Metric value: " << metric->GetValue(transform->GetParameters());
382 for (LandmarkPointContainer::const_iterator targetsIt = targets.begin(); targetsIt != targets.end(); ++targetsIt)
384 double minDistance = itk::NumericTraits<double>::max();
385 LandmarkPointContainer::iterator minDistanceIterator = sources.end();
386 for (LandmarkPointContainer::iterator sourcesIt = sources.begin(); sourcesIt != sources.end(); ++sourcesIt)
388 TransformInitializerType::LandmarkPointType transformedSource = transform->TransformPoint(*sourcesIt);
389 double dist = targetsIt->EuclideanDistanceTo(transformedSource);
390 MITK_INFO <<
"target: " << *targetsIt <<
", source: " << *sourcesIt <<
", transformed source: " << transformedSource <<
", dist: " << dist;
391 if (dist < minDistance )
393 minDistanceIterator = sourcesIt;
397 if (minDistanceIterator == sources.end())
399 MITK_INFO <<
"minimum distance point is: " << *minDistanceIterator <<
" (dist: " << targetsIt->EuclideanDistanceTo(transform->TransformPoint(*minDistanceIterator)) <<
", minDist: " << minDistance <<
")";
400 sortedSources.push_back(*minDistanceIterator);
401 sources.erase(minDistanceIterator);
404 sources = sortedSources;
414 m_LandmarkTransformInitializer->SetMovingLandmarks(targets);
415 m_LandmarkTransformInitializer->SetFixedLandmarks(sources);
416 m_LandmarkTransform->SetIdentity();
417 m_LandmarkTransformInitializer->InitializeTransform();
420 TransformInitializerType::LandmarkPointType curData;
422 for (LandmarkPointContainer::size_type index = 0; index < sources.size(); index++)
424 curData = m_LandmarkTransform->TransformPoint(sources.at(index));
425 m_Errors.push_back(curData.EuclideanDistanceTo(targets.at(index)));
427 this->AccumulateStatistics(m_Errors);
430 catch (std::exception& e)
433 m_LandmarkTransform->SetIdentity();
434 itkExceptionMacro(
"Initializing landmark-transform failed\n. " << e.what());