11 template <
unsigned int NDimensions>
12 MEstTransformAgregator <NDimensions>::
15 m_MEstimateFactor = 0.5;
16 m_StoppingThreshold = 1.0e-2;
17 m_EstimationBarycenter.Fill(0);
20 template <
unsigned int NDimensions>
25 return m_EstimationBarycenter;
28 template <
unsigned int NDimensions>
34 bool returnValue =
false;
47 returnValue = this->mestEstimateTranslationsToAny();
53 returnValue = this->mestEstimateAnyToAffine();
57 throw itk::ExceptionObject(__FILE__, __LINE__,
"Specific M-estimation agregation not handled yet...",ITK_LOCATION);
62 template <
unsigned int NDimensions>
65 mestEstimateTranslationsToAny()
70 throw itk::ExceptionObject(__FILE__, __LINE__,
"Dimension not supported",ITK_LOCATION);
72 std::vector <PointType> originPoints(nbPts);
73 std::vector <PointType> transformedPoints(nbPts);
80 for (
unsigned int i = 0;i < nbPts;++i)
84 PointType tmpDisp = tmpTrsf->TransformPoint(tmpOrig);
85 originPoints[i] = tmpOrig;
87 transformedPoints[i] = currTrsf->TransformPoint(tmpDisp);
89 transformedPoints[i] = tmpDisp;
92 vnl_matrix <ScalarType> covPcaOriginPoints(NDimensions, NDimensions, 0);
95 itk::Matrix<ScalarType, NDimensions, NDimensions> emptyMatrix;
104 itk::Point <ScalarType, NDimensions> unweightedBarX;
105 vnl_matrix <ScalarType> covOriginPoints(NDimensions, NDimensions, 0);
106 for (
unsigned int i = 0; i < nbPts; ++i)
108 for (
unsigned int j = 0; j < NDimensions; ++j)
109 unweightedBarX[j] += originPoints[i][j] / nbPts;
111 for (
unsigned int i = 0; i < nbPts; ++i)
113 for (
unsigned int j = 0; j < NDimensions; ++j)
115 for (
unsigned int k = 0; k < NDimensions; ++k)
116 covOriginPoints(j, k) += (originPoints[i][j] - unweightedBarX[j])*(originPoints[i][k] - unweightedBarX[k]);
119 itk::SymmetricEigenAnalysis < vnl_matrix <ScalarType>, vnl_diag_matrix<ScalarType>, vnl_matrix <ScalarType> > eigenSystem(3);
120 vnl_diag_matrix <double> eValsCov(NDimensions);
121 eigenSystem.SetOrderEigenValues(
true);
122 eigenSystem.ComputeEigenValuesAndVectors(covOriginPoints, eValsCov, covPcaOriginPoints);
124 covPcaOriginPoints = covPcaOriginPoints.transpose();
125 if (vnl_determinant(covPcaOriginPoints) < 0)
126 covPcaOriginPoints *= -1.0;
130 std::vector <double> weightsFiltered = weights;
132 std::vector < double > residualErrors;
133 std::vector < double > mestWeights(nbPts,1);
136 itk::Vector <double,3> tmpDiff;
138 bool continueLoop =
true;
139 unsigned int numMaxIter = 100;
140 unsigned int num_itr = 0;
141 double averageResidualValue = 1;
143 typename BaseOutputTransformType::Pointer resultTransform, resultTransformOld;
145 while(num_itr < numMaxIter)
152 anima::computeTranslationLSWFromTranslations<InternalScalarType,ScalarType,NDimensions>
153 (originPoints,transformedPoints,weightsFiltered,resultTransform);
157 anima::computeRigidLSWFromTranslations<InternalScalarType,ScalarType,NDimensions>
158 (originPoints,transformedPoints,weightsFiltered,resultTransform);
162 m_EstimationBarycenter = anima::computeAnisotropSimLSWFromTranslations<InternalScalarType, ScalarType, NDimensions>
163 (originPoints, transformedPoints, weightsFiltered, resultTransform, covPcaOriginPoints);
167 m_EstimationBarycenter = anima::computeAffineLSWFromTranslations<InternalScalarType,ScalarType,NDimensions>
168 (originPoints,transformedPoints,weightsFiltered,resultTransform);
172 throw itk::ExceptionObject(__FILE__, __LINE__,
"Not implemented yet...",ITK_LOCATION);
176 continueLoop = endLTSCondition(resultTransformOld,resultTransform);
181 resultTransformOld = resultTransform;
182 residualErrors.clear();
183 for (
unsigned int i = 0;i < nbPts;++i)
188 tmpOutPoint = resultTransform->TransformPoint(originPoints[i]);
189 tmpDiff = tmpOutPoint - transformedPoints[i];
190 double tmpRes = tmpDiff.GetNorm();
191 residualErrors.push_back(tmpRes * tmpRes);
197 double averageDist = 0;
198 for (
unsigned int i = 0;i < residualErrors.size();++i)
199 averageDist += residualErrors[i];
201 averageResidualValue = averageDist / residualErrors.size();
203 if (averageResidualValue <= 0)
204 averageResidualValue = 1;
207 unsigned int residualIndex = 0;
208 for (
unsigned int i = 0;i < nbPts;++i)
213 mestWeights[i] = exp(- residualErrors[residualIndex] / (averageResidualValue * m_MEstimateFactor));
217 for (
unsigned int i = 0;i < nbPts;++i)
218 weightsFiltered[i] = weights[i] * mestWeights[i];
225 template <
unsigned int NDimensions>
228 mestEstimateAnyToAffine()
231 throw itk::ExceptionObject(__FILE__, __LINE__,
"Agregation from affine transforms to rigid is not supported yet...",ITK_LOCATION);
233 typedef itk::MatrixOffsetTransformBase <InternalScalarType, NDimensions> BaseMatrixTransformType;
239 std::vector < vnl_matrix <InternalScalarType> > logTransformations(nbPts);
240 vnl_matrix <InternalScalarType> tmpMatrix(NDimensions+1,NDimensions+1,0), tmpLogMatrix(NDimensions+1,NDimensions+1,0);
241 tmpMatrix(NDimensions,NDimensions) = 1;
242 typename BaseMatrixTransformType::MatrixType affinePart;
243 itk::Vector <InternalScalarType, NDimensions> offsetPart;
245 for (
unsigned int i = 0;i < nbPts;++i)
249 BaseMatrixTransformType *tmpTrsf = (BaseMatrixTransformType *)this->
GetInputTransform(i);
250 affinePart = tmpTrsf->GetMatrix();
251 offsetPart = tmpTrsf->GetOffset();
253 for (
unsigned int j = 0;j < NDimensions;++j)
255 tmpMatrix(j,NDimensions) = offsetPart[j];
256 for (
unsigned int k = 0;k < NDimensions;++k)
257 tmpMatrix(j,k) = affinePart(j,k);
261 if (!std::isfinite(logTransformations[i](0,0)))
263 logTransformations[i].fill(0);
269 LogRigidTransformType *tmpTrsf = (LogRigidTransformType *)this->
GetInputTransform(i);
270 logTransformations[i] = tmpTrsf->GetLogTransform();
274 std::vector <InternalScalarType> weightsFiltered = weights;
277 std::vector < PointType > originPoints(nbPts);
278 std::vector < PointType > transformedPoints(nbPts);
280 for (
unsigned int i = 0;i < nbPts;++i)
284 PointType tmpDisp = tmpTrsf->TransformPoint(tmpOrig);
285 originPoints[i] = tmpOrig;
286 transformedPoints[i] = tmpDisp;
289 std::vector < double > residualErrors;
290 std::vector < double > mestWeights(nbPts,1);
292 bool continueLoop =
true;
293 unsigned int numMaxIter = 100;
294 unsigned int num_itr = 0;
295 double averageResidualValue = 1.0;
297 typename BaseOutputTransformType::Pointer resultTransform, resultTransformOld;
299 while(num_itr < numMaxIter)
303 anima::computeLogEuclideanAverage<InternalScalarType,ScalarType,NDimensions>(logTransformations,weightsFiltered,resultTransform);
304 continueLoop = endLTSCondition(resultTransformOld,resultTransform);
309 resultTransformOld = resultTransform;
310 residualErrors.clear();
312 BaseMatrixTransformType *tmpTrsf = (BaseMatrixTransformType *)resultTransform.GetPointer();
314 for (
unsigned int i = 0;i < nbPts;++i)
320 PointType tmpDisp = tmpTrsf->TransformPoint(originPoints[i]);
322 for (
unsigned int j = 0;j < NDimensions;++j)
323 tmpDiff += (transformedPoints[i][j] - tmpDisp[j]) * (transformedPoints[i][j] - tmpDisp[j]);
325 residualErrors.push_back(tmpDiff);
331 double averageDist = 0;
332 for (
unsigned int i = 0;i < residualErrors.size();++i)
333 averageDist += residualErrors[i];
335 averageResidualValue = averageDist / residualErrors.size();
337 if (averageResidualValue <= 0)
338 averageResidualValue = 1;
341 unsigned int residualIndex = 0;
342 for (
unsigned int i = 0;i < nbPts;++i)
347 mestWeights[i] = exp(- residualErrors[residualIndex] / (averageResidualValue * m_MEstimateFactor));
351 for (
unsigned int i = 0;i < nbPts;++i)
352 weightsFiltered[i] = weights[i] * mestWeights[i];
359 template <
unsigned int NDimensions>
367 typename BaseOutputTransformType::ParametersType oldParams = oldTrsf->GetParameters();
368 typename BaseOutputTransformType::ParametersType newParams = newTrsf->GetParameters();
370 for (
unsigned int i = 0;i < newParams.GetSize();++i)
372 double diffParam = fabs(newParams[i] - oldParams[i]);
373 if (diffParam > m_StoppingThreshold)
vnl_matrix< T > GetLogarithm(const vnl_matrix< T > &m, const double precision=0.00000000001, const int numApprox=1)
Computation of the matrix logarithm. Algo: inverse scaling and squaring, variant proposed by Cheng et...