DataFilters.cpp
Go to the documentation of this file.
1 #include "../utest.h"
2 #include <ciso646>
3 #include <cmath>
4 #include <cstdint>
6 
7 using namespace std;
8 using namespace PointMatcherSupport;
9 
10 //---------------------------
11 // DataFilter modules
12 //---------------------------
13 
14 // Utility classes
16 {
17 public:
18  // Will be called for every tests
19  virtual void SetUp()
20  {
21  icp.setDefault();
22  // Uncomment for console outputs
23  //setLogger(PM::get().LoggerRegistrar.create("FileLogger"));
24 
25  // We'll test the filters on reading point cloud
26  icp.readingDataPointsFilters.clear();
27  }
28 
29  // Will be called for every tests
30  virtual void TearDown() {}
31 
33  {
34  std::shared_ptr<PM::DataPointsFilter> testedDataPointFilter =
35  PM::get().DataPointsFilterRegistrar.create(name, params);
36 
37  icp.readingDataPointsFilters.push_back(testedDataPointFilter);
38  }
39 
40  void addFilter(string name)
41  {
42  std::shared_ptr<PM::DataPointsFilter> testedDataPointFilter =
43  PM::get().DataPointsFilterRegistrar.create(name);
44 
45  icp.readingDataPointsFilters.push_back(testedDataPointFilter);
46  }
47 
48  DP generateRandomDataPoints(int nbPoints = 100)
49  {
50  const int dimFeatures = 4;
51  const int dimDescriptors = 3;
52  const int dimTime = 2;
53 
54  PM::Matrix randFeat = PM::Matrix::Random(dimFeatures, nbPoints);
55  DP::Labels featLabels;
56  featLabels.push_back(DP::Label("x", 1));
57  featLabels.push_back(DP::Label("y", 1));
58  featLabels.push_back(DP::Label("z", 1));
59  featLabels.push_back(DP::Label("pad", 1));
60 
61  PM::Matrix randDesc = PM::Matrix::Random(dimDescriptors, nbPoints);
62  DP::Labels descLabels;
63  descLabels.push_back(DP::Label("dummyDesc", 3));
64 
65  PM::Int64Matrix randTimes = PM::Int64Matrix::Random(dimTime, nbPoints);
66  DP::Labels timeLabels;
67  timeLabels.push_back(DP::Label("dummyTime", 2));
68 
69  // Construct the point cloud from the generated matrices
70  DP pointCloud = DP(randFeat, featLabels, randDesc, descLabels, randTimes, timeLabels);
71 
72  return pointCloud;
73  }
74 
75  DP validateAngleLimitFilter(const DP& cloud, double thetaMin, double thetaMax, double phiMin, double phiMax, bool removeInside)
76  {
77  const int nbRows = cloud.features.rows();
79  params["thetaMin"] = toParam(thetaMin);
80  params["thetaMax"] = toParam(thetaMax);
81  params["phiMin"] = toParam(phiMin);
82  params["phiMax"] = toParam(phiMax);
83  params["removeInside"] = toParam(removeInside);
84 
85  std::shared_ptr<PM::DataPointsFilter> angleLimitFilter = PM::get().DataPointsFilterRegistrar.create("AngleLimitDataPointsFilter", params);
86  const DP filteredCloud = angleLimitFilter->filter(cloud);
87 
88  EXPECT_GE(cloud.getNbPoints(), filteredCloud.getNbPoints());
89  EXPECT_EQ(cloud.getDescriptorDim(), filteredCloud.getDescriptorDim());
90  EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());
91 
92  for (unsigned i = 0; i < filteredCloud.getNbPoints(); ++i)
93  {
94  const Eigen::Vector3d point = filteredCloud.features.col(i).head(3);
95  NumericType r = point.norm();
96  NumericType r_plane = point.head(nbRows-2).norm();
97  NumericType theta = PointMatcherSupport::radToDeg(acos(point(nbRows-2) / r));
98  NumericType phi = PointMatcherSupport::radToDeg(acos(point(0) / r_plane));
99 
100  if (point(1) < 0)
101  phi = -phi;
102  if (removeInside)
103  {
104  EXPECT_TRUE(theta < thetaMin || theta > thetaMax || phi < phiMin || phi > phiMax);
105  }
106  else
107  {
108  EXPECT_GE(theta, thetaMin);
109  EXPECT_LE(theta, thetaMax);
110  EXPECT_GE(phi, phiMin);
111  EXPECT_LE(phi, phiMax);
112  }
113  }
114  return filteredCloud;
115  }
116 };
117 
119 {
120  // build test cloud
121  DP ref2DCopy(ref2D);
122 
123  // apply and checked
124  addFilter("IdentityDataPointsFilter");
125  icp.readingDataPointsFilters.apply(ref2DCopy);
126  EXPECT_TRUE(ref2D == ref2DCopy);
127 }
128 
130 {
131  // build test cloud
132  DP ref2DCopy(ref2D);
133  int goodCount(0);
134  const NumericType nan(std::numeric_limits<NumericType>::quiet_NaN());
135  for (int i(0); i < ref2DCopy.features.cols(); ++i)
136  {
137  if (rand() % 3 == 0)
138  {
139  ref2DCopy.features(rand() % ref2DCopy.features.rows(), i) = nan;
140  }
141  else
142  ++goodCount;
143  }
144 
145  // apply and checked
146  addFilter("RemoveNaNDataPointsFilter");
147  icp.readingDataPointsFilters.apply(ref2DCopy);
148  EXPECT_TRUE(ref2DCopy.features.cols() == goodCount);
149 }
150 
152 {
153  // Max dist has been selected to not affect the points
155  params["dim"] = "0";
156  params["maxDist"] = toParam(6.0);
157 
158  // Filter on x axis
159  params["dim"] = "0";
160  icp.readingDataPointsFilters.clear();
161  addFilter("MaxDistDataPointsFilter", params);
162  validate2dTransformation();
163  validate3dTransformation();
164 
165  // Filter on y axis
166  params["dim"] = "1";
167  icp.readingDataPointsFilters.clear();
168  addFilter("MaxDistDataPointsFilter", params);
169  validate2dTransformation();
170  validate3dTransformation();
171 
172  // Filter on z axis (not existing)
173  params["dim"] = "2";
174  icp.readingDataPointsFilters.clear();
175  addFilter("MaxDistDataPointsFilter", params);
176  EXPECT_ANY_THROW(validate2dTransformation());
177  validate3dTransformation();
178 
179  // Filter on a radius
180  params["dim"] = "-1";
181  icp.readingDataPointsFilters.clear();
182  addFilter("MaxDistDataPointsFilter", params);
183  validate2dTransformation();
184  validate3dTransformation();
185 
186  // Parameter outside valid range
187  params["dim"] = "3";
188  //TODO: specify the exception, move that to GenericTest
189  EXPECT_ANY_THROW(addFilter("MaxDistDataPointsFilter", params));
190 
191 }
192 
194 {
195  // Min dist has been selected to not affect the points too much
197  params["dim"] = "0";
198  params["minDist"] = toParam(0.05);
199 
200  // Filter on x axis
201  params["dim"] = "0";
202  icp.readingDataPointsFilters.clear();
203  addFilter("MinDistDataPointsFilter", params);
204  validate2dTransformation();
205  validate3dTransformation();
206 
207  // Filter on y axis
208  params["dim"] = "1";
209  icp.readingDataPointsFilters.clear();
210  addFilter("MinDistDataPointsFilter", params);
211  validate2dTransformation();
212  validate3dTransformation();
213 
214  //TODO: move that to specific 2D test
215  // Filter on z axis (not existing)
216  params["dim"] = "2";
217  icp.readingDataPointsFilters.clear();
218  addFilter("MinDistDataPointsFilter", params);
219  EXPECT_ANY_THROW(validate2dTransformation());
220  validate3dTransformation();
221 
222  // Filter on a radius
223  params["dim"] = "-1";
224  icp.readingDataPointsFilters.clear();
225  addFilter("MinDistDataPointsFilter", params);
226  validate2dTransformation();
227  validate3dTransformation();
228 
229 }
230 
232 {
233  // Ratio has been selected to not affect the points too much
234  string ratio = "0.95";
236  params["dim"] = "0";
237  params["ratio"] = ratio;
238 
239  // Filter on x axis
240  params["dim"] = "0";
241  icp.readingDataPointsFilters.clear();
242  addFilter("MaxQuantileOnAxisDataPointsFilter", params);
243  validate2dTransformation();
244  validate3dTransformation();
245 
246  // Filter on y axis
247  params["dim"] = "1";
248  icp.readingDataPointsFilters.clear();
249  addFilter("MaxQuantileOnAxisDataPointsFilter", params);
250  validate2dTransformation();
251  validate3dTransformation();
252 
253  // Filter on z axis (not existing)
254  params["dim"] = "2";
255  icp.readingDataPointsFilters.clear();
256  addFilter("MaxQuantileOnAxisDataPointsFilter", params);
257  EXPECT_ANY_THROW(validate2dTransformation());
258  validate3dTransformation();
259 }
260 
261 
262 
264 {
265  // This filter create descriptor, so parameters should'nt impact results
267  params["knn"] = "5";
268  params["epsilon"] = "0.1";
269  params["keepNormals"] = "1";
270  params["keepDensities"] = "1";
271  params["keepEigenValues"] = "1";
272  params["keepEigenVectors"] = "1" ;
273  params["keepMatchedIds"] = "1" ;
274  // FIXME: the parameter keepMatchedIds seems to do nothing...
275 
276  addFilter("SurfaceNormalDataPointsFilter", params);
277  validate2dTransformation();
278  validate3dTransformation();
279 
280  // TODO: standardize how filter are tested:
281  // 1- impact on number of points
282  // 2- impact on descriptors
283  // 3- impact on ICP (that's what we test now)
284 }
285 
287 {
288  // Ratio has been selected to not affect the points too much
289  vector<double> ratio = {100, 1000, 5000};
290 
291  for(unsigned i=0; i < ratio.size(); i++)
292  {
293  icp.readingDataPointsFilters.clear();
295  params["knn"] = "5";
296  params["epsilon"] = "0.1";
297  params["keepNormals"] = "0";
298  params["keepDensities"] = "1";
299  params["keepEigenValues"] = "0";
300  params["keepEigenVectors"] = "0" ;
301  params["keepMatchedIds"] = "0" ;
302 
303  addFilter("SurfaceNormalDataPointsFilter", params);
304 
306  params["maxDensity"] = toParam(ratio[i]);
307 
308  addFilter("MaxDensityDataPointsFilter", params);
309 
310  // FIXME BUG: the density in 2D is not well computed
311  //validate2dTransformation();
312 
313  //double nbInitPts = data2D.features.cols();
314  //double nbRemainingPts = icp.getPrefilteredReadingPtsCount();
315  //EXPECT_TRUE(nbRemainingPts < nbInitPts);
316 
317  validate3dTransformation();
318 
319  double nbInitPts = data3D.features.cols();
320  double nbRemainingPts = icp.getPrefilteredReadingPtsCount();
321  EXPECT_TRUE(nbRemainingPts < nbInitPts);
322  }
323 }
324 
326 {
327  // This filter create descriptor AND subsample
329  params["knn"] = "5";
330  params["averageExistingDescriptors"] = "1";
331  params["keepNormals"] = "1";
332  params["keepDensities"] = "1";
333  params["keepEigenValues"] = "1";
334  params["keepEigenVectors"] = "1";
335 
336  addFilter("SamplingSurfaceNormalDataPointsFilter", params);
337  validate2dTransformation();
338  validate3dTransformation();
339 
340 }
341 
342 //TODO: this filter is broken, fix it!
343 /*
344 TEST_F(DataFilterTest, ElipsoidsDataPointsFilter)
345 {
346  // This filter creates descriptor AND subsamples
347  params = PM::Parameters();
348  params["knn"] = "5";
349  params["averageExistingDescriptors"] = "1";
350  params["keepNormals"] = "1";
351  params["keepDensities"] = "1";
352  params["keepEigenValues"] = "1";
353  params["keepEigenVectors"] = "1";
354  params["maxBoxDim"] = "inf";
355  params["maxTimeWindow"] = "10";
356  params["minPlanarity"] = "0";
357  params["keepMeans"] = "1";
358  params["keepCovariances"] = "1";
359  params["keepWeights"] = "1";
360  params["keepShapes"] = "1";
361  params["keepIndices"] = "1";
362 
363  addFilter("ElipsoidsDataPointsFilter", params);
364  validate2dTransformation();
365  validate3dTransformation();
366 }
367 */
368 
370 {
371  // This filter creates descriptor AND subsamples
373  params["knn"] = "5";
374  params["averageExistingDescriptors"] = "1";
375  params["keepNormals"] = "1";
376  params["keepEigenValues"] = "1";
377  params["keepEigenVectors"] = "1";
378  params["maxBoxDim"] = "1";
379  params["keepMeans"] = "1";
380  params["keepCovariances"] = "1";
381  params["keepGestaltFeatures"] = "1";
382  params["radius"] = "1";
383  params["ratio"] = "0.5";
384 
385  addFilter("GestaltDataPointsFilter", params);
386  validate3dTransformation();
387 }
388 
390 {
391  // Used to create normal for reading point cloud
392  std::shared_ptr<PM::DataPointsFilter> extraDataPointFilter;
393  extraDataPointFilter = PM::get().DataPointsFilterRegistrar.create(
394  "SurfaceNormalDataPointsFilter");
395  icp.readingDataPointsFilters.push_back(extraDataPointFilter);
396  addFilter("ObservationDirectionDataPointsFilter");
397  addFilter("OrientNormalsDataPointsFilter", {
398  {"towardCenter", toParam(false)}
399  }
400  );
401  validate2dTransformation();
402  validate3dTransformation();
403 }
404 
405 
407 {
408  for(const double prob : {0.8, 0.85, 0.9, 0.95})
409  {
410  for(const unsigned int samplingMethod : {0, 1})
411  {
412  // Try to avoid too low value for the reduction to avoid under sampling
414  params["prob"] = toParam(prob);
415  params["randomSamplingMethod"] = toParam(samplingMethod);
416 
417  icp.readingDataPointsFilters.clear();
418  addFilter("RandomSamplingDataPointsFilter", params);
419  validate2dTransformation();
420  validate3dTransformation();
421  }
422  }
423 }
424 
426 {
427  vector<unsigned> steps = {1, 2, 3};
428  for(unsigned i=0; i<steps.size(); i++)
429  {
430  // Try to avoid too low value for the reduction to avoid under sampling
432  params["startStep"] = toParam(steps[i]);
433 
434  icp.readingDataPointsFilters.clear();
435  addFilter("FixStepSamplingDataPointsFilter", params);
436  validate2dTransformation();
437  validate3dTransformation();
438  }
439 }
440 
442 {
443  DP cloud = ref3D;
444 
445  const size_t maxCount = 1000;
446 
448  params["seed"] = "42";
449  params["maxCount"] = toParam(maxCount);
450 
451  std::shared_ptr<PM::DataPointsFilter> maxPtsFilter =
452  PM::get().DataPointsFilterRegistrar.create("MaxPointCountDataPointsFilter", params);
453 
454  DP filteredCloud = maxPtsFilter->filter(cloud);
455 
456  //Check number of points
457  EXPECT_GT(cloud.getNbPoints(), filteredCloud.getNbPoints());
458  EXPECT_EQ(cloud.getDescriptorDim(), filteredCloud.getDescriptorDim());
459  EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());
460 
461  EXPECT_EQ(filteredCloud.getNbPoints(), maxCount);
462 
463  //Same seed should result same filtered cloud
464  DP filteredCloud2 = maxPtsFilter->filter(cloud);
465 
466  EXPECT_TRUE(filteredCloud == filteredCloud2);
467 
468  //Different seeds should not result same filtered cloud but same number
469  params.clear();
470  params["seed"] = "1";
471  params["maxCount"] = toParam(maxCount);
472 
473  std::shared_ptr<PM::DataPointsFilter> maxPtsFilter2 =
474  PM::get().DataPointsFilterRegistrar.create("MaxPointCountDataPointsFilter", params);
475 
476  DP filteredCloud3 = maxPtsFilter2->filter(cloud);
477 
478  EXPECT_FALSE(filteredCloud3 == filteredCloud2);
479 
480  EXPECT_EQ(filteredCloud3.getNbPoints(), maxCount);
481 
482  EXPECT_EQ(filteredCloud3.getNbPoints(), filteredCloud2.getNbPoints());
483  EXPECT_EQ(filteredCloud3.getDescriptorDim(), filteredCloud2.getDescriptorDim());
484  EXPECT_EQ(filteredCloud3.getTimeDim(), filteredCloud2.getTimeDim());
485 
486  //Validate transformation
487  icp.readingDataPointsFilters.clear();
488  addFilter("MaxPointCountDataPointsFilter", params);
489  validate2dTransformation();
490  validate3dTransformation();
491 }
492 
494 {
495  const unsigned int nbPts = 60000;
496  const DP cloud = generateRandomDataPoints(nbPts);
498 
499  std::shared_ptr<PM::DataPointsFilter> octreeFilter;
500 
501  for(const int meth : {0,1,2,3})
502  for(const size_t maxData : {1,5})
503  for(const NumericType maxSize : {0.,0.05})
504  {
505  params.clear();
506  params["maxPointByNode"] = toParam(maxData);
507  params["maxSizeByNode"] = toParam(maxSize);
508  params["samplingMethod"] = toParam(meth);
509  params["buildParallel"] = "1";
510 
511  octreeFilter = PM::get().DataPointsFilterRegistrar.create("OctreeGridDataPointsFilter", params);
512 
513  const DP filteredCloud = octreeFilter->filter(cloud);
514 
515  if(maxData==1 and maxSize==0.)
516  {
517  // 1/pts by octants + validate parallel build
518  // the number of point should not change
519  // the sampling methods should not change anything
520  //Check number of points
521  EXPECT_EQ(cloud.getNbPoints(), filteredCloud.getNbPoints());
522  EXPECT_EQ(cloud.getDescriptorDim(), filteredCloud.getDescriptorDim());
523  EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());
524 
525  EXPECT_EQ(filteredCloud.getNbPoints(), nbPts);
526  }
527  else
528  {
529  //Check number of points
530  EXPECT_GT(cloud.getNbPoints(), filteredCloud.getNbPoints());
531  }
532  //Validate transformation
533  icp.readingDataPointsFilters.clear();
534  addFilter("OctreeGridDataPointsFilter", params);
535  validate2dTransformation();
536  validate3dTransformation();
537  }
538 }
539 
541 {
542  const size_t nbPts = 60000;
543  DP cloud = generateRandomDataPoints(nbPts);
545 
546  //const size_t nbPts2D = ref2D.getNbPoints();
547  const size_t nbPts3D = ref3D.getNbPoints();
548 
549  std::shared_ptr<PM::DataPointsFilter> nssFilter;
550 
551  //Compute normals
552  auto paramsNorm = PM::Parameters();
553  paramsNorm["knn"] = "5";
554  paramsNorm["epsilon"] = "0.1";
555  paramsNorm["keepNormals"] = "1";
556  std::shared_ptr<PM::DataPointsFilter> normalFilter = PM::get().DataPointsFilterRegistrar.create("SurfaceNormalDataPointsFilter", paramsNorm);
557 
558  normalFilter->inPlaceFilter(cloud);
559 
560  //Evaluate filter
561  std::vector<size_t> samples = {/* 2*nbPts2D/3, nbPts2D,*/ 1500, 5000, nbPts, nbPts3D};
562  for(const NumericType epsilon : {M_PI/6., M_PI/32., M_PI/64.})
563  for(const size_t nbSample : samples)
564  {
565  icp.readingDataPointsFilters.clear();
566 
567  params.clear();
568  params["epsilon"] = toParam(epsilon);
569  params["nbSample"] = toParam(nbSample);
570 
571  nssFilter = PM::get().DataPointsFilterRegistrar.create("NormalSpaceDataPointsFilter", params);
572 
573  addFilter("SurfaceNormalDataPointsFilter", paramsNorm);
574  addFilter("NormalSpaceDataPointsFilter", params);
575 
576  const DP filteredCloud = nssFilter->filter(cloud);
577 
578  /*
579  if(nbSample <= nbPts2D)
580  {
581  validate2dTransformation();
582  EXPECT_LE(filteredCloud.getNbPoints(), nbPts2D);
583  continue;
584  }
585  else if (nbSample == nbPts3D)
586  {
587  EXPECT_EQ(filteredCloud.getNbPoints(), nbPts3D);
588  }
589  else */
590  if (nbSample == nbPts)
591  {
592  //Check number of points
593  EXPECT_EQ(cloud.getNbPoints(), filteredCloud.getNbPoints());
594  EXPECT_EQ(cloud.getDescriptorDim(), filteredCloud.getDescriptorDim());
595  EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());
596 
597  EXPECT_EQ(filteredCloud.getNbPoints(), nbPts);
598  }
599 
600  validate3dTransformation();
601  EXPECT_GE(cloud.getNbPoints(), filteredCloud.getNbPoints());
602  }
603 }
604 
606 {
607  const size_t nbPts = 60000;
608  DP cloud = generateRandomDataPoints(nbPts);
610 
611  const size_t nbPts3D = ref3D.getNbPoints();
612 
613  std::shared_ptr<PM::DataPointsFilter> covsFilter;
614 
615  //Compute normals
616  auto paramsNorm = PM::Parameters();
617  paramsNorm["knn"] = "5";
618  paramsNorm["epsilon"] = "0.1";
619  paramsNorm["keepNormals"] = "1";
620  std::shared_ptr<PM::DataPointsFilter> normalFilter = PM::get().DataPointsFilterRegistrar.create("SurfaceNormalDataPointsFilter", paramsNorm);
621 
622  normalFilter->inPlaceFilter(cloud);
623 
624  //Evaluate filter
625  std::vector<size_t> samples = {500, 1500, 5000, nbPts, nbPts3D};
626  for(const size_t nbSample : samples)
627  {
628  icp.readingDataPointsFilters.clear();
629 
630  params.clear();
631  params["nbSample"] = toParam(nbSample);
632 
633  covsFilter = PM::get().DataPointsFilterRegistrar.create("CovarianceSamplingDataPointsFilter", params);
634 
635  addFilter("SurfaceNormalDataPointsFilter", paramsNorm);
636  addFilter("CovarianceSamplingDataPointsFilter", params);
637 
638  const DP filteredCloud = covsFilter->filter(cloud);
639 
640  if (nbSample == nbPts3D)
641  {
642  EXPECT_EQ(filteredCloud.getNbPoints(), nbPts3D);
643  }
644  else if (nbSample == nbPts)
645  {
646  //Check number of points
647  EXPECT_EQ(cloud.getNbPoints(), filteredCloud.getNbPoints());
648  EXPECT_EQ(cloud.getDescriptorDim(), filteredCloud.getDescriptorDim());
649  EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());
650 
651  EXPECT_EQ(filteredCloud.getNbPoints(), nbPts);
652  }
653 
654  validate3dTransformation();
655  EXPECT_GE(cloud.getNbPoints(), filteredCloud.getNbPoints());
656  }
657 }
658 
660 {
661  // Test with point cloud
662  DP cloud = generateRandomDataPoints();
663 
665  params["vSizeX"] = "0.5";
666  params["vSizeY"] = "0.5";
667  params["vSizeZ"] = "0.5";
668  params["useCentroid"] = toParam(true);
669  params["averageExistingDescriptors"] = toParam(true);
670 
671  std::shared_ptr<PM::DataPointsFilter> voxelFilter =
672  PM::get().DataPointsFilterRegistrar.create("VoxelGridDataPointsFilter", params);
673 
674  DP filteredCloud = voxelFilter->filter(cloud);
675 
676  EXPECT_GT(cloud.getNbPoints(), filteredCloud.getNbPoints());
677  EXPECT_EQ(cloud.getDescriptorDim(), filteredCloud.getDescriptorDim());
678  EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());
679 
680  // Test with ICP
681  vector<bool> useCentroid = {false, true};
682  vector<bool> averageExistingDescriptors = {false, true};
683  for (unsigned i = 0 ; i < useCentroid.size() ; i++)
684  {
685  for (unsigned j = 0; j < averageExistingDescriptors.size(); j++)
686  {
688  params["vSizeX"] = "0.02";
689  params["vSizeY"] = "0.02";
690  params["vSizeZ"] = "0.02";
691  params["useCentroid"] = toParam(true);
692  params["averageExistingDescriptors"] = toParam(true);
693 
694  icp.readingDataPointsFilters.clear();
695  addFilter("VoxelGridDataPointsFilter", params);
696  validate2dTransformation();
697  }
698  }
699 
700  for (unsigned i = 0 ; i < useCentroid.size() ; i++)
701  {
702  for (unsigned j = 0; j < averageExistingDescriptors.size(); j++)
703  {
705  params["vSizeX"] = "1";
706  params["vSizeY"] = "1";
707  params["vSizeZ"] = "1";
708  params["useCentroid"] = toParam(true);
709  params["averageExistingDescriptors"] = toParam(true);
710 
711  icp.readingDataPointsFilters.clear();
712  addFilter("VoxelGridDataPointsFilter", params);
713  validate3dTransformation();
714  }
715  }
716 }
717 
719 {
720  // Copied from density ratio above
721  vector<double> thresholds = {100, 1000, 5000};
722 
723  DP ref3Ddensities = ref3D;
724  // Adding descriptor "densities"
725  icp.readingDataPointsFilters.clear();
727  params["knn"] = "5";
728  params["epsilon"] = "0.1";
729  params["keepNormals"] = "0";
730  params["keepDensities"] = "1";
731  params["keepEigenValues"] = "0";
732  params["keepEigenVectors"] = "0";
733  params["keepMatchedIds"] = "0";
734 
735 
736  addFilter("SurfaceNormalDataPointsFilter", params);
737  icp.readingDataPointsFilters.apply(ref3Ddensities);
738 
739  for(unsigned i=0; i < thresholds.size(); i++)
740  {
741  int belowCount=0;
742  int aboveCount=0;
743 
744  // counting points above and below
745  PM::DataPoints::View densities = ref3Ddensities.getDescriptorViewByName("densities");
746  for (unsigned j=0; j < densities.cols(); ++j)
747  {
748  if (densities(0, j) <= thresholds[i])
749  {
750  ++belowCount;
751  }
752  if (densities(0, j) >= thresholds[i])
753  {
754  ++aboveCount;
755  }
756  }
757 
758  for(bool useLargerThan(true); useLargerThan; useLargerThan=false)
759  {
760  DP ref3DCopy = ref3Ddensities;
761 
762  icp.readingDataPointsFilters.clear();
764  params["descName"] = toParam("densities");
765  params["useLargerThan"] = toParam(useLargerThan);
766  params["threshold"] = toParam(thresholds[i]);
767 
768 
769  addFilter("CutAtDescriptorThresholdDataPointsFilter", params);
770  icp.readingDataPointsFilters.apply(ref3DCopy);
771  if (useLargerThan)
772  {
773  EXPECT_TRUE(ref3DCopy.features.cols() == belowCount);
774  }
775  else
776  {
777  EXPECT_TRUE(ref3DCopy.features.cols() == aboveCount);
778  }
779  }
780  }
781 }
782 
784 {
786  params["dim"] = "0";
787  params["dist"] = toParam(6.0);
788  params["removeInside"] = "0";
789 
790  // Filter on x axis
791  params["dim"] = "0";
792  icp.readingDataPointsFilters.clear();
793  addFilter("DistanceLimitDataPointsFilter", params);
794  validate2dTransformation();
795  validate3dTransformation();
796 
797  // Filter on y axis
798  params["dim"] = "1";
799  icp.readingDataPointsFilters.clear();
800  addFilter("DistanceLimitDataPointsFilter", params);
801  validate2dTransformation();
802  validate3dTransformation();
803 
804  // Filter on z axis (not existing)
805  params["dim"] = "2";
806  icp.readingDataPointsFilters.clear();
807  addFilter("DistanceLimitDataPointsFilter", params);
808  EXPECT_ANY_THROW(validate2dTransformation());
809  validate3dTransformation();
810 
811  // Filter on a radius
812  params["dim"] = "-1";
813  icp.readingDataPointsFilters.clear();
814  addFilter("DistanceLimitDataPointsFilter", params);
815  validate2dTransformation();
816  validate3dTransformation();
817 
818  // Parameter outside valid range
819  params["dim"] = "3";
820  //TODO: specify the exception, move that to GenericTest
821  EXPECT_ANY_THROW(addFilter("DistanceLimitDataPointsFilter", params));
822 
823 
825  params["dim"] = "0";
826  params["dist"] = toParam(0.05);
827  params["removeInside"] = "1";
828 
829  // Filter on x axis
830  params["dim"] = "0";
831  icp.readingDataPointsFilters.clear();
832  addFilter("DistanceLimitDataPointsFilter", params);
833  validate2dTransformation();
834  validate3dTransformation();
835 
836  // Filter on y axis
837  params["dim"] = "1";
838  icp.readingDataPointsFilters.clear();
839  addFilter("DistanceLimitDataPointsFilter", params);
840  validate2dTransformation();
841  validate3dTransformation();
842 
843  //TODO: move that to specific 2D test
844  // Filter on z axis (not existing)
845  params["dim"] = "2";
846  icp.readingDataPointsFilters.clear();
847  addFilter("DistanceLimitDataPointsFilter", params);
848  EXPECT_ANY_THROW(validate2dTransformation());
849  validate3dTransformation();
850 
851  // Filter on a radius
852  params["dim"] = "-1";
853  icp.readingDataPointsFilters.clear();
854  addFilter("DistanceLimitDataPointsFilter", params);
855  validate2dTransformation();
856  validate3dTransformation();
857 }
858 
859 TEST_F(DataFilterTest, SameFilterInstanceTwice)
860 {
862 
863  std::shared_ptr<PM::DataPointsFilter> df = PM::get().DataPointsFilterRegistrar.create("MaxPointCountDataPointsFilter", params);
864 
865  icp.referenceDataPointsFilters.push_back(df);
866  icp.readingDataPointsFilters.push_back(df);
867 }
868 
870 {
871  const size_t nbPts = 6;
872  const double expectedErrors_LMS1xx[6] = {0., -0.0015156, -0.059276,
873  0., -0.002311, -0.163689};
874  const double expectedErrors_HDL32E[6] = {0., -0.002945, -0.075866,
875  0., -0.002998,-0.082777 };
876 
877  PM::Matrix points = (PM::Matrix(3,6) << 1, 1, 1, 5, 5, 5,
878  0, 0, 0, 0, 0, 0,
879  0, 0, 0, 0, 0, 0).finished();
880  DP::Labels pointsLabels;
881  pointsLabels.push_back(DP::Label("x", 1));
882  pointsLabels.push_back(DP::Label("y", 1));
883  pointsLabels.push_back(DP::Label("z", 1));
884  pointsLabels.push_back(DP::Label("pad", 1));
885 
886  PM::Matrix desc = (PM::Matrix(4,6) << 0., 0.7854, 1.4835, 0., 0.7854, 1.4835, //0,45,85 degrees
887  -1, -1, -1, -5, -5, -5,
888  0, 0, 0, 0, 0, 0, // observation : point to sensor
889  0, 0, 0, 0, 0, 0).finished();
890 
891  PM::Matrix desc2 = (PM::Matrix(4,6) << 0., 0.7854, std::nanf(""), 0., 0.7854, M_PI_2, //0,45,90 degrees
892  -1, -1, -1, -5, -5, -5,
893  0, 0, 0, 0, 0, 0, // observation : point to sensor
894  0, 0, 0, 0, 0, 0).finished();
895  DP::Labels descLabels;
896  descLabels.push_back(DP::Label("incidenceAngles", 1));
897  descLabels.push_back(DP::Label("observationDirections", 3));
898 
899  PM::Int64Matrix randTimes = PM::Int64Matrix::Random(2, nbPts);
900  DP::Labels timeLabels;
901  timeLabels.push_back(DP::Label("dummyTime", 2));
902 
903  // Construct the point cloud from the generated matrices
904  DP pointCloud = DP(points, pointsLabels, desc, descLabels, randTimes, timeLabels);
905 
906 
907  PM::Parameters parameters;
908  parameters["sensorType"] = toParam(0); //LMS_1xx
909  std::shared_ptr<PM::DataPointsFilter> removeSensorBiasFilter = PM::get().DataPointsFilterRegistrar.create("RemoveSensorBiasDataPointsFilter", parameters);
910  DP resultCloud = removeSensorBiasFilter->filter(pointCloud);
911  EXPECT_EQ(pointCloud.getNbPoints(), resultCloud.getNbPoints());
912 
913  for(std::size_t i = 0; i< nbPts; ++i)
914  {
915  const double error = pointCloud.features.col(i).norm() - resultCloud.features.col(i).norm();
916  EXPECT_NEAR(expectedErrors_LMS1xx[i], error, 1e-3); // below mm
917  }
918 
919  parameters["sensorType"] = toParam(1); //HDL32E
920  removeSensorBiasFilter = PM::get().DataPointsFilterRegistrar.create("RemoveSensorBiasDataPointsFilter", parameters);
921  resultCloud = removeSensorBiasFilter->filter(pointCloud);
922 
923  for(std::size_t i = 0; i< nbPts; ++i)
924  {
925  const double error = pointCloud.features.col(i).norm() - resultCloud.features.col(i).norm();
926  EXPECT_NEAR(expectedErrors_HDL32E[i], error, 1e-4); // below mm
927  }
928 
929 
930  //test points rejection
931  pointCloud = DP(points, pointsLabels, desc2, descLabels, randTimes, timeLabels);
932 
933  parameters["sensorType"] = toParam(0); //LMS_1xx
934  parameters["angleThreshold"] = toParam(30.);
935  removeSensorBiasFilter = PM::get().DataPointsFilterRegistrar.create("RemoveSensorBiasDataPointsFilter", parameters);
936  resultCloud = removeSensorBiasFilter->filter(pointCloud);
937 
938  //four points should have been rejected
939  EXPECT_EQ(pointCloud.getNbPoints()-4, resultCloud.getNbPoints());
940 }
941 
943 {
944  // This filter creates descriptors
946  params["k"] = "50";
947  params["sigma"] = "1.0";
948  params["keepNormals"] = "1";
949  params["keepLabels"] = "1";
950  params["keepTensors"] = "1";
951 
952  addFilter("SaliencyDataPointsFilter", params);
953  validate3dTransformation();
954 }
955 
957 {
958  using DPFiltersPtr = std::shared_ptr<PM::DataPointsFilter>;
959 
960  // Test with point cloud
961  DP cloud = generateRandomDataPoints(300000);
962 
963  // This filter creates descriptors
965  params["k"] = "50";
966  params["sigma"] = "0.1";
967  params["radius"] = "0.4";
968  params["itMax"] = "15";
969  params["keepNormals"] = "1";
970  params["keepLabels"] = "1";
971  params["keepLambdas"] = "1";
972  params["keepTensors"] = "1";
973 
974  DPFiltersPtr spdf = PM::get().DataPointsFilterRegistrar.create(
975  "SpectralDecompositionDataPointsFilter", params
976  );
977 
978  DP filteredCloud = spdf->filter(cloud);
979 
980  EXPECT_GT(cloud.getNbPoints(), filteredCloud.getNbPoints());
981  EXPECT_EQ(cloud.getDescriptorDim()+(3+3+1+3+1+4+7+3), filteredCloud.getDescriptorDim());
982  EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());
983 
985  params["k"] = "50";
986  params["sigma"] = "1.";
987  params["radius"] = "2.";
988  params["itMax"] = "15";
989  params["keepNormals"] = "1";
990  params["keepLabels"] = "1";
991  params["keepLambdas"] = "1";
992  params["keepTensors"] = "1";
993 
994  addFilter("SpectralDecompositionDataPointsFilter", params);
995  validate3dTransformation();
996 }
997 
999 {
1000  using DPFiltersPtr = std::shared_ptr<PM::DataPointsFilter>;
1001 
1002  // Test with point cloud
1003  DP cloud = generateRandomDataPoints(100);
1004 
1005  std::string descriptorName = "test_descriptor";
1006  std::size_t descriptorDimension = 3;
1007  std::vector<NumericType> descriptorValues{2, 3, 4};
1008 
1009  // This filter adds a new descriptor
1010  params = PM::Parameters();
1011  params["descriptorName"] = descriptorName;
1012  params["descriptorDimension"] = toParam(descriptorDimension);
1013  params["descriptorValues"] = toParam(descriptorValues);
1014 
1015  DPFiltersPtr addDescriptorFilter = PM::get().DataPointsFilterRegistrar.create(
1016  "AddDescriptorDataPointsFilter", params
1017  );
1018 
1019  DP filteredCloud = addDescriptorFilter->filter(cloud);
1020 
1021  EXPECT_EQ(cloud.getNbPoints(), filteredCloud.getNbPoints());
1022  EXPECT_EQ(cloud.getDescriptorDim()+descriptorDimension, filteredCloud.getDescriptorDim());
1023  EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());
1024 
1025  Eigen::Matrix<NumericType, 1, Eigen::Dynamic> row = Eigen::Matrix<NumericType, 1, Eigen::Dynamic>::Ones(cloud.getNbPoints());
1026  EXPECT_EQ(filteredCloud.descriptorLabels.back().text, descriptorName);
1027  EXPECT_EQ(filteredCloud.descriptorLabels.back().span, descriptorDimension);
1028  for(unsigned i = 0; i < descriptorDimension; ++i)
1029  {
1030  EXPECT_EQ(filteredCloud.descriptors.row(filteredCloud.descriptors.rows()-3+i), row*descriptorValues[i]);
1031  }
1032 
1033 
1034  descriptorValues = std::vector<NumericType>{-2, -3, -4};
1035  params["descriptorValues"] = toParam(descriptorValues);
1036 
1037  addDescriptorFilter = PM::get().DataPointsFilterRegistrar.create(
1038  "AddDescriptorDataPointsFilter", params
1039  );
1040  DP filteredCloudOvewriteParams = addDescriptorFilter->filter(filteredCloud);
1041  EXPECT_EQ(filteredCloudOvewriteParams.descriptorLabels.back().text, descriptorName);
1042  EXPECT_EQ(filteredCloudOvewriteParams.descriptorLabels.back().span, descriptorDimension);
1043  for(unsigned i = 0; i < descriptorDimension; ++i)
1044  {
1045  EXPECT_EQ(filteredCloudOvewriteParams.descriptors.row(filteredCloud.descriptors.rows()-3+i), row*descriptorValues[i]);
1046  }
1047 
1048 
1049  descriptorValues = std::vector<NumericType>{-2, -3, -4, -5};
1050  params["descriptorDimension"] = toParam(4);
1051  params["descriptorValues"] = toParam(descriptorValues);
1052  addDescriptorFilter = PM::get().DataPointsFilterRegistrar.create(
1053  "AddDescriptorDataPointsFilter", params
1054  );
1055  EXPECT_THROW(addDescriptorFilter->filter(filteredCloud), std::runtime_error);
1056 
1057  params = PM::Parameters();
1058  params["descriptorName"] = "my_descriptor";
1059  params["descriptorDimension"] = toParam(descriptorDimension);
1060  params["descriptorValues"] = "[2, 3, 4]";
1061 
1062  addFilter("AddDescriptorDataPointsFilter", params);
1063  validate3dTransformation();
1064 }
1065 
1066 
1068 {
1069  const unsigned int nbPts = 10000;
1070  const DP cloud = generateRandomDataPoints(nbPts);
1071 
1072  // Remove negative x-axis: thetaMin = -180, thetaMax = 180, phiMin = -180/2, phiMax = 180/2, removeInside = 0
1073  DP filteredCloud = validateAngleLimitFilter(cloud, -180, 180, -90, 90, false);
1074  for (unsigned i = 0; i < filteredCloud.getNbPoints(); ++i)
1075  {
1076  const Eigen::Vector3d point = filteredCloud.features.col(i).head(3);
1077  EXPECT_GT(point(0), 0.0);
1078  }
1079 
1080  // Remove positive x-axis: thetaMin = -180, thetaMax = 180, phiMin = -180/2, phiMax = 180/2, removeInside = 1
1081  filteredCloud = validateAngleLimitFilter(cloud, -180, 180, -90, 90, true);
1082  for (unsigned i = 0; i < filteredCloud.getNbPoints(); ++i)
1083  {
1084  const Eigen::Vector3d point = filteredCloud.features.col(i).head(3);
1085  EXPECT_LT(point(0), 0.0);
1086  }
1087 
1088  // Remove negative y-axis: thetaMin = -180, thetaMax = 180, phiMin = 0, phiMax = 180, removeInside = 0
1089  filteredCloud = validateAngleLimitFilter(cloud, -180, 180, 0, 180, false);
1090  for (unsigned i = 0; i < filteredCloud.getNbPoints(); ++i)
1091  {
1092  const Eigen::Vector3d point = filteredCloud.features.col(i).head(3);
1093  EXPECT_GT(point(1), 0.0);
1094  }
1095 
1096  // Remove positive y-axis: thetaMin = -180, thetaMax = 180, phiMin = 0, phiMax = 180, removeInside = 1
1097  filteredCloud = validateAngleLimitFilter(cloud, -180, 180, 0, 180, true);
1098  for (unsigned i = 0; i < filteredCloud.getNbPoints(); ++i)
1099  {
1100  const Eigen::Vector3d point = filteredCloud.features.col(i).head(3);
1101  EXPECT_LT(point(1), 0.0);
1102  }
1103 
1104  // // Remove negative z-axis: thetaMin = -90, thetaMax = 90, phiMin = -180, phiMax = 180, removeInside = 0
1105  filteredCloud = validateAngleLimitFilter(cloud, -90, 90, -180, 180, false);
1106 
1107  for (unsigned i = 0; i < filteredCloud.getNbPoints(); ++i)
1108  {
1109  const Eigen::Vector3d point = filteredCloud.features.col(i).head(3);
1110  EXPECT_GT(point(2), 0.0);
1111  }
1112 
1113  // // Remove positive z-axis: thetaMin = -90, thetaMax = 90, phiMin = -180, phiMax = 180, removeInside = 1
1114  filteredCloud = validateAngleLimitFilter(cloud, -90, 90, -180, 180, true);
1115  for (unsigned i = 0; i < filteredCloud.getNbPoints(); ++i)
1116  {
1117  const Eigen::Vector3d point = filteredCloud.features.col(i).head(3);
1118  EXPECT_LT(point(2), 0.0);
1119  }
1120 }
FixStepSamplingDataPointsFilter
Systematic sampling, with variation over time.
Definition: FixStepSampling.h:41
EXPECT_GE
#define EXPECT_GE(val1, val2)
Definition: gtest.h:19757
PointMatcher< float >::Parameters
Parametrizable::Parameters Parameters
alias
Definition: PointMatcher.h:186
PointMatcherSupport::toParam
std::string toParam(const S &value)
Return the string value using lexical_cast.
Definition: Parametrizable.h:123
PointMatcher::DataPoints::descriptorLabels
Labels descriptorLabels
labels of descriptors
Definition: PointMatcher.h:334
EXPECT_LE
#define EXPECT_LE(val1, val2)
Definition: gtest.h:19753
OrientNormalsDataPointsFilter
Reorientation of normals.
Definition: OrientNormals.h:41
DistanceLimitDataPointsFilter
Subsampling. Filter points based on distance measured on a specific axis.
Definition: DistanceLimit.h:41
MaxQuantileOnAxisDataPointsFilter
Subsampling. Filter points beyond a maximum quantile measured on a specific axis.
Definition: MaxQuantileOnAxis.h:41
MinDistDataPointsFilter
Subsampling. Filter points before a minimum distance measured on a specific axis.
Definition: MinDist.h:41
DataFilterTest::validateAngleLimitFilter
DP validateAngleLimitFilter(const DP &cloud, double thetaMin, double thetaMax, double phiMin, double phiMax, bool removeInside)
Definition: DataFilters.cpp:75
PointMatcher::DataPoints::Labels
A vector of Label.
Definition: PointMatcher.h:229
icp_customized.name
string name
Definition: icp_customized.py:45
ref3D
DP ref3D
Definition: utest.cpp:47
EXPECT_NEAR
#define EXPECT_NEAR(val1, val2, abs_error)
Definition: gtest.h:19868
RemoveSensorBiasDataPointsFilter
Definition: RemoveSensorBias.h:41
MaxDistDataPointsFilter
Subsampling. Filter points beyond a maximum distance measured on a specific axis.
Definition: MaxDist.h:41
PointMatcher::DataPoints::getTimeDim
unsigned getTimeDim() const
Return the total number of times.
Definition: pointmatcher/DataPoints.cpp:194
PointMatcher::DataPoints
A point cloud.
Definition: PointMatcher.h:207
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: gtest.h:19327
testing::internal::string
::std::string string
Definition: gtest.h:1979
IcpHelper
Definition: utest.h:30
AngleLimitDataPointsFilter
Definition: AngleLimit.h:44
EXPECT_GT
#define EXPECT_GT(val1, val2)
Definition: gtest.h:19759
GestaltDataPointsFilter
Gestalt descriptors filter as described in Bosse & Zlot ICRA 2013.
Definition: Gestalt.h:41
SurfaceNormalDataPointsFilter
Surface normals estimation. Find the normal for every point using eigen-decomposition of neighbour po...
Definition: SurfaceNormal.h:43
SaliencyDataPointsFilter
Definition: Saliency.h:40
EXPECT_LT
#define EXPECT_LT(val1, val2)
Definition: gtest.h:19755
EXPECT_EQ
#define EXPECT_EQ(expected, actual)
Definition: gtest.h:19747
DataFilterTest::addFilter
void addFilter(string name)
Definition: DataFilters.cpp:40
PointMatcher< float >::Int64Matrix
Eigen::Matrix< std::int64_t, Eigen::Dynamic, Eigen::Dynamic > Int64Matrix
A dense signed 64-bits matrix.
Definition: PointMatcher.h:173
OctreeGridDataPointsFilter
Data Filter based on Octree representation.
Definition: OctreeGrid.h:54
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: gtest.h:19330
align_sequence.params
params
Definition: align_sequence.py:13
DataFilterTest
Definition: DataFilters.cpp:15
AddDescriptorDataPointsFilter
Add new descriptor to an existing point cloud.
Definition: AddDescriptor.h:10
VoxelGridDataPointsFilter
Definition: VoxelGrid.h:40
DataFilterTest::addFilter
void addFilter(string name, PM::Parameters params)
Definition: DataFilters.cpp:32
SamplingSurfaceNormalDataPointsFilter
Sampling surface normals. First decimate the space until there is at most knn points,...
Definition: SamplingSurfaceNormal.h:41
PointMatcher::DataPoints::descriptors
Matrix descriptors
descriptors of points in the cloud, might be empty
Definition: PointMatcher.h:333
RandomSamplingDataPointsFilter
Random sampling.
Definition: RandomSampling.h:43
PointMatcher< float >::Matrix
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic > Matrix
A dense matrix over ScalarType.
Definition: PointMatcher.h:169
TEST_F
TEST_F(DataFilterTest, IdentityDataPointsFilter)
Definition: DataFilters.cpp:118
ref2D
DP ref2D
Definition: utest.cpp:45
SpectralDecompositionDataPointsFilter
Definition: SpectralDecomposition.h:49
PointMatcher::DataPoints::getNbPoints
unsigned getNbPoints() const
Return the number of points contained in the point cloud.
Definition: pointmatcher/DataPoints.cpp:158
IdentityDataPointsFilter
IdentityDataPointsFilter, does nothing.
Definition: DataPointsFilters/Identity.h:41
PointMatcher::DataPoints::features
Matrix features
features of points in the cloud
Definition: PointMatcher.h:331
RemoveNaNDataPointsFilter
Remove points having NaN as coordinate.
Definition: RemoveNaN.h:41
data3D
DP data3D
Definition: utest.cpp:48
NumericType
double NumericType
Definition: utest.h:13
CovarianceSamplingDataPointsFilter
Definition: CovarianceSampling.h:40
DataFilterTest::SetUp
virtual void SetUp()
Definition: DataFilters.cpp:19
std
EXPECT_ANY_THROW
#define EXPECT_ANY_THROW(statement)
Definition: gtest.h:19315
MaxDensityDataPointsFilter
Subsampling. Reduce the points number by randomly removing points with a dentsity higher than a tresh...
Definition: MaxDensity.h:41
PointMatcherSupport::radToDeg
T radToDeg(T rad)
Definition: Functions.h:63
icp
Definition: icp.py:1
CutAtDescriptorThresholdDataPointsFilter
Subsampling. Cut points with value of a given descriptor above or below a given threshold.
Definition: CutAtDescriptorThreshold.h:43
PointMatcher::DataPoints::getDescriptorDim
unsigned getDescriptorDim() const
Return the total number of descriptors.
Definition: pointmatcher/DataPoints.cpp:187
EXPECT_THROW
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:19311
PointMatcher< float >::get
static const PointMatcher & get()
Return instances.
Definition: Registry.cpp:147
MaxPointCountDataPointsFilter
Maximum number of points.
Definition: MaxPointCount.h:41
Functions.h
PointMatcherSupport
Functions and classes that are not dependant on scalar type are defined in this namespace.
Definition: Bibliography.cpp:45
DP
PM::DataPoints DP
Definition: convert.cpp:45
DataFilterTest::TearDown
virtual void TearDown()
Definition: DataFilters.cpp:30
PointMatcher::DataPoints::getDescriptorViewByName
ConstView getDescriptorViewByName(const std::string &name) const
Get a const view on a descriptor by name, throw an exception if it does not exist.
Definition: pointmatcher/DataPoints.cpp:555
DataFilterTest::generateRandomDataPoints
DP generateRandomDataPoints(int nbPoints=100)
Definition: DataFilters.cpp:48
NormalSpaceDataPointsFilter
Definition: NormalSpace.h:40
PointMatcher::DataPoints::Label
The name for a certain number of dim.
Definition: PointMatcher.h:221


libpointmatcher
Author(s):
autogenerated on Sun Dec 22 2024 03:21:52