test_pfh_estimation.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2012, Willow Garage, Inc.
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of the copyright holder(s) nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * $Id$
00037  *
00038  */
00039 
00040 #include <gtest/gtest.h>
00041 #include <pcl/point_cloud.h>
00042 #include <pcl/features/normal_3d.h>
00043 #include <pcl/features/pfh.h>
00044 #include <pcl/features/fpfh.h>
00045 #include <pcl/features/fpfh_omp.h>
00046 #include <pcl/features/vfh.h>
00047 #include <pcl/features/gfpfh.h>
00048 #include <pcl/io/pcd_io.h>
00049 
00050 using namespace pcl;
00051 using namespace pcl::io;
00052 using namespace std;
00053 
00054 typedef search::KdTree<PointXYZ>::Ptr KdTreePtr;
00055 
00056 PointCloud<PointXYZ> cloud;
00057 vector<int> indices;
00058 KdTreePtr tree;
00059 
00061 template <typename FeatureEstimation, typename PointT, typename NormalT, typename OutputT> void
00062 testIndicesAndSearchSurface (const typename PointCloud<PointT>::Ptr & points,
00063                              const typename PointCloud<NormalT>::Ptr & normals,
00064                              const boost::shared_ptr<vector<int> > & indices, int ndims)
00065 {
00066   //
00067   // Test setIndices and setSearchSurface
00068   //
00069   PointCloud<OutputT> full_output, output0, output1, output2;
00070 
00071   // Compute for all points and then subsample the results
00072   FeatureEstimation est0;
00073   est0.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00074   est0.setKSearch (10);
00075   est0.setInputCloud (points);
00076   est0.setInputNormals (normals);
00077   est0.compute (full_output);
00078   copyPointCloud (full_output, *indices, output0);
00079 
00080   // Compute with all points as "search surface" and the specified sub-cloud as "input"
00081   typename PointCloud<PointT>::Ptr subpoints (new PointCloud<PointT>);
00082   copyPointCloud (*points, *indices, *subpoints);
00083   FeatureEstimation est1;
00084   est1.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00085   est1.setKSearch (10);
00086   est1.setInputCloud (subpoints);
00087   est1.setSearchSurface (points);
00088   est1.setInputNormals (normals);
00089   est1.compute (output1);
00090 
00091   // Compute with all points as "input" and the specified indices
00092   FeatureEstimation est2;
00093   est2.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00094   est2.setKSearch (10);
00095   est2.setInputCloud (points);
00096   est2.setInputNormals (normals);
00097   est2.setIndices (indices);
00098   est2.compute (output2);
00099 
00100   // All three of the above cases should produce equivalent results
00101   ASSERT_EQ (output0.size (), output1.size ());
00102   ASSERT_EQ (output1.size (), output2.size ());
00103   for (size_t i = 0; i < output1.size (); ++i)
00104   {
00105     for (int j = 0; j < ndims; ++j)
00106     {
00107       ASSERT_EQ (output0.points[i].histogram[j], output1.points[i].histogram[j]);
00108       ASSERT_EQ (output1.points[i].histogram[j], output2.points[i].histogram[j]);
00109     }
00110   }
00111 
00112   //
00113   // Test the combination of setIndices and setSearchSurface
00114   //
00115   PointCloud<OutputT> output3, output4;
00116 
00117   boost::shared_ptr<vector<int> > indices2 (new vector<int> (0));
00118   for (size_t i = 0; i < (indices->size ()/2); ++i)
00119     indices2->push_back (static_cast<int> (i));
00120 
00121   // Compute with all points as search surface + the specified sub-cloud as "input" but for only a subset of indices
00122   FeatureEstimation est3;
00123   est3.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00124   est3.setKSearch (10);
00125   est3.setSearchSurface (points);
00126   est3.setInputNormals (normals);
00127   est3.setInputCloud (subpoints);
00128   est3.setIndices (indices2);
00129   est3.compute (output3);
00130 
00131   // Start with features for each point in "subpoints" and then subsample the results
00132   copyPointCloud (output0, *indices2, output4); // (Re-using "output0" from above)
00133 
00134   // The two cases above should produce equivalent results
00135   ASSERT_EQ (output3.size (), output4.size ());
00136   for (size_t i = 0; i < output3.size (); ++i)
00137   {
00138     for (int j = 0; j < ndims; ++j)
00139     {
00140       ASSERT_EQ (output3.points[i].histogram[j], output4.points[i].histogram[j]);
00141     }
00142   }
00143 }
00144 
00146 TEST (PCL, PFHEstimation)
00147 {
00148   float f1, f2, f3, f4;
00149 
00150   // Estimate normals first
00151   NormalEstimation<PointXYZ, Normal> n;
00152   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00153   // set parameters
00154   n.setInputCloud (cloud.makeShared ());
00155   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00156   n.setIndices (indicesptr);
00157   n.setSearchMethod (tree);
00158   n.setKSearch (10); // Use 10 nearest neighbors to estimate the normals
00159   // estimate
00160   n.compute (*normals);
00161 
00162   PFHEstimation<PointXYZ, Normal, PFHSignature125> pfh;
00163   pfh.setInputNormals (normals);
00164   EXPECT_EQ (pfh.getInputNormals (), normals);
00165 
00166   // computePairFeatures
00167   pfh.computePairFeatures (cloud, *normals, 0, 12, f1, f2, f3, f4);
00168   EXPECT_NEAR (f1, -0.072575, 1e-4);
00169   EXPECT_NEAR (f2, -0.040221, 1e-4);
00170   EXPECT_NEAR (f3, 0.068133, 1e-4);
00171   EXPECT_NEAR (f4, 0.006130, 1e-4);
00172 
00173   // computePointPFHSignature
00174   int nr_subdiv = 3;
00175   Eigen::VectorXf pfh_histogram (nr_subdiv * nr_subdiv * nr_subdiv);
00176   pfh.computePointPFHSignature (cloud, *normals, indices, nr_subdiv, pfh_histogram);
00177   EXPECT_NEAR (pfh_histogram[0],  0.932506, 1e-2);
00178   EXPECT_NEAR (pfh_histogram[1],  2.32429 , 1e-2);
00179   EXPECT_NEAR (pfh_histogram[2],  0.357477, 1e-2);
00180   EXPECT_NEAR (pfh_histogram[3],  0.848541, 1e-2);
00181   EXPECT_NEAR (pfh_histogram[4],  3.65565 , 2e-2); // larger error w.r.t. considering all point pairs (feature bins=0,1,1 where 1 is middle, so angle of 0)
00182   EXPECT_NEAR (pfh_histogram[5],  0.178104, 1e-2);
00183   EXPECT_NEAR (pfh_histogram[6],  1.45284 , 1e-2);
00184   EXPECT_NEAR (pfh_histogram[7],  3.60666 , 1e-2);
00185   EXPECT_NEAR (pfh_histogram[8],  0.298959, 1e-2);
00186   EXPECT_NEAR (pfh_histogram[9],  0.295143, 1e-2);
00187   EXPECT_NEAR (pfh_histogram[10], 2.13474 , 1e-2);
00188   EXPECT_NEAR (pfh_histogram[11], 0.41218 , 1e-2);
00189   EXPECT_NEAR (pfh_histogram[12], 0.165382, 1e-2);
00190   EXPECT_NEAR (pfh_histogram[13], 8.97407 , 1e-2);
00191   EXPECT_NEAR (pfh_histogram[14], 0.306592, 1e-2);
00192   EXPECT_NEAR (pfh_histogram[15], 0.455432, 1e-2);
00193   EXPECT_NEAR (pfh_histogram[16], 4.5977 ,  1e-2);
00194   EXPECT_NEAR (pfh_histogram[17], 0.393097, 1e-2);
00195   EXPECT_NEAR (pfh_histogram[18], 7.54668 , 1e-2);
00196   EXPECT_NEAR (pfh_histogram[19], 6.78336 , 1e-2);
00197   EXPECT_NEAR (pfh_histogram[20], 1.63858 , 1e-2);
00198   EXPECT_NEAR (pfh_histogram[21], 9.93842 , 1e-2);
00199   EXPECT_NEAR (pfh_histogram[22], 18.4947 , 2e-2); // larger error w.r.t. considering all point pairs (feature bins=2,1,1 where 1 is middle, so angle of 0)
00200   EXPECT_NEAR (pfh_histogram[23], 1.96553 , 1e-4);
00201   EXPECT_NEAR (pfh_histogram[24], 8.04793 , 1e-4);
00202   EXPECT_NEAR (pfh_histogram[25], 11.2793  , 1e-4);
00203   EXPECT_NEAR (pfh_histogram[26], 2.91714 , 1e-4);
00204 
00205   // Sum of values should be 100
00206   EXPECT_NEAR (pfh_histogram.sum (), 100.0, 1e-2);
00207   //std::cerr << pfh_histogram << std::endl;
00208 
00209   // Object
00210   PointCloud<PFHSignature125>::Ptr pfhs (new PointCloud<PFHSignature125> ());
00211 
00212   // set parameters
00213   pfh.setInputCloud (cloud.makeShared ());
00214   pfh.setIndices (indicesptr);
00215   pfh.setSearchMethod (tree);
00216   pfh.setKSearch (static_cast<int> (indices.size ()));
00217 
00218   // estimate
00219   pfh.compute (*pfhs);
00220   EXPECT_EQ (pfhs->points.size (), indices.size ());
00221 
00222   for (size_t i = 0; i < pfhs->points.size (); ++i)
00223   {
00224     EXPECT_NEAR (pfhs->points[i].histogram[0],  0.156477  , 1e-4);
00225     EXPECT_NEAR (pfhs->points[i].histogram[1],  0.539396  , 1e-4);
00226     EXPECT_NEAR (pfhs->points[i].histogram[2],  0.410907  , 1e-4);
00227     EXPECT_NEAR (pfhs->points[i].histogram[3],  0.184465  , 1e-4);
00228     EXPECT_NEAR (pfhs->points[i].histogram[4],  0.115767  , 1e-4);
00229     EXPECT_NEAR (pfhs->points[i].histogram[5],  0.0572475 , 1e-4);
00230     EXPECT_NEAR (pfhs->points[i].histogram[6],  0.206092  , 1e-4);
00231     EXPECT_NEAR (pfhs->points[i].histogram[7],  0.339667  , 1e-4);
00232     EXPECT_NEAR (pfhs->points[i].histogram[8],  0.265883  , 1e-4);
00233     EXPECT_NEAR (pfhs->points[i].histogram[9],  0.0038165 , 1e-4);
00234     EXPECT_NEAR (pfhs->points[i].histogram[10], 0.103046  , 1e-4);
00235     EXPECT_NEAR (pfhs->points[i].histogram[11], 0.214997  , 1e-4);
00236     EXPECT_NEAR (pfhs->points[i].histogram[12], 0.398186  , 3e-2); // larger error w.r.t. considering all point pairs (feature bins=0,2,2 where 2 is middle, so angle of 0)
00237     EXPECT_NEAR (pfhs->points[i].histogram[13], 0.298959  , 1e-4);
00238     EXPECT_NEAR (pfhs->points[i].histogram[14], 0.00127217, 1e-4);
00239     EXPECT_NEAR (pfhs->points[i].histogram[15], 0.11704   , 1e-4);
00240     EXPECT_NEAR (pfhs->points[i].histogram[16], 0.255706  , 1e-4);
00241     EXPECT_NEAR (pfhs->points[i].histogram[17], 0.356205  , 1e-4);
00242     EXPECT_NEAR (pfhs->points[i].histogram[18], 0.265883  , 1e-4);
00243     EXPECT_NEAR (pfhs->points[i].histogram[19], 0.00127217, 1e-4);
00244     EXPECT_NEAR (pfhs->points[i].histogram[20], 0.148844  , 1e-4);
00245     //EXPECT_NEAR (pfhs->points[i].histogram[21], 0.721316  , 1e-3);
00246     //EXPECT_NEAR (pfhs->points[i].histogram[22], 0.438899  , 1e-2);
00247     EXPECT_NEAR (pfhs->points[i].histogram[23], 0.22263   , 1e-4);
00248     EXPECT_NEAR (pfhs->points[i].histogram[24], 0.0216269 , 1e-4);
00249     EXPECT_NEAR (pfhs->points[i].histogram[25], 0.223902  , 1e-4);
00250     EXPECT_NEAR (pfhs->points[i].histogram[26], 0.07633   , 1e-4);
00251   }
00252   //Eigen::Map<Eigen::VectorXf> h (&(pfhs->points[0].histogram[0]), 125);
00253   //std::cerr << h.head<27> () << std::endl;
00254 
00255   // Test results when setIndices and/or setSearchSurface are used
00256 
00257   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00258   for (size_t i = 0; i < cloud.size (); i+=3)
00259     test_indices->push_back (static_cast<int> (i));
00260 
00261   testIndicesAndSearchSurface<PFHEstimation<PointXYZ, Normal, PFHSignature125>, PointXYZ, Normal, PFHSignature125>
00262   (cloud.makeShared (), normals, test_indices, 125);
00263 }
00264 
00266 TEST (PCL, FPFHEstimation)
00267 {
00268   // Estimate normals first
00269   NormalEstimation<PointXYZ, Normal> n;
00270   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00271   // set parameters
00272   n.setInputCloud (cloud.makeShared ());
00273   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00274   n.setIndices (indicesptr);
00275   n.setSearchMethod (tree);
00276   n.setKSearch (10); // Use 10 nearest neighbors to estimate the normals
00277   // estimate
00278   n.compute (*normals);
00279 
00280   FPFHEstimation<PointXYZ, Normal, FPFHSignature33> fpfh;
00281   fpfh.setInputNormals (normals);
00282   EXPECT_EQ (fpfh.getInputNormals (), normals);
00283 
00284   // computePointSPFHSignature
00285   int nr_subdiv = 11; // use the same number of bins for all three angular features
00286   Eigen::MatrixXf hist_f1 (indices.size (), nr_subdiv), hist_f2 (indices.size (), nr_subdiv), hist_f3 (indices.size (), nr_subdiv);
00287   hist_f1.setZero (); hist_f2.setZero (); hist_f3.setZero ();
00288   for (int i = 0; i < static_cast<int> (indices.size ()); ++i)
00289     fpfh.computePointSPFHSignature (cloud, *normals, i, i, indices, hist_f1, hist_f2, hist_f3);
00290 
00291   EXPECT_NEAR (hist_f1 (0, 0), 0.757576, 1e-4);
00292   EXPECT_NEAR (hist_f1 (0, 1), 0.757576, 1e-4);
00293   EXPECT_NEAR (hist_f1 (0, 2), 4.54545,  1e-4);
00294   EXPECT_NEAR (hist_f1 (0, 3), 19.697,   1e-4);
00295   EXPECT_NEAR (hist_f1 (0, 4), 40.6566,  1e-4);
00296   EXPECT_NEAR (hist_f1 (0, 5), 21.4647,  1e-4);
00297   EXPECT_NEAR (hist_f1 (0, 6), 7.575759, 1e-4);
00298   EXPECT_NEAR (hist_f1 (0, 7), 0.000000, 1e-4);
00299   EXPECT_NEAR (hist_f1 (0, 8), 0.000000, 1e-4);
00300   EXPECT_NEAR (hist_f1 (0, 9), 0.50505,  1e-4);
00301   EXPECT_NEAR (hist_f1 (0, 10), 4.0404,  1e-4);
00302 
00303   EXPECT_NEAR (hist_f2 (0, 0), 0.757576, 1e-4);
00304   EXPECT_NEAR (hist_f2 (0, 1), 1.51515,  1e-4);
00305   EXPECT_NEAR (hist_f2 (0, 2), 6.31313,  1e-4);
00306   EXPECT_NEAR (hist_f2 (0, 3), 9.59596,  1e-4);
00307   EXPECT_NEAR (hist_f2 (0, 4), 20.7071,  1e-4);
00308   EXPECT_NEAR (hist_f2 (0, 5), 18.9394,  1e-4);
00309   EXPECT_NEAR (hist_f2 (0, 6), 15.9091,  1e-4);
00310   EXPECT_NEAR (hist_f2 (0, 7), 12.8788,  1e-4);
00311   EXPECT_NEAR (hist_f2 (0, 8), 6.56566,  1e-4);
00312   EXPECT_NEAR (hist_f2 (0, 9), 4.29293,  1e-4);
00313   EXPECT_NEAR (hist_f2 (0, 10), 2.52525, 1e-4);
00314 
00315   EXPECT_NEAR (hist_f3 (0, 0), 0.000000, 1e-4);
00316   EXPECT_NEAR (hist_f3 (0, 1), 5.05051,  1e-4);
00317   EXPECT_NEAR (hist_f3 (0, 2), 4.54545,  1e-4);
00318   EXPECT_NEAR (hist_f3 (0, 3), 5.05051,  1e-4);
00319   EXPECT_NEAR (hist_f3 (0, 4), 1.76768,  1e-4);
00320   EXPECT_NEAR (hist_f3 (0, 5), 3.0303,   1e-4);
00321   EXPECT_NEAR (hist_f3 (0, 6), 9.09091,  1e-4);
00322   EXPECT_NEAR (hist_f3 (0, 7), 31.8182,  1e-4);
00323   EXPECT_NEAR (hist_f3 (0, 8), 22.2222,  1e-4);
00324   EXPECT_NEAR (hist_f3 (0, 9), 11.8687,  1e-4);
00325   EXPECT_NEAR (hist_f3 (0, 10), 5.55556, 1e-4);
00326 
00327   // weightPointSPFHSignature
00328   Eigen::VectorXf fpfh_histogram (nr_subdiv + nr_subdiv + nr_subdiv);
00329   fpfh_histogram.setZero ();
00330   vector<float> dists (indices.size ());
00331   for (size_t i = 0; i < dists.size (); ++i) dists[i] = static_cast<float> (i);
00332   fpfh.weightPointSPFHSignature (hist_f1, hist_f2, hist_f3, indices, dists, fpfh_histogram);
00333 
00334   EXPECT_NEAR (fpfh_histogram[0],  1.9798 ,  1e-2);
00335   EXPECT_NEAR (fpfh_histogram[1],  2.86927,  1e-2);
00336   EXPECT_NEAR (fpfh_histogram[2],  8.47911,  1e-2);
00337   EXPECT_NEAR (fpfh_histogram[3],  22.8784,  1e-2);
00338   EXPECT_NEAR (fpfh_histogram[4],  29.8597,  1e-2);
00339   EXPECT_NEAR (fpfh_histogram[5],  19.6877,  1e-2);
00340   EXPECT_NEAR (fpfh_histogram[6],  7.38611,  1e-2);
00341   EXPECT_NEAR (fpfh_histogram[7],  1.44265,  1e-2);
00342   EXPECT_NEAR (fpfh_histogram[8],  0.69677,  1e-2);
00343   EXPECT_NEAR (fpfh_histogram[9],  1.72609,  1e-2);
00344   EXPECT_NEAR (fpfh_histogram[10], 2.99435,  1e-2);
00345   EXPECT_NEAR (fpfh_histogram[11], 2.26313,  1e-2);
00346   EXPECT_NEAR (fpfh_histogram[12], 5.16573,  1e-2);
00347   EXPECT_NEAR (fpfh_histogram[13], 8.3263 ,  1e-2);
00348   EXPECT_NEAR (fpfh_histogram[14], 9.92427,  1e-2);
00349   EXPECT_NEAR (fpfh_histogram[15], 16.8062,  1e-2);
00350   EXPECT_NEAR (fpfh_histogram[16], 16.2767,  1e-2);
00351   EXPECT_NEAR (fpfh_histogram[17], 12.251 ,  1e-2);
00352   //EXPECT_NEAR (fpfh_histogram[18], 10.354,  1e-1);
00353   //EXPECT_NEAR (fpfh_histogram[19], 6.65578,  1e-2);
00354   EXPECT_NEAR (fpfh_histogram[20], 6.1437 ,  1e-2);
00355   EXPECT_NEAR (fpfh_histogram[21], 5.83341,  1e-2);
00356   EXPECT_NEAR (fpfh_histogram[22], 1.08809,  1e-2);
00357   EXPECT_NEAR (fpfh_histogram[23], 3.34133,  1e-2);
00358   EXPECT_NEAR (fpfh_histogram[24], 5.59236,  1e-2);
00359   EXPECT_NEAR (fpfh_histogram[25], 5.6355 ,  1e-2);
00360   EXPECT_NEAR (fpfh_histogram[26], 3.03257,  1e-2);
00361   EXPECT_NEAR (fpfh_histogram[27], 1.37437,  1e-2);
00362   EXPECT_NEAR (fpfh_histogram[28], 7.99746,  1e-2);
00363   EXPECT_NEAR (fpfh_histogram[29], 18.0343,  1e-2);
00364   EXPECT_NEAR (fpfh_histogram[30], 23.691 ,  1e-2);
00365   EXPECT_NEAR (fpfh_histogram[31], 19.8475,  1e-2);
00366   EXPECT_NEAR (fpfh_histogram[32], 10.3655,  1e-2);
00367 
00368   // Object
00369   PointCloud<FPFHSignature33>::Ptr fpfhs (new PointCloud<FPFHSignature33> ());
00370 
00371   // set parameters
00372   fpfh.setInputCloud (cloud.makeShared ());
00373   fpfh.setNrSubdivisions (11, 11, 11);
00374   fpfh.setIndices (indicesptr);
00375   fpfh.setSearchMethod (tree);
00376   fpfh.setKSearch (static_cast<int> (indices.size ()));
00377 
00378   // estimate
00379   fpfh.compute (*fpfhs);
00380   EXPECT_EQ (fpfhs->points.size (), indices.size ());
00381 
00382   EXPECT_NEAR (fpfhs->points[0].histogram[0],  1.58591, 1e-2);
00383   EXPECT_NEAR (fpfhs->points[0].histogram[1],  1.68365, 1e-2);
00384   EXPECT_NEAR (fpfhs->points[0].histogram[2],  6.71   , 1e-2);
00385   EXPECT_NEAR (fpfhs->points[0].histogram[3],  23.0717, 1e-2);
00386   EXPECT_NEAR (fpfhs->points[0].histogram[4],  33.3844, 1e-2);
00387   EXPECT_NEAR (fpfhs->points[0].histogram[5],  20.4002, 1e-2);
00388   EXPECT_NEAR (fpfhs->points[0].histogram[6],  7.31067, 1e-2);
00389   EXPECT_NEAR (fpfhs->points[0].histogram[7],  1.02635, 1e-2);
00390   EXPECT_NEAR (fpfhs->points[0].histogram[8],  0.48591, 1e-2);
00391   EXPECT_NEAR (fpfhs->points[0].histogram[9],  1.47069, 1e-2);
00392   EXPECT_NEAR (fpfhs->points[0].histogram[10], 2.87061, 1e-2);
00393   EXPECT_NEAR (fpfhs->points[0].histogram[11], 1.78321, 1e-2);
00394   EXPECT_NEAR (fpfhs->points[0].histogram[12], 4.30795, 1e-2);
00395   EXPECT_NEAR (fpfhs->points[0].histogram[13], 7.05514, 1e-2);
00396   EXPECT_NEAR (fpfhs->points[0].histogram[14], 9.37615, 1e-2);
00397   EXPECT_NEAR (fpfhs->points[0].histogram[15], 17.963 , 1e-2);
00398   EXPECT_NEAR (fpfhs->points[0].histogram[16], 18.2801, 1e-2);
00399   EXPECT_NEAR (fpfhs->points[0].histogram[17], 14.2766, 1e-2);
00400   //EXPECT_NEAR (fpfhs->points[0].histogram[18], 10.8542, 1e-2);
00401   //EXPECT_NEAR (fpfhs->points[0].histogram[19], 6.07925, 1e-2);
00402   EXPECT_NEAR (fpfhs->points[0].histogram[20], 5.28565, 1e-2);
00403   EXPECT_NEAR (fpfhs->points[0].histogram[21], 4.73887, 1e-2);
00404   EXPECT_NEAR (fpfhs->points[0].histogram[22], 0.56984, 1e-2);
00405   EXPECT_NEAR (fpfhs->points[0].histogram[23], 3.29826, 1e-2);
00406   EXPECT_NEAR (fpfhs->points[0].histogram[24], 5.28156, 1e-2);
00407   EXPECT_NEAR (fpfhs->points[0].histogram[25], 5.26939, 1e-2);
00408   EXPECT_NEAR (fpfhs->points[0].histogram[26], 3.13191, 1e-2);
00409   EXPECT_NEAR (fpfhs->points[0].histogram[27], 1.74453, 1e-2);
00410   EXPECT_NEAR (fpfhs->points[0].histogram[28], 9.41971, 1e-2);
00411   EXPECT_NEAR (fpfhs->points[0].histogram[29], 21.5894, 1e-2);
00412   EXPECT_NEAR (fpfhs->points[0].histogram[30], 24.6302, 1e-2);
00413   EXPECT_NEAR (fpfhs->points[0].histogram[31], 17.7764, 1e-2);
00414   EXPECT_NEAR (fpfhs->points[0].histogram[32], 7.28878, 1e-2);
00415 
00416   // Test results when setIndices and/or setSearchSurface are used
00417 
00418   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00419   for (size_t i = 0; i < cloud.size (); i+=3)
00420     test_indices->push_back (static_cast<int> (i));
00421 
00422   testIndicesAndSearchSurface<FPFHEstimation<PointXYZ, Normal, FPFHSignature33>, PointXYZ, Normal, FPFHSignature33>
00423   (cloud.makeShared (), normals, test_indices, 33);
00424 
00425 }
00426 
00428 TEST (PCL, FPFHEstimationOpenMP)
00429 {
00430   // Estimate normals first
00431   NormalEstimation<PointXYZ, Normal> n;
00432   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00433   // set parameters
00434   n.setInputCloud (cloud.makeShared ());
00435   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00436   n.setIndices (indicesptr);
00437   n.setSearchMethod (tree);
00438   n.setKSearch (10); // Use 10 nearest neighbors to estimate the normals
00439   // estimate
00440   n.compute (*normals);
00441   FPFHEstimationOMP<PointXYZ, Normal, FPFHSignature33> fpfh (4); // instantiate 4 threads
00442   fpfh.setInputNormals (normals);
00443 
00444   // Object
00445   PointCloud<FPFHSignature33>::Ptr fpfhs (new PointCloud<FPFHSignature33> ());
00446 
00447   // set parameters
00448   fpfh.setInputCloud (cloud.makeShared ());
00449   fpfh.setNrSubdivisions (11, 11, 11);
00450   fpfh.setIndices (indicesptr);
00451   fpfh.setSearchMethod (tree);
00452   fpfh.setKSearch (static_cast<int> (indices.size ()));
00453 
00454   // estimate
00455   fpfh.compute (*fpfhs);
00456   EXPECT_EQ (fpfhs->points.size (), indices.size ());
00457 
00458   EXPECT_NEAR (fpfhs->points[0].histogram[0],  1.58591, 1e-3);
00459   EXPECT_NEAR (fpfhs->points[0].histogram[1],  1.68365, 1e-2);
00460   EXPECT_NEAR (fpfhs->points[0].histogram[2],  6.71   , 1e-3);
00461   EXPECT_NEAR (fpfhs->points[0].histogram[3],  23.073, 1e-3);
00462   EXPECT_NEAR (fpfhs->points[0].histogram[4],  33.3828, 1e-2);
00463   EXPECT_NEAR (fpfhs->points[0].histogram[5],  20.4002, 1e-3);
00464   EXPECT_NEAR (fpfhs->points[0].histogram[6],  7.31067, 1e-3);
00465   EXPECT_NEAR (fpfhs->points[0].histogram[7],  1.02635, 1e-3);
00466   EXPECT_NEAR (fpfhs->points[0].histogram[8],  0.48591, 1e-3);
00467   EXPECT_NEAR (fpfhs->points[0].histogram[9],  1.47069, 1e-2);
00468   EXPECT_NEAR (fpfhs->points[0].histogram[10], 2.87061, 1e-3);
00469   EXPECT_NEAR (fpfhs->points[0].histogram[11], 1.78321, 1e-3);
00470   EXPECT_NEAR (fpfhs->points[0].histogram[12], 4.30795, 1e-3);
00471   EXPECT_NEAR (fpfhs->points[0].histogram[13], 7.05514, 1e-3);
00472   EXPECT_NEAR (fpfhs->points[0].histogram[14], 9.37615, 1e-3);
00473   EXPECT_NEAR (fpfhs->points[0].histogram[15], 17.963 , 1e-3);
00474   //EXPECT_NEAR (fpfhs->points[0].histogram[16], 18.2801, 1e-3);
00475   //EXPECT_NEAR (fpfhs->points[0].histogram[17], 14.2766, 1e-3);
00476   //EXPECT_NEAR (fpfhs->points[0].histogram[18], 10.8542, 1e-3);
00477   //EXPECT_NEAR (fpfhs->points[0].histogram[19], 6.07925, 1e-3);
00478   EXPECT_NEAR (fpfhs->points[0].histogram[20], 5.28991, 1e-3);
00479   EXPECT_NEAR (fpfhs->points[0].histogram[21], 4.73438, 1e-3);
00480   EXPECT_NEAR (fpfhs->points[0].histogram[22], 0.56984, 1e-3);
00481   EXPECT_NEAR (fpfhs->points[0].histogram[23], 3.29826, 1e-3);
00482   EXPECT_NEAR (fpfhs->points[0].histogram[24], 5.28156, 1e-3);
00483   EXPECT_NEAR (fpfhs->points[0].histogram[25], 5.26939, 1e-2);
00484   EXPECT_NEAR (fpfhs->points[0].histogram[26], 3.13191, 1e-3);
00485   EXPECT_NEAR (fpfhs->points[0].histogram[27], 1.74453, 1e-3);
00486   EXPECT_NEAR (fpfhs->points[0].histogram[28], 9.41971, 1e-3);
00487   EXPECT_NEAR (fpfhs->points[0].histogram[29], 21.5894, 1e-2);
00488   EXPECT_NEAR (fpfhs->points[0].histogram[30], 24.6302, 1e-3);
00489   EXPECT_NEAR (fpfhs->points[0].histogram[31], 17.7764, 1e-3);
00490   EXPECT_NEAR (fpfhs->points[0].histogram[32], 7.28878, 1e-3);
00491 
00492   // Test results when setIndices and/or setSearchSurface are used
00493 
00494   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00495   for (size_t i = 0; i < cloud.size (); i+=3)
00496     test_indices->push_back (static_cast<int> (i));
00497 
00498   testIndicesAndSearchSurface<FPFHEstimationOMP<PointXYZ, Normal, FPFHSignature33>, PointXYZ, Normal, FPFHSignature33>
00499   (cloud.makeShared (), normals, test_indices, 33);
00500 }
00501 
00503 TEST (PCL, VFHEstimation)
00504 {
00505   // Estimate normals first
00506   NormalEstimation<PointXYZ, Normal> n;
00507   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00508   // set parameters
00509   n.setInputCloud (cloud.makeShared ());
00510   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00511   n.setIndices (indicesptr);
00512   n.setSearchMethod (tree);
00513   n.setKSearch (10); // Use 10 nearest neighbors to estimate the normals
00514   // estimate
00515   n.compute (*normals);
00516   VFHEstimation<PointXYZ, Normal, VFHSignature308> vfh;
00517   vfh.setInputNormals (normals);
00518 
00519   //  PointCloud<PointNormal> cloud_normals;
00520   //  concatenateFields (cloud, normals, cloud_normals);
00521   //  savePCDFile ("bun0_n.pcd", cloud_normals);
00522 
00523   // Object
00524   PointCloud<VFHSignature308>::Ptr vfhs (new PointCloud<VFHSignature308> ());
00525 
00526   // set parameters
00527   vfh.setInputCloud (cloud.makeShared ());
00528   vfh.setIndices (indicesptr);
00529   vfh.setSearchMethod (tree);
00530 
00531   // estimate
00532   vfh.compute (*vfhs);
00533   EXPECT_EQ (int (vfhs->points.size ()), 1);
00534 
00535   //for (size_t d = 0; d < 308; ++d)
00536   //  std::cerr << vfhs.points[0].histogram[d] << std::endl;
00537 }
00538 
00540 TEST (PCL, GFPFH)
00541 {
00542   PointCloud<PointXYZL>::Ptr cloud (new PointCloud<PointXYZL>());
00543 
00544   const unsigned num_classes = 3;
00545 
00546   // Build a cubic shape with a hole and changing labels.
00547   for (int z = -10; z < 10; ++z)
00548     for (int y = -10; y < 10; ++y)
00549       for (int x = -10; x < 10; ++x)
00550       {
00551         if (x >= -9 && x < 9 && y >= -9 && y < 9 && z >= -9 && z < 9)
00552           continue;
00553         unsigned label = 1 + (std::abs (x+y+z) % num_classes);
00554         PointXYZL p;
00555         p.label = label;
00556         p.x = static_cast<float> (x);
00557         p.y = static_cast<float> (y);
00558         p.z = static_cast<float> (z);
00559         cloud->points.push_back (p);
00560       }
00561   cloud->width = static_cast<uint32_t> (cloud->points.size ());
00562   cloud->height = 1;
00563 
00564   GFPFHEstimation<PointXYZL, PointXYZL, GFPFHSignature16> gfpfh;
00565   gfpfh.setNumberOfClasses (num_classes);
00566   gfpfh.setOctreeLeafSize (2);
00567   gfpfh.setInputCloud (cloud);
00568   gfpfh.setInputLabels (cloud);
00569   PointCloud<GFPFHSignature16> descriptor;
00570   gfpfh.compute (descriptor);
00571 
00572   const float ref_values[] = { 3216, 7760, 8740, 26584, 4645, 2995, 3029, 4349, 6192, 5440, 9514, 47563, 21814, 22073, 5734, 1253 };
00573 
00574   EXPECT_EQ (descriptor.points.size (), 1);
00575   for (size_t i = 0; i < size_t (descriptor.points[0].descriptorSize ()); ++i)
00576   {
00577     EXPECT_EQ (descriptor.points[0].histogram[i], ref_values[i]);
00578   }
00579 }
00580 
00581 /* ---[ */
00582 int
00583 main (int argc, char** argv)
00584 {
00585   if (argc < 2)
00586   {
00587     std::cerr << "No test file given. Please download `bun0.pcd` and pass its path to the test." << std::endl;
00588     return (-1);
00589   }
00590 
00591   if (loadPCDFile<PointXYZ> (argv[1], cloud) < 0)
00592   {
00593     std::cerr << "Failed to read test file. Please download `bun0.pcd` and pass its path to the test." << std::endl;
00594     return (-1);
00595   }
00596 
00597   indices.resize (cloud.points.size ());
00598   for (size_t i = 0; i < indices.size (); ++i)
00599     indices[i] = static_cast<int> (i);
00600 
00601   tree.reset (new search::KdTree<PointXYZ> (false));
00602   tree->setInputCloud (cloud.makeShared ());
00603 
00604   testing::InitGoogleTest (&argc, argv);
00605   return (RUN_ALL_TESTS ());
00606 }
00607 /* ]--- */


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:35:30