44 k{Parametrizable::get<std::size_t>(
"k")},
45 sigma{Parametrizable::get<T>(
"sigma")},
46 radius{Parametrizable::get<T>(
"radius")},
47 itMax{Parametrizable::get<std::size_t>(
"itMax")},
48 keepNormals{Parametrizable::get<bool>(
"keepNormals")},
49 keepLabels{Parametrizable::get<bool>(
"keepLabels")},
50 keepLambdas{Parametrizable::get<bool>(
"keepLambdas")},
51 keepTensors{Parametrizable::get<bool>(
"keepTensors")}
60 inPlaceFilter(output);
75 tv.cfvote(cloud,
true);
78 addDescriptor(cloud, tv,
false ,
false ,
true ,
false );
82 const std::size_t itMax_ = itMax;
83 const std::size_t k_ = k;
84 std::size_t oldnbPts = nbPts;
86 auto checkConvergence = [&oldnbPts, &it, &itMax_, &k_](
const DataPoints& pts,
const std::size_t threshold)
mutable ->
bool{
87 const std::size_t nbPts = pts.getNbPoints();
88 bool ret = (oldnbPts - nbPts) < threshold;
92 return ret or ++it >= itMax_ or k_ >= nbPts;
95 const T xi3 = xi_expectation(3, sigma, radius);
96 const T xi2 = xi_expectation(2, sigma, radius);
97 const T xi1 = xi_expectation(1, sigma, radius);
102 filterPointness(cloud, xi3, tv.k);
104 filterCurveness(cloud, xi1, tv.k);
106 filterSurfaceness(cloud, xi2, tv.k);
110 tv.cfvote(cloud,
true);
114 addDescriptor(cloud, tv,
false ,
false ,
true ,
false );
116 while(not checkConvergence(cloud, 5 ));
119 addDescriptor(cloud, tv,
false ,
false ,
false ,
true );
126 addDescriptor(cloud, tv, keepNormals,
true, keepLambdas, keepTensors);
129 removeOutlier(cloud, tv);
133 template <
typename T>
138 Matrix labels = Matrix::Zero(1, nbPts);
139 Matrix l1 = PM::Matrix::Zero(1, nbPts);
140 Matrix l2 = PM::Matrix::Zero(1, nbPts);
141 Matrix l3 = PM::Matrix::Zero(1, nbPts);
143 if(keepLabels_ or keepLambdas_)
145 #pragma omp parallel for
146 for(std::size_t i = 0; i < nbPts; ++i)
153 Vector coeff = (
Vector(3) << lambda3, (lambda2 - lambda3), (lambda1 - lambda2)).finished();
154 coeff.maxCoeff(&index);
156 labels(i) = index + 1 ;
193 std::cerr <<
"SpectralDecomposition<T>::inPlaceFilter::addDescriptor: Cannot add descriptors to pointcloud" << std::endl;
202 template <
typename T>
205 static constexpr
int POINT = 0;
206 static constexpr
int CURVE = 1;
207 static constexpr
int SURFACE = 2;
209 static constexpr
T th = 0.1;
219 for (std::size_t i = 0; i < nbPts; ++i)
226 (
Vector(3) << pointness, curveness, surfaceness).finished().maxCoeff(&label);
228 bool keepPt = ((label == POINT) and (pointness >= th_p))
229 or ((label == CURVE) and (curveness >= th_c))
230 or ((label == SURFACE) and (surfaceness >= th_s));
244 template <
typename T>
247 constexpr std::size_t seed = 1;
248 std::mt19937 gen(seed);
249 std::uniform_real_distribution<> uni01(0., 1.);
256 throw InvalidField(
"SpectralDecomposition<T>::filter: Error, lambdas field not found in descriptors.");
264 for (std::size_t i = 0; i < nbPts; ++i)
266 const T randv = uni01(gen);
268 const T nl1 = lambda1(0,i) / k;
269 const T nl2 = lambda2(0,i) / k;
270 const T nl3 = lambda3(0,i) / k;
272 if (nl1 < xi or nl2 < 0.75 * xi or nl3 < 0.75 * xi or randv < 0.5)
281 template <
typename T>
284 constexpr std::size_t seed = 1;
285 std::mt19937 gen(seed);
286 std::uniform_real_distribution<> uni01(0., 1.);
293 throw InvalidField(
"SpectralDecomposition<T>::filter: Error, lambdas field not found in descriptors.");
301 for (std::size_t i = 0; i < nbPts; ++i)
303 const T randv = uni01(gen);
305 const T nl1 = lambda1(0,i) / k;
306 const T nl2 = lambda2(0,i) / k;
307 const T nl3 = lambda3(0,i) / k;
309 if (nl1 < xi or nl2 < xi or nl3 < 0.5 * xi or randv < 0.5)
318 template <
typename T>
321 constexpr std::size_t seed = 1;
322 std::mt19937 gen(seed);
323 std::uniform_real_distribution<> uni01(0., 1.);
330 throw InvalidField(
"SpectralDecomposition<T>::filter: Error, lambdas field not found in descriptors.");
338 for (std::size_t i = 0; i < nbPts; ++i)
340 const T randv = uni01(gen);
342 const T nl1 = lambda1(0,i) / k;
343 const T nl2 = lambda2(0,i) / k;
344 const T nl3 = lambda3(0,i) / k;
346 if (nl1 < (5./6.) * xi or nl2 < (5./6.) * xi or nl3 < (5./6.) * xi or randv < 0.2)