Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <gtest/gtest.h>
00041 #include <pcl/point_types.h>
00042 #include <pcl/point_cloud.h>
00043 #include <pcl/common/eigen.h>
00044 #include <pcl/common/transforms.h>
00045 #include <pcl/io/pcd_io.h>
00046 #include <pcl/registration/correspondence_rejection_median_distance.h>
00047 #include <pcl/registration/correspondence_rejection_poly.h>
00048
00049 #include <boost/random.hpp>
00050
00051 pcl::PointCloud<pcl::PointXYZ> cloud;
00052
00054 TEST (CorrespondenceRejectors, CorrespondenceRejectionMedianDistance)
00055 {
00056 pcl::CorrespondencesPtr corresps (new pcl::Correspondences ());
00057 for (int i = 0; i <= 10; ++i)
00058 {
00059 pcl::Correspondence c;
00060 c.distance = static_cast<float> (i * i);
00061 corresps->push_back (c);
00062 }
00063
00064 pcl::registration::CorrespondenceRejectorMedianDistance rejector;
00065 rejector.setInputCorrespondences (corresps);
00066 rejector.setMedianFactor (2.0);
00067
00068 pcl::Correspondences corresps_filtered;
00069 rejector.getCorrespondences (corresps_filtered);
00070
00071 EXPECT_EQ (corresps_filtered.size (), 8);
00072 for (int i = 0; i < 8; ++i)
00073 EXPECT_NEAR (corresps_filtered[i].distance, static_cast<float> (i * i), 1e-5);
00074 }
00075
00077 TEST (CorrespondenceRejectors, CorrespondenceRejectionPoly)
00078 {
00079
00080 const int size = static_cast<int> (cloud.size ());
00081
00082
00083 pcl::Correspondences corr (size);
00084 for (int i = 0; i < size; ++i)
00085 corr[i].index_query = corr[i].index_match = i;
00086
00087
00088 const int last = 3*size/4;
00089 const int inc = size/8;
00090 for (int i = 0; i < last; ++i)
00091 corr[i].index_match += inc;
00092
00093
00094 pcl::PointCloud<pcl::PointXYZ> target;
00095 Eigen::Vector3f t(0.1f, 0.2f, 0.3f);
00096 Eigen::Quaternionf q (float (std::cos (0.5*M_PI_4)), 0.0f, 0.0f, float (std::sin (0.5*M_PI_4)));
00097 pcl::transformPointCloud (cloud, target, t, q);
00098
00099
00100 boost::mt19937 rng;
00101 rng.seed (1e6);
00102 boost::normal_distribution<> nd (0, 0.005);
00103 boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > var_nor (rng, nd);
00104 for (pcl::PointCloud<pcl::PointXYZ>::iterator it = target.begin (); it != target.end (); ++it)
00105 {
00106 it->x += static_cast<float> (var_nor ());
00107 it->y += static_cast<float> (var_nor ());
00108 it->z += static_cast<float> (var_nor ());
00109 }
00110
00111
00112 std::srand (1e6);
00113
00114
00115 pcl::registration::CorrespondenceRejectorPoly<pcl::PointXYZ, pcl::PointXYZ> reject;
00116 reject.setIterations (10000);
00117 reject.setCardinality (3);
00118 reject.setSimilarityThreshold (0.75f);
00119 reject.setInputSource (cloud.makeShared ());
00120 reject.setInputTarget (target.makeShared ());
00121
00122
00123 pcl::Correspondences result;
00124 reject.getRemainingCorrespondences (corr, result);
00125
00126
00127 const float ground_truth_frac = float (size-last) / float (size);
00128 const float accepted_frac = float (result.size()) / float (size);
00129
00130
00131
00132
00133
00134 EXPECT_GE(accepted_frac, ground_truth_frac);
00135 EXPECT_LE(accepted_frac, 1.5f*ground_truth_frac);
00136
00137
00138
00139
00140
00141 unsigned int true_positives = 0;
00142 for (unsigned int i = 0; i < result.size(); ++i)
00143 if (result[i].index_query == result[i].index_match)
00144 ++true_positives;
00145 const unsigned int false_positives = static_cast<unsigned int> (result.size()) - true_positives;
00146
00147 const double precision = double(true_positives) / double(true_positives+false_positives);
00148 const double recall = double(true_positives) / double(size-last);
00149 EXPECT_NEAR(precision, 1.0, 0.4);
00150 EXPECT_NEAR(recall, 1.0, 0.2);
00151 }
00152
00153
00154
00155 int
00156 main (int argc, char** argv)
00157 {
00158 if (argc < 2)
00159 {
00160 std::cerr << "No test files given. Please download `bunny.pcd` and pass its path to the test." << std::endl;
00161 return (-1);
00162 }
00163
00164
00165 if (pcl::io::loadPCDFile (argv[1], cloud) < 0)
00166 {
00167 std::cerr << "Failed to read test file. Please download `bunny.pcd` and pass its path to the test." << std::endl;
00168 return (-1);
00169 }
00170
00171 testing::InitGoogleTest (&argc, argv);
00172 return (RUN_ALL_TESTS ());
00173 }
00174