24 #include <vtkIdList.h>
25 #include <vtkKdTree.h>
26 #include <vtkKdTreePointLocator.h>
27 #include <vtkPoints.h>
28 #include <vtkPolyData.h>
37 typedef std::pair<unsigned int, double> Correspondence;
39 bool operator()(
const Correspondence &a,
const Correspondence &b) {
return (a.second < b.second); }
43 : m_MaxIterations(1000),
44 m_Threshold(0.000001),
45 m_FRENormalizationFactor(1.0),
47 m_MaxIterationsInWeightedPointTransform(1000),
50 m_NumberOfIterations(0),
51 m_MovingSurface(nullptr),
52 m_FixedSurface(nullptr),
63 vtkKdTreePointLocator *Y,
70 typedef itk::Matrix<double, 3, 3> WeightMatrix;
72 #pragma omp parallel for
73 for (vtkIdType i = 0; i < X->GetNumberOfPoints(); ++i)
75 vtkIdType bestIdx = 0;
90 while (ids->GetNumberOfIds() <= 0)
92 Y->FindPointsWithinRadius(r, p, ids);
98 for (vtkIdType j = 0; j < ids->GetNumberOfIds(); ++j)
101 const vtkIdType
id = ids->GetId(j);
105 Y->GetDataSet()->GetPoint(
id, p);
114 const double dist = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
124 Y->GetDataSet()->GetPoint(bestIdx, p);
126 sigma_Z[i] = sigma_Y[bestIdx];
128 Correspondence _pair(i, bestDist);
129 correspondences[i] = _pair;
138 unsigned int numberOfTrimmedPoints = 0;
164 Y->SetDataSet(m_FixedSurface->GetVtkPolyData());
169 X->DeepCopy(m_MovingSurface->GetVtkPolyData()->GetPoints());
171 Z->SetNumberOfPoints(X->GetNumberOfPoints());
173 Sigma_Z.resize(X->GetNumberOfPoints());
174 distanceList.resize(X->GetNumberOfPoints());
175 RotationNew.SetIdentity();
176 TranslationNew.Fill(0.0);
180 m_Rotation.SetIdentity();
181 m_Translation.Fill(0.0);
185 if (m_TrimmFactor > 0.0)
187 numberOfTrimmedPoints = X->GetNumberOfPoints() * m_TrimmFactor;
192 Sigma_Z_sorted.resize(numberOfTrimmedPoints);
193 Sigma_X_sorted.resize(numberOfTrimmedPoints);
194 X_sorted->SetNumberOfPoints(numberOfTrimmedPoints);
195 Z_sorted->SetNumberOfPoints(numberOfTrimmedPoints);
198 unsigned int steps = m_MaxIterations;
199 unsigned int stepSize = m_MaxIterations / 10;
205 double currSearchRadius = m_SearchRadius;
206 unsigned int radiusDoubled = 0;
215 ComputeCorrespondences(X, Z, Y, Sigma_X, Sigma_Y, Sigma_Z, distanceList, currSearchRadius);
225 if (m_TrimmFactor > 0.0)
227 std::sort(distanceList.begin(), distanceList.end(),
AICPComp);
229 for (
unsigned int i = 0; i < numberOfTrimmedPoints; ++i)
231 const int idx = distanceList[i].first;
232 Sigma_Z_sorted[i] = Sigma_Z[idx];
233 Sigma_X_sorted[i] = Sigma_X[idx];
234 Z_sorted->SetPoint(i, Z->GetPoint(idx));
235 X_sorted->SetPoint(i, X->GetPoint(idx));
240 Sigma_X_k = &Sigma_X_sorted;
241 Sigma_Z_k = &Sigma_Z_sorted;
246 m_WeightedPointTransform->SetMovingPointSet(X_k);
247 m_WeightedPointTransform->SetFixedPointSet(Z_k);
248 m_WeightedPointTransform->SetCovarianceMatricesMoving(*Sigma_X_k);
249 m_WeightedPointTransform->SetCovarianceMatricesFixed(*Sigma_Z_k);
250 m_WeightedPointTransform->SetMaxIterations(m_MaxIterationsInWeightedPointTransform);
251 m_WeightedPointTransform->SetFRENormalizationFactor(m_FRENormalizationFactor);
254 m_WeightedPointTransform->ComputeTransformation();
256 RotationNew = m_WeightedPointTransform->GetTransformR();
257 TranslationNew = m_WeightedPointTransform->GetTransformT();
258 FRE_new = m_WeightedPointTransform->GetFRE();
262 currSearchRadius *= 2.0;
265 if (radiusDoubled >= 20)
267 mitkThrow() <<
"Radius doubled 20 times, preventing endless loop, check input and search radius";
271 diff = m_FRE - FRE_new;
273 }
while (diff < -1.0e-3);
275 MITK_DEBUG <<
"FRE:" << m_FRE <<
", FRE_new: " << FRE_new;
281 m_Rotation = RotationNew * m_Rotation;
282 m_Translation = RotationNew * m_Translation + TranslationNew;
291 stepSize = (k % 2 == 0) ? stepSize / 2 : stepSize;
292 stepSize = (stepSize == 0) ? 1 : stepSize;
295 }
while (diff > m_Threshold && k < m_MaxIterations);
297 m_NumberOfIterations = k;
AnisotropicIterativeClosestPointRegistration()
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
CovarianceMatrix Rotation
void ComputeCorrespondences(vtkPoints *X, vtkPoints *Z, vtkKdTreePointLocator *Y, const CovarianceMatrixList &sigma_X, const CovarianceMatrixList &sigma_Y, CovarianceMatrixList &sigma_Z, CorrespondenceList &correspondences, const double radius)
DataCollection - Class to facilitate loading/accessing structured data.
std::vector< CovarianceMatrix > CovarianceMatrixList
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
struct AICPComperator AICPComp
static void PropagateMatrices(const MatrixList &src, MatrixList &dst, const Rotation &rotation)
Propagate a list of matrices with a rotation matrix.
std::vector< Correspondence > CorrespondenceList
void AddStepsToDo(unsigned int steps)
Adds steps to totalSteps.
static void TransformPoints(vtkPoints *src, vtkPoints *dst, const Rotation &rotation, const Translation &translation)
Transforms a point cloud with a Rotation and Translation.
static WeightMatrix CalculateWeightMatrix(const CovarianceMatrix &sigma_X, const CovarianceMatrix &sigma_Y)
Method that computes a WeightMatrix with two CovarianceMatrices.
~AnisotropicIterativeClosestPointRegistration()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.