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