Ponca  4a9354998d048bf882a3ee9bac8105216fa08d13
Point Cloud Analysis library
Loading...
Searching...
No Matches
covariancePlaneFit.hpp
1/*
2 Copyright (C) 2014 Nicolas Mellado <nmellado0@gmail.com>
3 Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
4
5 This Source Code Form is subject to the terms of the Mozilla Public
6 License, v. 2.0. If a copy of the MPL was not distributed with this
7 file, You can obtain one at http://mozilla.org/MPL/2.0/.
8*/
9
10template <class DataPoint, class _NFilter, typename T>
11 requires COVARIANCE_PLANE_FIT_REQUIREMENTS
13{
14 if (Base::finalize() == STABLE)
15 {
16 if (Base::plane().isValid())
17 Base::m_eCurrentState = CONFLICT_ERROR_FOUND;
18 Base::setPlane(Base::m_solver.eigenvectors().col(0), Base::barycenterLocal());
19 }
20
21 return Base::m_eCurrentState;
22}
23
24template <class DataPoint, class _NFilter, typename T>
25 requires COVARIANCE_PLANE_FIT_REQUIREMENTS
27 DataPoint, _NFilter, T>::worldToTangentPlane(const VectorType& _q, bool _isPositionVector) const
28{
29 return Base::m_solver.eigenvectors().transpose() *
30 Base::getNeighborFrame().convertToLocalBasis(_q, _isPositionVector);
31}
32
33template <class DataPoint, class _NFilter, typename T>
34 requires COVARIANCE_PLANE_FIT_REQUIREMENTS
36 DataPoint, _NFilter, T>::tangentPlaneToWorld(const VectorType& _lq, bool _isPositionVector) const
37{
38 return Base::getNeighborFrame().convertToGlobalBasis(Base::m_solver.eigenvectors().transpose().inverse() * _lq,
40}
41
42template <class DataPoint, class _NFilter, int DiffType, typename T>
43 requires COVARIANCE_PLANE_DER_REQUIREMENTS
45{
46 PONCA_MULTIARCH_CU_STD_FUNC(numeric_limits);
47
48 Base::finalize();
49 // Test if base finalize end on a viable case (stable / unstable)
50 if (this->isReady())
51 {
52 VectorType barycenter = Base::barycenterLocal();
53 VectorArray dBarycenter = Base::barycenterDerivatives();
54
55 // pre-compute shifted eigenvalues to apply the pseudo inverse of C - lambda_0 I
56 Scalar epsilon = Scalar(2) * Eigen::NumTraits<Scalar>::epsilon();
58
59 // This is where the limitation to 3d comes from.
60 // \fixme Replace shift in 2d subspace by any subspace with co-dimension 1
61 Eigen::Matrix<Scalar, 2, 1> shifted_eivals =
62 Base::m_solver.eigenvalues().template tail<2>().array() - Base::m_solver.eigenvalues()(0);
64 shifted_eivals(0) = 0;
66 shifted_eivals(1) = 0;
67
68 for (int k = 0; k < Base::NbDerivatives; ++k)
69 {
70 VectorType normal = Base::primitiveGradient();
71 // The derivative of 'normal' is the derivative of the smallest eigenvector.
72 // Since the covariance matrix is real and symmetric, it is equal to:
73 // n' = - (C - lambda_0 I)^+ C' n
74 // Where ^+ denotes the pseudo-inverse.
75 // Since we already performed the eigenvalue decomposition of the matrix C,
76 // we can directly apply the pseudo inverse by observing that:
77 // (C - lambda_0 I) = V (L - lambda_0 I) V^T
78 // where V is the eigenvector matrix, and L the eigenvalue diagonal matrix.
79 Eigen::Matrix<Scalar, 2, 1> z =
80 -Base::m_solver.eigenvectors().template rightCols<2>().transpose() * (Base::m_dCov[k] * normal);
81 if (shifted_eivals(0) > 0)
82 z(0) /= shifted_eivals(0);
83 if (shifted_eivals(1) > 0)
84 z(1) /= shifted_eivals(1);
85 m_dNormal.col(k) = Base::m_solver.eigenvectors().template rightCols<2>() * z;
86
88 if (k > 0 || !Base::isScaleDer())
89 dDiff(Base::isScaleDer() ? k - 1 : k) += 1;
90 m_dDist(k) = m_dNormal.col(k).dot(barycenter) + normal.dot(dDiff);
91 }
92 }
93
94 return Base::m_eCurrentState;
95}
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:294
[CovariancePlaneFit Definition]
typename Base::VectorArray VectorArray
Alias to vector derivatives array.
typename Base::VectorType VectorType
Alias to vector type.
typename DataPoint::Scalar Scalar
Alias to scalar type.
Plane fitting procedure using only points position.
typename Base::VectorType VectorType
Alias to vector type.
Ponca::MeanPosition T barycenter() const
where are all the point samples in 's neighborhood
Definition mean.h:45
FIT_RESULT
Enum corresponding to the state of a fitting method (and what the finalize function returns)
Definition enums.h:15
@ CONFLICT_ERROR_FOUND
Multiple classes of the fitting procedure initialize the primitive.
Definition enums.h:27
@ STABLE
The fitting is stable and ready to use.
Definition enums.h:17