26 icp.readingDataPointsFilters.clear();
34 std::shared_ptr<PM::DataPointsFilter> testedDataPointFilter =
37 icp.readingDataPointsFilters.push_back(testedDataPointFilter);
42 std::shared_ptr<PM::DataPointsFilter> testedDataPointFilter =
45 icp.readingDataPointsFilters.push_back(testedDataPointFilter);
50 const int dimFeatures = 4;
51 const int dimDescriptors = 3;
52 const int dimTime = 2;
54 PM::Matrix randFeat = PM::Matrix::Random(dimFeatures, nbPoints);
59 featLabels.push_back(
DP::Label(
"pad", 1));
61 PM::Matrix randDesc = PM::Matrix::Random(dimDescriptors, nbPoints);
63 descLabels.push_back(
DP::Label(
"dummyDesc", 3));
67 timeLabels.push_back(
DP::Label(
"dummyTime", 2));
70 DP pointCloud =
DP(randFeat, featLabels, randDesc, descLabels, randTimes, timeLabels);
77 const int nbRows = cloud.
features.rows();
85 std::shared_ptr<PM::DataPointsFilter> angleLimitFilter =
PM::get().DataPointsFilterRegistrar.create(
"AngleLimitDataPointsFilter",
params);
86 const DP filteredCloud = angleLimitFilter->filter(cloud);
92 for (
unsigned i = 0; i < filteredCloud.
getNbPoints(); ++i)
94 const Eigen::Vector3d point = filteredCloud.
features.col(i).head(3);
104 EXPECT_TRUE(theta < thetaMin || theta > thetaMax || phi < phiMin || phi > phiMax);
114 return filteredCloud;
124 addFilter(
"IdentityDataPointsFilter");
125 icp.readingDataPointsFilters.apply(ref2DCopy);
134 const NumericType nan(std::numeric_limits<NumericType>::quiet_NaN());
135 for (
int i(0); i < ref2DCopy.
features.cols(); ++i)
146 addFilter(
"RemoveNaNDataPointsFilter");
147 icp.readingDataPointsFilters.apply(ref2DCopy);
160 icp.readingDataPointsFilters.clear();
161 addFilter(
"MaxDistDataPointsFilter",
params);
162 validate2dTransformation();
163 validate3dTransformation();
167 icp.readingDataPointsFilters.clear();
168 addFilter(
"MaxDistDataPointsFilter",
params);
169 validate2dTransformation();
170 validate3dTransformation();
174 icp.readingDataPointsFilters.clear();
175 addFilter(
"MaxDistDataPointsFilter",
params);
177 validate3dTransformation();
181 icp.readingDataPointsFilters.clear();
182 addFilter(
"MaxDistDataPointsFilter",
params);
183 validate2dTransformation();
184 validate3dTransformation();
202 icp.readingDataPointsFilters.clear();
203 addFilter(
"MinDistDataPointsFilter",
params);
204 validate2dTransformation();
205 validate3dTransformation();
209 icp.readingDataPointsFilters.clear();
210 addFilter(
"MinDistDataPointsFilter",
params);
211 validate2dTransformation();
212 validate3dTransformation();
217 icp.readingDataPointsFilters.clear();
218 addFilter(
"MinDistDataPointsFilter",
params);
220 validate3dTransformation();
224 icp.readingDataPointsFilters.clear();
225 addFilter(
"MinDistDataPointsFilter",
params);
226 validate2dTransformation();
227 validate3dTransformation();
234 string ratio =
"0.95";
241 icp.readingDataPointsFilters.clear();
242 addFilter(
"MaxQuantileOnAxisDataPointsFilter",
params);
243 validate2dTransformation();
244 validate3dTransformation();
248 icp.readingDataPointsFilters.clear();
249 addFilter(
"MaxQuantileOnAxisDataPointsFilter",
params);
250 validate2dTransformation();
251 validate3dTransformation();
255 icp.readingDataPointsFilters.clear();
256 addFilter(
"MaxQuantileOnAxisDataPointsFilter",
params);
258 validate3dTransformation();
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" ;
276 addFilter(
"SurfaceNormalDataPointsFilter",
params);
277 validate2dTransformation();
278 validate3dTransformation();
289 vector<double> ratio = {100, 1000, 5000};
291 for(
unsigned i=0; i < ratio.size(); i++)
293 icp.readingDataPointsFilters.clear();
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" ;
303 addFilter(
"SurfaceNormalDataPointsFilter",
params);
308 addFilter(
"MaxDensityDataPointsFilter",
params);
317 validate3dTransformation();
320 double nbRemainingPts =
icp.getPrefilteredReadingPtsCount();
330 params[
"averageExistingDescriptors"] =
"1";
331 params[
"keepNormals"] =
"1";
332 params[
"keepDensities"] =
"1";
333 params[
"keepEigenValues"] =
"1";
334 params[
"keepEigenVectors"] =
"1";
336 addFilter(
"SamplingSurfaceNormalDataPointsFilter",
params);
337 validate2dTransformation();
338 validate3dTransformation();
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";
385 addFilter(
"GestaltDataPointsFilter",
params);
386 validate3dTransformation();
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)}
401 validate2dTransformation();
402 validate3dTransformation();
408 for(
const double prob : {0.8, 0.85, 0.9, 0.95})
410 for(
const unsigned int samplingMethod : {0, 1})
417 icp.readingDataPointsFilters.clear();
418 addFilter(
"RandomSamplingDataPointsFilter",
params);
419 validate2dTransformation();
420 validate3dTransformation();
427 vector<unsigned> steps = {1, 2, 3};
428 for(
unsigned i=0; i<steps.size(); i++)
434 icp.readingDataPointsFilters.clear();
435 addFilter(
"FixStepSamplingDataPointsFilter",
params);
436 validate2dTransformation();
437 validate3dTransformation();
445 const size_t maxCount = 1000;
451 std::shared_ptr<PM::DataPointsFilter> maxPtsFilter =
452 PM::get().DataPointsFilterRegistrar.create(
"MaxPointCountDataPointsFilter",
params);
454 DP filteredCloud = maxPtsFilter->filter(cloud);
464 DP filteredCloud2 = maxPtsFilter->filter(cloud);
473 std::shared_ptr<PM::DataPointsFilter> maxPtsFilter2 =
474 PM::get().DataPointsFilterRegistrar.create(
"MaxPointCountDataPointsFilter",
params);
476 DP filteredCloud3 = maxPtsFilter2->filter(cloud);
487 icp.readingDataPointsFilters.clear();
488 addFilter(
"MaxPointCountDataPointsFilter",
params);
489 validate2dTransformation();
490 validate3dTransformation();
495 const unsigned int nbPts = 60000;
496 const DP cloud = generateRandomDataPoints(nbPts);
499 std::shared_ptr<PM::DataPointsFilter> octreeFilter;
501 for(
const int meth : {0,1,2,3})
502 for(
const size_t maxData : {1,5})
509 params[
"buildParallel"] =
"1";
511 octreeFilter =
PM::get().DataPointsFilterRegistrar.create(
"OctreeGridDataPointsFilter",
params);
513 const DP filteredCloud = octreeFilter->filter(cloud);
515 if(maxData==1 and maxSize==0.)
533 icp.readingDataPointsFilters.clear();
534 addFilter(
"OctreeGridDataPointsFilter",
params);
535 validate2dTransformation();
536 validate3dTransformation();
542 const size_t nbPts = 60000;
543 DP cloud = generateRandomDataPoints(nbPts);
549 std::shared_ptr<PM::DataPointsFilter> nssFilter;
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);
558 normalFilter->inPlaceFilter(cloud);
561 std::vector<size_t> samples = { 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)
565 icp.readingDataPointsFilters.clear();
571 nssFilter =
PM::get().DataPointsFilterRegistrar.create(
"NormalSpaceDataPointsFilter",
params);
573 addFilter(
"SurfaceNormalDataPointsFilter", paramsNorm);
574 addFilter(
"NormalSpaceDataPointsFilter",
params);
576 const DP filteredCloud = nssFilter->filter(cloud);
590 if (nbSample == nbPts)
600 validate3dTransformation();
607 const size_t nbPts = 60000;
608 DP cloud = generateRandomDataPoints(nbPts);
613 std::shared_ptr<PM::DataPointsFilter> covsFilter;
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);
622 normalFilter->inPlaceFilter(cloud);
625 std::vector<size_t> samples = {500, 1500, 5000, nbPts, nbPts3D};
626 for(
const size_t nbSample : samples)
628 icp.readingDataPointsFilters.clear();
633 covsFilter =
PM::get().DataPointsFilterRegistrar.create(
"CovarianceSamplingDataPointsFilter",
params);
635 addFilter(
"SurfaceNormalDataPointsFilter", paramsNorm);
636 addFilter(
"CovarianceSamplingDataPointsFilter",
params);
638 const DP filteredCloud = covsFilter->filter(cloud);
640 if (nbSample == nbPts3D)
644 else if (nbSample == nbPts)
654 validate3dTransformation();
662 DP cloud = generateRandomDataPoints();
671 std::shared_ptr<PM::DataPointsFilter> voxelFilter =
672 PM::get().DataPointsFilterRegistrar.create(
"VoxelGridDataPointsFilter",
params);
674 DP filteredCloud = voxelFilter->filter(cloud);
681 vector<bool> useCentroid = {
false,
true};
682 vector<bool> averageExistingDescriptors = {
false,
true};
683 for (
unsigned i = 0 ; i < useCentroid.size() ; i++)
685 for (
unsigned j = 0; j < averageExistingDescriptors.size(); j++)
688 params[
"vSizeX"] =
"0.02";
689 params[
"vSizeY"] =
"0.02";
690 params[
"vSizeZ"] =
"0.02";
694 icp.readingDataPointsFilters.clear();
695 addFilter(
"VoxelGridDataPointsFilter",
params);
696 validate2dTransformation();
700 for (
unsigned i = 0 ; i < useCentroid.size() ; i++)
702 for (
unsigned j = 0; j < averageExistingDescriptors.size(); j++)
711 icp.readingDataPointsFilters.clear();
712 addFilter(
"VoxelGridDataPointsFilter",
params);
713 validate3dTransformation();
721 vector<double> thresholds = {100, 1000, 5000};
725 icp.readingDataPointsFilters.clear();
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";
736 addFilter(
"SurfaceNormalDataPointsFilter",
params);
737 icp.readingDataPointsFilters.apply(ref3Ddensities);
739 for(
unsigned i=0; i < thresholds.size(); i++)
746 for (
unsigned j=0; j < densities.cols(); ++j)
748 if (densities(0, j) <= thresholds[i])
752 if (densities(0, j) >= thresholds[i])
758 for(
bool useLargerThan(
true); useLargerThan; useLargerThan=
false)
760 DP ref3DCopy = ref3Ddensities;
762 icp.readingDataPointsFilters.clear();
769 addFilter(
"CutAtDescriptorThresholdDataPointsFilter",
params);
770 icp.readingDataPointsFilters.apply(ref3DCopy);
788 params[
"removeInside"] =
"0";
792 icp.readingDataPointsFilters.clear();
793 addFilter(
"DistanceLimitDataPointsFilter",
params);
794 validate2dTransformation();
795 validate3dTransformation();
799 icp.readingDataPointsFilters.clear();
800 addFilter(
"DistanceLimitDataPointsFilter",
params);
801 validate2dTransformation();
802 validate3dTransformation();
806 icp.readingDataPointsFilters.clear();
807 addFilter(
"DistanceLimitDataPointsFilter",
params);
809 validate3dTransformation();
813 icp.readingDataPointsFilters.clear();
814 addFilter(
"DistanceLimitDataPointsFilter",
params);
815 validate2dTransformation();
816 validate3dTransformation();
827 params[
"removeInside"] =
"1";
831 icp.readingDataPointsFilters.clear();
832 addFilter(
"DistanceLimitDataPointsFilter",
params);
833 validate2dTransformation();
834 validate3dTransformation();
838 icp.readingDataPointsFilters.clear();
839 addFilter(
"DistanceLimitDataPointsFilter",
params);
840 validate2dTransformation();
841 validate3dTransformation();
846 icp.readingDataPointsFilters.clear();
847 addFilter(
"DistanceLimitDataPointsFilter",
params);
849 validate3dTransformation();
853 icp.readingDataPointsFilters.clear();
854 addFilter(
"DistanceLimitDataPointsFilter",
params);
855 validate2dTransformation();
856 validate3dTransformation();
863 std::shared_ptr<PM::DataPointsFilter> df =
PM::get().DataPointsFilterRegistrar.create(
"MaxPointCountDataPointsFilter",
params);
865 icp.referenceDataPointsFilters.push_back(df);
866 icp.readingDataPointsFilters.push_back(df);
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 };
879 0, 0, 0, 0, 0, 0).finished();
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));
887 -1, -1, -1, -5, -5, -5,
889 0, 0, 0, 0, 0, 0).finished();
892 -1, -1, -1, -5, -5, -5,
894 0, 0, 0, 0, 0, 0).finished();
896 descLabels.push_back(
DP::Label(
"incidenceAngles", 1));
897 descLabels.push_back(
DP::Label(
"observationDirections", 3));
901 timeLabels.push_back(
DP::Label(
"dummyTime", 2));
904 DP pointCloud =
DP(points, pointsLabels, desc, descLabels, randTimes, timeLabels);
908 parameters[
"sensorType"] =
toParam(0);
909 std::shared_ptr<PM::DataPointsFilter> removeSensorBiasFilter =
PM::get().DataPointsFilterRegistrar.create(
"RemoveSensorBiasDataPointsFilter", parameters);
910 DP resultCloud = removeSensorBiasFilter->filter(pointCloud);
913 for(std::size_t i = 0; i< nbPts; ++i)
915 const double error = pointCloud.
features.col(i).norm() - resultCloud.
features.col(i).norm();
916 EXPECT_NEAR(expectedErrors_LMS1xx[i], error, 1e-3);
919 parameters[
"sensorType"] =
toParam(1);
920 removeSensorBiasFilter =
PM::get().DataPointsFilterRegistrar.create(
"RemoveSensorBiasDataPointsFilter", parameters);
921 resultCloud = removeSensorBiasFilter->filter(pointCloud);
923 for(std::size_t i = 0; i< nbPts; ++i)
925 const double error = pointCloud.
features.col(i).norm() - resultCloud.
features.col(i).norm();
926 EXPECT_NEAR(expectedErrors_HDL32E[i], error, 1e-4);
931 pointCloud =
DP(points, pointsLabels, desc2, descLabels, randTimes, timeLabels);
933 parameters[
"sensorType"] =
toParam(0);
934 parameters[
"angleThreshold"] =
toParam(30.);
935 removeSensorBiasFilter =
PM::get().DataPointsFilterRegistrar.create(
"RemoveSensorBiasDataPointsFilter", parameters);
936 resultCloud = removeSensorBiasFilter->filter(pointCloud);
948 params[
"keepNormals"] =
"1";
949 params[
"keepLabels"] =
"1";
950 params[
"keepTensors"] =
"1";
952 addFilter(
"SaliencyDataPointsFilter",
params);
953 validate3dTransformation();
958 using DPFiltersPtr = std::shared_ptr<PM::DataPointsFilter>;
961 DP cloud = generateRandomDataPoints(300000);
969 params[
"keepNormals"] =
"1";
970 params[
"keepLabels"] =
"1";
971 params[
"keepLambdas"] =
"1";
972 params[
"keepTensors"] =
"1";
974 DPFiltersPtr spdf =
PM::get().DataPointsFilterRegistrar.create(
975 "SpectralDecompositionDataPointsFilter",
params
978 DP filteredCloud = spdf->filter(cloud);
989 params[
"keepNormals"] =
"1";
990 params[
"keepLabels"] =
"1";
991 params[
"keepLambdas"] =
"1";
992 params[
"keepTensors"] =
"1";
994 addFilter(
"SpectralDecompositionDataPointsFilter",
params);
995 validate3dTransformation();
1000 using DPFiltersPtr = std::shared_ptr<PM::DataPointsFilter>;
1003 DP cloud = generateRandomDataPoints(100);
1006 std::size_t descriptorDimension = 3;
1007 std::vector<NumericType> descriptorValues{2, 3, 4};
1011 params[
"descriptorName"] = descriptorName;
1012 params[
"descriptorDimension"] =
toParam(descriptorDimension);
1015 DPFiltersPtr addDescriptorFilter =
PM::get().DataPointsFilterRegistrar.create(
1016 "AddDescriptorDataPointsFilter",
params
1019 DP filteredCloud = addDescriptorFilter->filter(cloud);
1025 Eigen::Matrix<NumericType, 1, Eigen::Dynamic> row = Eigen::Matrix<NumericType, 1, Eigen::Dynamic>::Ones(cloud.
getNbPoints());
1028 for(
unsigned i = 0; i < descriptorDimension; ++i)
1034 descriptorValues = std::vector<NumericType>{-2, -3, -4};
1037 addDescriptorFilter =
PM::get().DataPointsFilterRegistrar.create(
1038 "AddDescriptorDataPointsFilter",
params
1040 DP filteredCloudOvewriteParams = addDescriptorFilter->filter(filteredCloud);
1043 for(
unsigned i = 0; i < descriptorDimension; ++i)
1049 descriptorValues = std::vector<NumericType>{-2, -3, -4, -5};
1052 addDescriptorFilter =
PM::get().DataPointsFilterRegistrar.create(
1053 "AddDescriptorDataPointsFilter",
params
1055 EXPECT_THROW(addDescriptorFilter->filter(filteredCloud), std::runtime_error);
1058 params[
"descriptorName"] =
"my_descriptor";
1059 params[
"descriptorDimension"] =
toParam(descriptorDimension);
1060 params[
"descriptorValues"] =
"[2, 3, 4]";
1062 addFilter(
"AddDescriptorDataPointsFilter",
params);
1063 validate3dTransformation();
1069 const unsigned int nbPts = 10000;
1070 const DP cloud = generateRandomDataPoints(nbPts);
1073 DP filteredCloud = validateAngleLimitFilter(cloud, -180, 180, -90, 90,
false);
1074 for (
unsigned i = 0; i < filteredCloud.
getNbPoints(); ++i)
1076 const Eigen::Vector3d point = filteredCloud.
features.col(i).head(3);
1081 filteredCloud = validateAngleLimitFilter(cloud, -180, 180, -90, 90,
true);
1082 for (
unsigned i = 0; i < filteredCloud.
getNbPoints(); ++i)
1084 const Eigen::Vector3d point = filteredCloud.
features.col(i).head(3);
1089 filteredCloud = validateAngleLimitFilter(cloud, -180, 180, 0, 180,
false);
1090 for (
unsigned i = 0; i < filteredCloud.
getNbPoints(); ++i)
1092 const Eigen::Vector3d point = filteredCloud.
features.col(i).head(3);
1097 filteredCloud = validateAngleLimitFilter(cloud, -180, 180, 0, 180,
true);
1098 for (
unsigned i = 0; i < filteredCloud.
getNbPoints(); ++i)
1100 const Eigen::Vector3d point = filteredCloud.
features.col(i).head(3);
1105 filteredCloud = validateAngleLimitFilter(cloud, -90, 90, -180, 180,
false);
1107 for (
unsigned i = 0; i < filteredCloud.
getNbPoints(); ++i)
1109 const Eigen::Vector3d point = filteredCloud.
features.col(i).head(3);
1114 filteredCloud = validateAngleLimitFilter(cloud, -90, 90, -180, 180,
true);
1115 for (
unsigned i = 0; i < filteredCloud.
getNbPoints(); ++i)
1117 const Eigen::Vector3d point = filteredCloud.
features.col(i).head(3);