test_shot_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_omp.h>
00043 #include <pcl/io/pcd_io.h>
00044 #include <pcl/features/shot.h>
00045 #include <pcl/features/shot_omp.h>
00046 #include "pcl/features/shot_lrf.h"
00047 #include <pcl/features/3dsc.h>
00048 #include <pcl/features/usc.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 PointT> void
00062 shotCopyPointCloud (const PointCloud<PointT> &cloud_in, const std::vector<int> &indices,
00063                     PointCloud<PointT> &cloud_out)
00064 {
00065   pcl::copyPointCloud<PointT>(cloud_in, indices, cloud_out);
00066 }
00067 
00069 template <typename PointT> void
00070 checkDesc(const pcl::PointCloud<PointT>& d0, const pcl::PointCloud<PointT>& d1)
00071 {
00072   ASSERT_EQ (d0.size (), d1.size ());
00073   for (size_t i = 0; i < d1.size (); ++i)
00074     for (size_t j = 0; j < d0.points[i].descriptor.size(); ++j)
00075       ASSERT_EQ (d0.points[i].descriptor[j], d1.points[i].descriptor[j]);
00076 }
00077 
00079 template <> void
00080 checkDesc<SHOT352>(const pcl::PointCloud<SHOT352>& d0, const pcl::PointCloud<SHOT352>& d1)
00081 {
00082   ASSERT_EQ (d0.size (), d1.size ());
00083   for (size_t i = 0; i < d1.size (); ++i)
00084     for (size_t j = 0; j < 352; ++j)
00085       ASSERT_EQ (d0.points[i].descriptor[j], d1.points[i].descriptor[j]);
00086 }
00087 
00089 template <> void
00090 checkDesc<SHOT1344>(const pcl::PointCloud<SHOT1344>& d0, const pcl::PointCloud<SHOT1344>& d1)
00091 {
00092   ASSERT_EQ (d0.size (), d1.size ());
00093   for (size_t i = 0; i < d1.size (); ++i)
00094     for (size_t j = 0; j < 1344; ++j)
00095       ASSERT_EQ (d0.points[i].descriptor[j], d1.points[i].descriptor[j]);
00096 }
00097 
00099 template <> void
00100 checkDesc<ShapeContext1980>(const pcl::PointCloud<ShapeContext1980>& d0, const pcl::PointCloud<ShapeContext1980>& d1)
00101 {
00102   ASSERT_EQ (d0.size (), d1.size ());
00103   for (size_t i = 0; i < d1.size (); ++i)
00104     for (size_t j = 0; j < 1980; ++j)
00105       ASSERT_EQ (d0.points[i].descriptor[j], d1.points[i].descriptor[j]);
00106 }
00107 
00109 template <typename FeatureEstimation, typename PointT, typename NormalT, typename OutputT>
00110 struct createSHOTDesc
00111 {
00112   FeatureEstimation operator ()(const typename PointCloud<NormalT>::Ptr & normals,
00113                                 const int nr_shape_bins_ = 10,
00114                                 const int = 30,
00115                                 const bool = true,
00116                                 const bool = false) const
00117   {
00118     FeatureEstimation f(nr_shape_bins_);
00119     f.setInputNormals (normals);
00120     return (f);
00121   }
00122 };
00123 
00125 template <typename FeatureEstimation, typename PointT, typename NormalT>
00126 struct createSHOTDesc<FeatureEstimation, PointT, NormalT, SHOT352>
00127 {
00128   FeatureEstimation operator ()(const typename PointCloud<NormalT>::Ptr & normals,
00129                                 const int = 10,
00130                                 const int = 30,
00131                                 const bool = true,
00132                                 const bool = false) const
00133   {
00134     FeatureEstimation f;
00135     f.setInputNormals (normals);
00136     return (f);
00137   }
00138 };
00139 
00141 template <typename FeatureEstimation, typename PointT, typename NormalT>
00142 struct createSHOTDesc<FeatureEstimation, PointT, NormalT, SHOT1344>
00143 {
00144   FeatureEstimation operator ()(const typename PointCloud<NormalT>::Ptr & normals,
00145                                 const int = 10,
00146                                 const int = 30,
00147                                 const bool describe_shape = true,
00148                                 const bool describe_color = false) const
00149   {
00150     FeatureEstimation f (describe_shape, describe_color);
00151     f.setInputNormals (normals);
00152     return (f);
00153   }
00154 };
00155 
00157 template <typename PointT, typename NormalT, typename OutputT>
00158 struct createSHOTDesc<ShapeContext3DEstimation<PointT, NormalT, OutputT>, PointT, NormalT, OutputT>
00159 {
00160   ShapeContext3DEstimation<PointT, NormalT, OutputT>
00161     operator ()(const typename PointCloud<NormalT>::Ptr & normals,
00162                 const int,
00163                 const int,
00164                 const bool,
00165                 const bool) const
00166   {
00167     ShapeContext3DEstimation<PointT, NormalT, OutputT> sc3d;
00168     //sc3d.setAzimuthBins (4);
00169     //sc3d.setElevationBins (4);
00170     //sc3d.setRadiusBins (4);
00171     sc3d.setMinimalRadius (0.004);
00172     sc3d.setPointDensityRadius (0.008);
00173     sc3d.setInputNormals (normals);
00174     return (sc3d);
00175   }
00176 };
00177 
00179 template <typename PointT, typename NormalT, typename OutputT>
00180 struct createSHOTDesc<UniqueShapeContext<PointT, OutputT>, PointT, NormalT, OutputT>
00181 {
00182   UniqueShapeContext<PointT, OutputT>
00183     operator ()(const typename PointCloud<NormalT>::Ptr &,
00184                 const int,
00185                 const int,
00186                 const bool,
00187                 const bool) const
00188   {
00189     UniqueShapeContext<PointT, OutputT> usc;
00190     //usc.setAzimuthBins (4);
00191     //usc.setElevationBins (4);
00192     //usc.setRadiusBins (4);
00193     usc.setMinimalRadius (0.004);
00194     usc.setPointDensityRadius (0.008);
00195     usc.setLocalRadius (0.04);
00196     return (usc);
00197   }
00198 };
00199 
00201 template <typename FeatureEstimation, typename PointT, typename NormalT, typename OutputT> void
00202 testSHOTIndicesAndSearchSurface (const typename PointCloud<PointT>::Ptr & points,
00203                                  const typename PointCloud<NormalT>::Ptr & normals,
00204                                  const boost::shared_ptr<vector<int> > & indices,
00205                                  const int nr_shape_bins = 10,
00206                                  const int nr_color_bins = 30,
00207                                  const bool describe_shape = true,
00208                                  const bool describe_color = false)
00209 {
00210   double radius = 0.04;
00211   //
00212   // Test setIndices and setSearchSurface
00213   //
00214   PointCloud<OutputT> full_output, output0, output1, output2;
00215 
00216   // Compute for all points and then subsample the results
00217   FeatureEstimation est0 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>()(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00218   est0.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00219   est0.setRadiusSearch (radius);
00220   est0.setInputCloud (points);
00221   est0.compute (full_output);
00222 
00223   shotCopyPointCloud<OutputT> (full_output, *indices, output0);
00224 
00225   // Compute with all points as "search surface" and the specified sub-cloud as "input"
00226   typename PointCloud<PointT>::Ptr subpoints (new PointCloud<PointT>);
00227   copyPointCloud (*points, *indices, *subpoints);
00228   FeatureEstimation est1 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>()(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00229   est1.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00230   est1.setRadiusSearch (radius);
00231   est1.setInputCloud (subpoints);
00232   est1.setSearchSurface (points);
00233   est1.compute (output1);
00234 
00236   FeatureEstimation est2 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>()(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00237   est2.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00238   est2.setRadiusSearch (radius);
00239   est2.setInputCloud (points);
00240   est2.setIndices (indices);
00241   est2.compute (output2);
00242 
00243   // All three of the above cases should produce equivalent results
00244   checkDesc<OutputT> (output0, output1);
00245   checkDesc<OutputT> (output1, output2);
00246 
00247   //
00248   // Test the combination of setIndices and setSearchSurface
00249   //
00250   PointCloud<OutputT> output3, output4;
00251 
00252   boost::shared_ptr<vector<int> > indices2 (new vector<int> (0));
00253   for (size_t i = 0; i < (indices->size ()/2); ++i)
00254     indices2->push_back (static_cast<int> (i));
00255 
00256   // Compute with all points as search surface + the specified sub-cloud as "input" but for only a subset of indices
00257   FeatureEstimation est3 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>()(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00258   est3.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00259   est3.setRadiusSearch (radius);
00260   est3.setSearchSurface (points);
00261   est3.setInputCloud (subpoints);
00262   est3.setIndices (indices2);
00263   est3.compute (output3);
00264 
00265   // Start with features for each point in "subpoints" and then subsample the results
00266   shotCopyPointCloud<OutputT> (output0, *indices2, output4); // (Re-using "output0" from above)
00267 
00268   // The two cases above should produce equivalent results
00269   checkDesc<OutputT> (output3, output4);
00270 }
00271 
00273 template <typename FeatureEstimation, typename PointT, typename NormalT, typename OutputT> void
00274 testSHOTLocalReferenceFrame (const typename PointCloud<PointT>::Ptr & points,
00275                              const typename PointCloud<NormalT>::Ptr & normals,
00276                              const boost::shared_ptr<vector<int> > & indices,
00277                              const int nr_shape_bins = 10,
00278                              const int nr_color_bins = 30,
00279                              const bool describe_shape = true,
00280                              const bool describe_color = false)
00281 {
00282   double radius = 0.04;
00283 
00284   typename PointCloud<PointT>::Ptr subpoints (new PointCloud<PointT> ());
00285   copyPointCloud (*points, *indices, *subpoints);
00286 
00287   boost::shared_ptr<vector<int> > indices2 (new vector<int> (0));
00288   for (size_t i = 0; i < (indices->size ()/2); ++i)
00289     indices2->push_back (static_cast<int> (i));
00290   //
00291   // Test an external computation for the local reference frames
00292   //
00293   PointCloud<ReferenceFrame>::Ptr frames (new PointCloud<ReferenceFrame> ());
00294   SHOTLocalReferenceFrameEstimation<PointT, pcl::ReferenceFrame> lrf_estimator;
00295   lrf_estimator.setRadiusSearch (radius);
00296   lrf_estimator.setInputCloud (subpoints);
00297   lrf_estimator.setIndices (indices2);
00298   lrf_estimator.setSearchSurface(points);
00299   lrf_estimator.compute (*frames);
00300 
00301   PointCloud<OutputT> output, output2;
00302 
00303   FeatureEstimation est = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>()(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00304   est.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00305   est.setRadiusSearch (radius);
00306   est.setSearchSurface (points);
00307   est.setInputCloud (subpoints);
00308   est.setIndices (indices2);
00309   est.compute (output);
00310 
00311   FeatureEstimation est2 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>()(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00312   est2.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00313   est2.setRadiusSearch (radius);
00314   est2.setSearchSurface (points);
00315   est2.setInputCloud (subpoints);
00316   est2.setIndices (indices2);
00317   est2.setInputReferenceFrames (frames);
00318   est2.compute (output2);
00319 
00320   // Check frames
00321   pcl::PointCloud<pcl::ReferenceFrame>::ConstPtr f = est.getInputReferenceFrames ();
00322   pcl::PointCloud<pcl::ReferenceFrame>::ConstPtr f2 = est2.getInputReferenceFrames ();
00323   ASSERT_EQ (frames->points.size (), f->points.size ());
00324   ASSERT_EQ (f2->points.size (), f->points.size ());
00325   for (int i = 0; i < static_cast<int> (frames->points.size ()); ++i)
00326   {
00327     for (unsigned j = 0; j < 9; ++j)
00328       ASSERT_EQ (frames->points[i].rf[j], f->points[i].rf[j]);
00329 
00330     for (unsigned j = 0; j < 9; ++j)
00331       ASSERT_EQ (frames->points[i].rf[j], f2->points[i].rf[j]);
00332   }
00333 
00334   // The two cases above should produce equivalent results
00335   checkDesc<OutputT> (output, output2);
00336 }
00337 
00339 TEST (PCL, SHOTShapeEstimation)
00340 {
00341   // Estimate normals first
00342   double mr = 0.002;
00343   NormalEstimation<PointXYZ, Normal> n;
00344   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00345   // set parameters
00346   n.setInputCloud (cloud.makeShared ());
00347   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00348   n.setIndices (indicesptr);
00349   n.setSearchMethod (tree);
00350   n.setRadiusSearch (20 * mr);
00351   n.compute (*normals);
00352 
00353   EXPECT_NEAR (normals->points[103].normal_x, 0.36683175, 1e-4);
00354   EXPECT_NEAR (normals->points[103].normal_y, -0.44696972, 1e-4);
00355   EXPECT_NEAR (normals->points[103].normal_z, -0.81587529, 1e-4);
00356   EXPECT_NEAR (normals->points[200].normal_x, -0.71414840, 1e-4);
00357   EXPECT_NEAR (normals->points[200].normal_y, -0.06002361, 1e-4);
00358   EXPECT_NEAR (normals->points[200].normal_z, -0.69741613, 1e-4);
00359 
00360   EXPECT_NEAR (normals->points[140].normal_x, -0.45109111, 1e-4);
00361   EXPECT_NEAR (normals->points[140].normal_y, -0.19499126, 1e-4);
00362   EXPECT_NEAR (normals->points[140].normal_z, -0.87091631, 1e-4);
00363 
00364 /*
00365   SHOTEstimation<PointXYZ, Normal, SHOT> shot;
00366   shot.setInputNormals (normals);
00367   EXPECT_EQ (shot.getInputNormals (), normals);
00368   shot.setRadiusSearch (20 * mr);
00369 
00370   // Object
00371   PointCloud<SHOT>::Ptr shots (new PointCloud<SHOT> ());
00372 
00373   // set parameters
00374   shot.setInputCloud (cloud.makeShared ());
00375   shot.setIndices (indicesptr);
00376   shot.setSearchMethod (tree);
00377 
00378   // estimate
00379   shot.compute (*shots);
00380   EXPECT_EQ (shots->points.size (), indices.size ());
00381 
00382   EXPECT_NEAR (shots->points[103].descriptor[9 ], 0.0072018504, 1e-4);
00383   EXPECT_NEAR (shots->points[103].descriptor[10], 0.0023103887, 1e-4);
00384   EXPECT_NEAR (shots->points[103].descriptor[11], 0.0024724449, 1e-4);
00385   EXPECT_NEAR (shots->points[103].descriptor[19], 0.0031367359, 1e-4);
00386   EXPECT_NEAR (shots->points[103].descriptor[20], 0.17439659, 1e-4);
00387   EXPECT_NEAR (shots->points[103].descriptor[21], 0.070665278, 1e-4);
00388   EXPECT_NEAR (shots->points[103].descriptor[42], 0.013304681, 1e-4);
00389   EXPECT_NEAR (shots->points[103].descriptor[53], 0.0073520984, 1e-4);
00390   EXPECT_NEAR (shots->points[103].descriptor[54], 0.013584172, 1e-4);
00391   EXPECT_NEAR (shots->points[103].descriptor[55], 0.0050609680, 1e-4);
00392 */
00393 
00394   // SHOT352
00395   SHOTEstimation<PointXYZ, Normal, SHOT352> shot352;
00396   shot352.setInputNormals (normals);
00397   EXPECT_EQ (shot352.getInputNormals (), normals);
00398   shot352.setRadiusSearch (20 * mr);
00399 
00400   // Object
00401   PointCloud<SHOT352>::Ptr shots352 (new PointCloud<SHOT352> ());
00402 
00403   // set parameters
00404   shot352.setInputCloud (cloud.makeShared ());
00405   shot352.setIndices (indicesptr);
00406   shot352.setSearchMethod (tree);
00407 
00408   // estimate
00409   shot352.compute (*shots352);
00410   EXPECT_EQ (shots352->points.size (), indices.size ());
00411 
00412   EXPECT_NEAR (shots352->points[103].descriptor[9 ], 0.0072018504, 1e-4);
00413   EXPECT_NEAR (shots352->points[103].descriptor[10], 0.0023103887, 1e-4);
00414   EXPECT_NEAR (shots352->points[103].descriptor[11], 0.0024724449, 1e-4);
00415   EXPECT_NEAR (shots352->points[103].descriptor[19], 0.0031367359, 1e-4);
00416   EXPECT_NEAR (shots352->points[103].descriptor[20], 0.17439659, 1e-4);
00417   EXPECT_NEAR (shots352->points[103].descriptor[21], 0.070665278, 1e-4);
00418   EXPECT_NEAR (shots352->points[103].descriptor[42], 0.013304681, 1e-4);
00419   EXPECT_NEAR (shots352->points[103].descriptor[53], 0.0073520984, 1e-4);
00420   EXPECT_NEAR (shots352->points[103].descriptor[54], 0.013584172, 1e-4);
00421   EXPECT_NEAR (shots352->points[103].descriptor[55], 0.0050609680, 1e-4);
00422 
00423 
00424   // Test results when setIndices and/or setSearchSurface are used
00425 
00426   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00427   for (size_t i = 0; i < cloud.size (); i+=3)
00428     test_indices->push_back (static_cast<int> (i));
00429 
00430   //testSHOTIndicesAndSearchSurface<SHOTEstimation<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices);
00431   //testSHOTLocalReferenceFrame<SHOTEstimation<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices);
00432 
00433   testSHOTIndicesAndSearchSurface<SHOTEstimation<PointXYZ, Normal, SHOT352>, PointXYZ, Normal, SHOT352> (cloud.makeShared (), normals, test_indices);
00434   testSHOTLocalReferenceFrame<SHOTEstimation<PointXYZ, Normal, SHOT352>, PointXYZ, Normal, SHOT352> (cloud.makeShared (), normals, test_indices);
00435 }
00436 
00438 /*
00439 TEST (PCL, GenericSHOTShapeEstimation)
00440 {
00441   // SHOT length
00442   const int shapeStep_ = 20;
00443   //const int dim = 32*(shapeStep_+1);
00444 
00445   // Estimate normals first
00446   double mr = 0.002;
00447   NormalEstimation<PointXYZ, Normal> n;
00448   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00449   // set parameters
00450   n.setInputCloud (cloud.makeShared ());
00451   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00452   n.setIndices (indicesptr);
00453   n.setSearchMethod (tree);
00454   n.setRadiusSearch (20 * mr);
00455   n.compute (*normals);
00456 
00457   SHOTEstimation<PointXYZ, Normal, SHOT> shot (shapeStep_);
00458   shot.setInputNormals (normals);
00459   EXPECT_EQ (shot.getInputNormals (), normals);
00460 
00461   shot.setRadiusSearch (20 * mr);
00462 
00463   PointCloud< SHOT >::Ptr shots (new PointCloud< SHOT > ());
00464 
00465   // set parameters
00466   shot.setInputCloud (cloud.makeShared ());
00467   shot.setIndices (indicesptr);
00468   shot.setSearchMethod (tree);
00469 
00470   // estimate
00471   shot.compute (*shots);
00472   EXPECT_EQ (shots->points.size (), indices.size ());
00473 
00474   EXPECT_NEAR (shots->points[103].descriptor[18], 0.0077019366, 1e-5);
00475   EXPECT_NEAR (shots->points[103].descriptor[19], 0.0024708188, 1e-5);
00476   EXPECT_NEAR (shots->points[103].descriptor[21], 0.0079652183, 1e-5);
00477   EXPECT_NEAR (shots->points[103].descriptor[38], 0.0067090928, 1e-5);
00478   EXPECT_NEAR (shots->points[103].descriptor[39], 0.17498907, 1e-5);
00479   EXPECT_NEAR (shots->points[103].descriptor[40], 0.078413926, 1e-5);
00480   EXPECT_NEAR (shots->points[103].descriptor[81], 0.014228539, 1e-5);
00481   EXPECT_NEAR (shots->points[103].descriptor[103], 0.022390056, 1e-5);
00482   EXPECT_NEAR (shots->points[103].descriptor[105], 0.0058866320, 1e-5);
00483   EXPECT_NEAR (shots->points[103].descriptor[123], 0.019105887, 1e-5);
00484 
00485   // Test results when setIndices and/or setSearchSurface are used
00486   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00487   for (size_t i = 0; i < cloud.size (); i+=3)
00488     test_indices->push_back (static_cast<int> (i));
00489 
00490   testSHOTIndicesAndSearchSurface<SHOTEstimation<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices, shapeStep_);
00491   testSHOTLocalReferenceFrame<SHOTEstimation<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices, shapeStep_);
00492 }
00493 */
00495 TEST (PCL, SHOTShapeAndColorEstimation)
00496 {
00497   double mr = 0.002;
00498   // Estimate normals first
00499   NormalEstimation<PointXYZ, Normal> n;
00500   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00501   // set parameters
00502   n.setInputCloud (cloud.makeShared ());
00503   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00504   n.setIndices (indicesptr);
00505   n.setSearchMethod (tree);
00506   n.setRadiusSearch (20 * mr);
00507   n.compute (*normals);
00508 
00509   search::KdTree<PointXYZRGBA>::Ptr rgbaTree;
00510   rgbaTree.reset (new search::KdTree<PointXYZRGBA> (false));
00511 
00512   // Create fake point cloud with colors
00513   PointCloud<PointXYZRGBA> cloudWithColors;
00514   for (int i = 0; i < static_cast<int> (cloud.points.size ()); ++i)
00515   {
00516     PointXYZRGBA p;
00517     p.x = cloud.points[i].x;
00518     p.y = cloud.points[i].y;
00519     p.z = cloud.points[i].z;
00520 
00521     p.rgba = ( (i%255) << 16 ) + ( ( (255 - i ) %255) << 8) + ( ( i*37 ) %255);
00522     cloudWithColors.push_back(p);
00523   }
00524 
00525 /*
00526   // Object
00527   SHOTEstimation<PointXYZRGBA, Normal, SHOT> shot (true, true);
00528   shot.setInputNormals (normals);
00529   EXPECT_EQ (shot.getInputNormals (), normals);
00530 
00531   shot.setRadiusSearch ( 20 * mr);
00532 
00533   rgbaTree->setInputCloud (cloudWithColors.makeShared ());
00534   PointCloud<SHOT>::Ptr shots (new PointCloud<SHOT>);
00535 
00536   shot.setInputCloud (cloudWithColors.makeShared ());
00537   shot.setIndices (indicesptr);
00538   shot.setSearchMethod (rgbaTree);
00539 
00540   // estimate
00541   shot.compute (*shots);
00542   EXPECT_EQ (shots->points.size (), indices.size ());
00543 
00544   EXPECT_NEAR (shots->points[103].descriptor[10], 0.0020453099, 1e-5);
00545   EXPECT_NEAR (shots->points[103].descriptor[11], 0.0021887729, 1e-5);
00546   EXPECT_NEAR (shots->points[103].descriptor[21], 0.062557608, 1e-5);
00547   EXPECT_NEAR (shots->points[103].descriptor[42], 0.011778189, 1e-5);
00548   EXPECT_NEAR (shots->points[103].descriptor[53], 0.0065085669, 1e-5);
00549   EXPECT_NEAR (shots->points[103].descriptor[54], 0.012025614, 1e-5);
00550   EXPECT_NEAR (shots->points[103].descriptor[55], 0.0044803056, 1e-5);
00551   EXPECT_NEAR (shots->points[103].descriptor[64], 0.064429596, 1e-5);
00552   EXPECT_NEAR (shots->points[103].descriptor[65], 0.046486385, 1e-5);
00553   EXPECT_NEAR (shots->points[103].descriptor[86], 0.011518310, 1e-5);
00554 
00555   EXPECT_NEAR (shots->points[103].descriptor[357], 0.0020453099, 1e-5);
00556   EXPECT_NEAR (shots->points[103].descriptor[360], 0.0027993850, 1e-5);
00557   EXPECT_NEAR (shots->points[103].descriptor[386], 0.045115642, 1e-5);
00558   EXPECT_NEAR (shots->points[103].descriptor[387], 0.059068538, 1e-5);
00559   EXPECT_NEAR (shots->points[103].descriptor[389], 0.0047547864, 1e-5);
00560   EXPECT_NEAR (shots->points[103].descriptor[453], 0.0051176427, 1e-5);
00561   EXPECT_NEAR (shots->points[103].descriptor[481], 0.0053625242, 1e-5);
00562   EXPECT_NEAR (shots->points[103].descriptor[482], 0.012025614, 1e-5);
00563   EXPECT_NEAR (shots->points[103].descriptor[511], 0.0057367259, 1e-5);
00564   EXPECT_NEAR (shots->points[103].descriptor[512], 0.048357654, 1e-5);
00565 */
00566 
00567   // SHOT1344
00568   SHOTColorEstimation<PointXYZRGBA, Normal, SHOT1344> shot1344 (true, true);
00569   shot1344.setInputNormals (normals);
00570   EXPECT_EQ (shot1344.getInputNormals (), normals);
00571 
00572   shot1344.setRadiusSearch ( 20 * mr);
00573 
00574   PointCloud<SHOT1344>::Ptr shots1344 (new PointCloud<SHOT1344>);
00575 
00576   shot1344.setInputCloud (cloudWithColors.makeShared ());
00577   shot1344.setIndices (indicesptr);
00578   shot1344.setSearchMethod (rgbaTree);
00579 
00580   // estimate
00581   shot1344.compute (*shots1344);
00582   EXPECT_EQ (shots1344->points.size (), indices.size ());
00583 
00584   EXPECT_NEAR (shots1344->points[103].descriptor[10], 0.0020453099, 1e-5);
00585   EXPECT_NEAR (shots1344->points[103].descriptor[11], 0.0021887729, 1e-5);
00586   EXPECT_NEAR (shots1344->points[103].descriptor[21], 0.062557608, 1e-5);
00587   EXPECT_NEAR (shots1344->points[103].descriptor[42], 0.011778189, 1e-5);
00588   EXPECT_NEAR (shots1344->points[103].descriptor[53], 0.0065085669, 1e-5);
00589   EXPECT_NEAR (shots1344->points[103].descriptor[54], 0.012025614, 1e-5);
00590   EXPECT_NEAR (shots1344->points[103].descriptor[55], 0.0044803056, 1e-5);
00591   EXPECT_NEAR (shots1344->points[103].descriptor[64], 0.064429596, 1e-5);
00592   EXPECT_NEAR (shots1344->points[103].descriptor[65], 0.046486385, 1e-5);
00593   EXPECT_NEAR (shots1344->points[103].descriptor[86], 0.011518310, 1e-5);
00594 
00595   EXPECT_NEAR (shots1344->points[103].descriptor[357], 0.0020453099, 1e-5);
00596   EXPECT_NEAR (shots1344->points[103].descriptor[360], 0.0027993850, 1e-5);
00597   EXPECT_NEAR (shots1344->points[103].descriptor[386], 0.045115642, 1e-5);
00598   EXPECT_NEAR (shots1344->points[103].descriptor[387], 0.059068538, 1e-5);
00599   EXPECT_NEAR (shots1344->points[103].descriptor[389], 0.0047547864, 1e-5);
00600   EXPECT_NEAR (shots1344->points[103].descriptor[453], 0.0051176427, 1e-5);
00601   EXPECT_NEAR (shots1344->points[103].descriptor[481], 0.0053625242, 1e-5);
00602   EXPECT_NEAR (shots1344->points[103].descriptor[482], 0.012025614, 1e-5);
00603   EXPECT_NEAR (shots1344->points[103].descriptor[511], 0.0057367259, 1e-5);
00604   EXPECT_NEAR (shots1344->points[103].descriptor[512], 0.048357654, 1e-5);
00605 
00606   // Test results when setIndices and/or setSearchSurface are used
00607   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00608   for (size_t i = 0; i < cloud.size (); i+=3)
00609     test_indices->push_back (static_cast<int> (i));
00610 
00611   //testSHOTIndicesAndSearchSurface<SHOTEstimation<PointXYZRGBA, Normal, SHOT>, PointXYZRGBA, Normal, SHOT> (cloudWithColors.makeShared (), normals, test_indices);
00612   //testSHOTLocalReferenceFrame<SHOTEstimation<PointXYZRGBA, Normal, SHOT>, PointXYZRGBA, Normal, SHOT> (cloudWithColors.makeShared (), normals, test_indices);
00613 
00614   testSHOTIndicesAndSearchSurface<SHOTColorEstimation<PointXYZRGBA, Normal, SHOT1344>, PointXYZRGBA, Normal, SHOT1344> (cloudWithColors.makeShared (), normals, test_indices);
00615   testSHOTLocalReferenceFrame<SHOTColorEstimation<PointXYZRGBA, Normal, SHOT1344>, PointXYZRGBA, Normal, SHOT1344> (cloudWithColors.makeShared (), normals, test_indices);
00616 }
00617 
00619 TEST (PCL, SHOTShapeEstimationOpenMP)
00620 {
00621   // Estimate normals first
00622   double mr = 0.002;
00623 #ifdef _OPENMP
00624   NormalEstimationOMP<PointXYZ, Normal> n (omp_get_max_threads ());
00625 #else
00626   NormalEstimationOMP<PointXYZ, Normal> n;
00627 #endif
00628   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00629   // set parameters
00630   n.setInputCloud (cloud.makeShared ());
00631   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00632   n.setIndices (indicesptr);
00633   n.setSearchMethod (tree);
00634   n.setRadiusSearch (20 * mr);
00635   n.compute (*normals);
00636 
00637 /*
00638   SHOTEstimationOMP<PointXYZ, Normal, SHOT> shot;
00639   shot.setInputNormals (normals);
00640   EXPECT_EQ (shot.getInputNormals (), normals);
00641 
00642   shot.setRadiusSearch ( 20 * mr);
00643 
00644   // Object
00645   PointCloud<SHOT>::Ptr shots (new PointCloud<SHOT>);
00646 
00647   // set parameters
00648   shot.setInputCloud (cloud.makeShared ());
00649   shot.setIndices (indicesptr);
00650   shot.setSearchMethod (tree);
00651 
00652   // estimate
00653   shot.compute (*shots);
00654   EXPECT_EQ (shots->points.size (), indices.size ());
00655 
00656   EXPECT_NEAR (shots->points[103].descriptor[9 ], 0.0072018504, 1e-4);
00657   EXPECT_NEAR (shots->points[103].descriptor[10], 0.0023103887, 1e-4);
00658   EXPECT_NEAR (shots->points[103].descriptor[11], 0.0024724449, 1e-4);
00659   EXPECT_NEAR (shots->points[103].descriptor[19], 0.0031367359, 1e-4);
00660   EXPECT_NEAR (shots->points[103].descriptor[20], 0.17439659, 1e-4);
00661   EXPECT_NEAR (shots->points[103].descriptor[21], 0.070665278, 1e-4);
00662   EXPECT_NEAR (shots->points[103].descriptor[42], 0.013304681, 1e-4);
00663   EXPECT_NEAR (shots->points[103].descriptor[53], 0.0073520984, 1e-4);
00664   EXPECT_NEAR (shots->points[103].descriptor[54], 0.013584172, 1e-4);
00665   EXPECT_NEAR (shots->points[103].descriptor[55], 0.0050609680, 1e-4);
00666 */
00667 
00668   // SHOT352
00669   SHOTEstimationOMP<PointXYZ, Normal, SHOT352> shot352;
00670   shot352.setInputNormals (normals);
00671   EXPECT_EQ (shot352.getInputNormals (), normals);
00672 
00673   shot352.setRadiusSearch ( 20 * mr);
00674 
00675   // Object
00676   PointCloud<SHOT352>::Ptr shots352 (new PointCloud<SHOT352>);
00677 
00678   // set parameters
00679   shot352.setInputCloud (cloud.makeShared ());
00680   shot352.setIndices (indicesptr);
00681   shot352.setSearchMethod (tree);
00682 
00683   // estimate
00684   shot352.compute (*shots352);
00685   EXPECT_EQ (shots352->points.size (), indices.size ());
00686 
00687   EXPECT_NEAR (shots352->points[103].descriptor[9 ], 0.0072018504, 1e-4);
00688   EXPECT_NEAR (shots352->points[103].descriptor[10], 0.0023103887, 1e-4);
00689   EXPECT_NEAR (shots352->points[103].descriptor[11], 0.0024724449, 1e-4);
00690   EXPECT_NEAR (shots352->points[103].descriptor[19], 0.0031367359, 1e-4);
00691   EXPECT_NEAR (shots352->points[103].descriptor[20], 0.17439659, 1e-4);
00692   EXPECT_NEAR (shots352->points[103].descriptor[21], 0.070665278, 1e-4);
00693   EXPECT_NEAR (shots352->points[103].descriptor[42], 0.013304681, 1e-4);
00694   EXPECT_NEAR (shots352->points[103].descriptor[53], 0.0073520984, 1e-4);
00695   EXPECT_NEAR (shots352->points[103].descriptor[54], 0.013584172, 1e-4);
00696   EXPECT_NEAR (shots352->points[103].descriptor[55], 0.0050609680, 1e-4);
00697 
00698   // Test results when setIndices and/or setSearchSurface are used
00699   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00700   for (size_t i = 0; i < cloud.size (); i+=3)
00701     test_indices->push_back (static_cast<int> (i));
00702 
00703   //testSHOTIndicesAndSearchSurface<SHOTEstimationOMP<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices);
00704   //testSHOTLocalReferenceFrame<SHOTEstimationOMP<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices);
00705 
00706   testSHOTIndicesAndSearchSurface<SHOTEstimationOMP<PointXYZ, Normal, SHOT352>, PointXYZ, Normal, SHOT352> (cloud.makeShared (), normals, test_indices);
00707   testSHOTLocalReferenceFrame<SHOTEstimationOMP<PointXYZ, Normal, SHOT352>, PointXYZ, Normal, SHOT352> (cloud.makeShared (), normals, test_indices);
00708 }
00709 
00711 TEST (PCL,SHOTShapeAndColorEstimationOpenMP)
00712 {
00713   double mr = 0.002;
00714   // Estimate normals first
00715   NormalEstimation<PointXYZ, Normal> n;
00716   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00717   // set parameters
00718   n.setInputCloud (cloud.makeShared ());
00719   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00720   n.setIndices (indicesptr);
00721   n.setSearchMethod (tree);
00722   n.setRadiusSearch (20 * mr);
00723   n.compute (*normals);
00724 
00725   search::KdTree<PointXYZRGBA>::Ptr rgbaTree;
00726 
00727   rgbaTree.reset (new search::KdTree<PointXYZRGBA> (false));
00728 
00729   // Create fake point cloud with colors
00730   PointCloud<PointXYZRGBA> cloudWithColors;
00731   for (int i = 0; i < static_cast<int> (cloud.points.size ()); ++i)
00732   {
00733     PointXYZRGBA p;
00734     p.x = cloud.points[i].x;
00735     p.y = cloud.points[i].y;
00736     p.z = cloud.points[i].z;
00737 
00738     p.rgba = ( (i%255) << 16 ) + ( ( (255 - i ) %255) << 8) + ( ( i*37 ) %255);
00739     cloudWithColors.push_back(p);
00740   }
00741 
00742 /*
00743   // Object
00744   SHOTEstimationOMP<PointXYZRGBA, Normal, SHOT> shot (true, true, -1);
00745   shot.setInputNormals (normals);
00746 
00747   EXPECT_EQ (shot.getInputNormals (), normals);
00748 
00749   shot.setRadiusSearch ( 20 * mr);
00750 
00751   rgbaTree->setInputCloud (cloudWithColors.makeShared ());
00752 
00753   PointCloud<SHOT>::Ptr shots (new PointCloud<SHOT> ());
00754 
00755   shot.setInputCloud (cloudWithColors.makeShared ());
00756   shot.setIndices (indicesptr);
00757   shot.setSearchMethod (rgbaTree);
00758 
00759   // estimate
00760   shot.compute (*shots);
00761   EXPECT_EQ (shots->points.size (), indices.size ());
00762 
00763   EXPECT_NEAR (shots->points[103].descriptor[10], 0.0020453099, 1e-5);
00764   EXPECT_NEAR (shots->points[103].descriptor[11], 0.0021887729, 1e-5);
00765   EXPECT_NEAR (shots->points[103].descriptor[21], 0.062557608, 1e-5);
00766   EXPECT_NEAR (shots->points[103].descriptor[42], 0.011778189, 1e-5);
00767   EXPECT_NEAR (shots->points[103].descriptor[53], 0.0065085669, 1e-5);
00768   EXPECT_NEAR (shots->points[103].descriptor[54], 0.012025614, 1e-5);
00769   EXPECT_NEAR (shots->points[103].descriptor[55], 0.0044803056, 1e-5);
00770   EXPECT_NEAR (shots->points[103].descriptor[64], 0.064429596, 1e-5);
00771   EXPECT_NEAR (shots->points[103].descriptor[65], 0.046486385, 1e-5);
00772   EXPECT_NEAR (shots->points[103].descriptor[86], 0.011518310, 1e-5);
00773 
00774   EXPECT_NEAR (shots->points[103].descriptor[357], 0.0020453099, 1e-5);
00775   EXPECT_NEAR (shots->points[103].descriptor[360], 0.0027993850, 1e-5);
00776   EXPECT_NEAR (shots->points[103].descriptor[386], 0.045115642, 1e-5);
00777   EXPECT_NEAR (shots->points[103].descriptor[387], 0.059068538, 1e-5);
00778   EXPECT_NEAR (shots->points[103].descriptor[389], 0.0047547864, 1e-5);
00779   EXPECT_NEAR (shots->points[103].descriptor[453], 0.0051176427, 1e-5);
00780   EXPECT_NEAR (shots->points[103].descriptor[481], 0.0053625242, 1e-5);
00781   EXPECT_NEAR (shots->points[103].descriptor[482], 0.012025614, 1e-5);
00782   EXPECT_NEAR (shots->points[103].descriptor[511], 0.0057367259, 1e-5);
00783   EXPECT_NEAR (shots->points[103].descriptor[512], 0.048357654, 1e-5);
00784 */
00785 
00786   // SHOT1344
00787   SHOTColorEstimationOMP<PointXYZRGBA, Normal, SHOT1344> shot1344 (true, true);
00788   shot1344.setInputNormals (normals);
00789 
00790   EXPECT_EQ (shot1344.getInputNormals (), normals);
00791 
00792   shot1344.setRadiusSearch ( 20 * mr);
00793 
00794   PointCloud<SHOT1344>::Ptr shots1344 (new PointCloud<SHOT1344> ());
00795 
00796   shot1344.setInputCloud (cloudWithColors.makeShared ());
00797   shot1344.setIndices (indicesptr);
00798   shot1344.setSearchMethod (rgbaTree);
00799 
00800   // estimate
00801   shot1344.compute (*shots1344);
00802   EXPECT_EQ (shots1344->points.size (), indices.size ());
00803 
00804   EXPECT_NEAR (shots1344->points[103].descriptor[10], 0.0020453099, 1e-5);
00805   EXPECT_NEAR (shots1344->points[103].descriptor[11], 0.0021887729, 1e-5);
00806   EXPECT_NEAR (shots1344->points[103].descriptor[21], 0.062557608, 1e-5);
00807   EXPECT_NEAR (shots1344->points[103].descriptor[42], 0.011778189, 1e-5);
00808   EXPECT_NEAR (shots1344->points[103].descriptor[53], 0.0065085669, 1e-5);
00809   EXPECT_NEAR (shots1344->points[103].descriptor[54], 0.012025614, 1e-5);
00810   EXPECT_NEAR (shots1344->points[103].descriptor[55], 0.0044803056, 1e-5);
00811   EXPECT_NEAR (shots1344->points[103].descriptor[64], 0.064429596, 1e-5);
00812   EXPECT_NEAR (shots1344->points[103].descriptor[65], 0.046486385, 1e-5);
00813   EXPECT_NEAR (shots1344->points[103].descriptor[86], 0.011518310, 1e-5);
00814 
00815   EXPECT_NEAR (shots1344->points[103].descriptor[357], 0.0020453099, 1e-5);
00816   EXPECT_NEAR (shots1344->points[103].descriptor[360], 0.0027993850, 1e-5);
00817   EXPECT_NEAR (shots1344->points[103].descriptor[386], 0.045115642, 1e-5);
00818   EXPECT_NEAR (shots1344->points[103].descriptor[387], 0.059068538, 1e-5);
00819   EXPECT_NEAR (shots1344->points[103].descriptor[389], 0.0047547864, 1e-5);
00820   EXPECT_NEAR (shots1344->points[103].descriptor[453], 0.0051176427, 1e-5);
00821   EXPECT_NEAR (shots1344->points[103].descriptor[481], 0.0053625242, 1e-5);
00822   EXPECT_NEAR (shots1344->points[103].descriptor[482], 0.012025614, 1e-5);
00823   EXPECT_NEAR (shots1344->points[103].descriptor[511], 0.0057367259, 1e-5);
00824   EXPECT_NEAR (shots1344->points[103].descriptor[512], 0.048357654, 1e-5);
00825 
00826   // Test results when setIndices and/or setSearchSurface are used
00827   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00828   for (size_t i = 0; i < cloud.size (); i+=3)
00829     test_indices->push_back (static_cast<int> (i));
00830 
00831   //testSHOTIndicesAndSearchSurface<SHOTEstimationOMP<PointXYZRGBA, Normal, SHOT>, PointXYZRGBA, Normal, SHOT> (cloudWithColors.makeShared (), normals, test_indices);
00832   //testSHOTLocalReferenceFrame<SHOTEstimationOMP<PointXYZRGBA, Normal, SHOT>, PointXYZRGBA, Normal, SHOT> (cloudWithColors.makeShared (), normals, test_indices);
00833 
00834   testSHOTIndicesAndSearchSurface<SHOTColorEstimationOMP<PointXYZRGBA, Normal, SHOT1344>, PointXYZRGBA, Normal, SHOT1344> (cloudWithColors.makeShared (), normals, test_indices);
00835   testSHOTLocalReferenceFrame<SHOTColorEstimationOMP<PointXYZRGBA, Normal, SHOT1344>, PointXYZRGBA, Normal, SHOT1344> (cloudWithColors.makeShared (), normals, test_indices);
00836 }
00837 
00839 TEST (PCL,3DSCEstimation)
00840 {
00841   float meshRes = 0.002f;
00842   //size_t nBinsL = 4;
00843   //size_t nBinsK = 4;
00844   //size_t nBinsJ = 4;
00845   float radius = 20.0f * meshRes;
00846   float rmin = radius / 10.0f;
00847   float ptDensityRad = radius / 5.0f;
00848 
00849   PointCloud<PointXYZ>::Ptr cloudptr = cloud.makeShared ();
00850 
00851   // Estimate normals first
00852   NormalEstimation<PointXYZ, Normal> ne;
00853   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00854   // set parameters
00855   ne.setInputCloud (cloudptr);
00856   ne.setSearchMethod (tree);
00857   ne.setRadiusSearch (radius);
00858   // estimate
00859   ne.compute (*normals);
00860 
00861   ShapeContext3DEstimation<PointXYZ, Normal, ShapeContext1980> sc3d;
00862   sc3d.setInputCloud (cloudptr);
00863   sc3d.setInputNormals (normals);
00864   sc3d.setSearchMethod (tree);
00865   sc3d.setRadiusSearch (radius);
00866   //sc3d.setAzimuthBins (nBinsL);
00867   //sc3d.setElevationBins (nBinsK);
00868   //sc3d.setRadiusBins (nBinsJ);
00869   sc3d.setMinimalRadius (rmin);
00870   sc3d.setPointDensityRadius (ptDensityRad);
00871   // Compute the features
00872   PointCloud<ShapeContext1980>::Ptr sc3ds (new PointCloud<ShapeContext1980> ());
00873   sc3d.compute (*sc3ds);
00874   EXPECT_EQ (sc3ds->size (), cloud.size ());
00875 
00876   // 3DSC does not define a repeatable local RF, we set it to zero to signal it to the user
00877   //EXPECT_NEAR ((*sc3ds)[0].rf[0], 0.2902f, 1e-4f);
00878   //EXPECT_NEAR ((*sc3ds)[0].rf[1], 0.7334f, 1e-4f);
00879   //EXPECT_NEAR ((*sc3ds)[0].rf[2], -0.6146f, 1e-4f);
00880   //EXPECT_NEAR ((*sc3ds)[0].rf[3], 0.9486f, 1e-4f);
00881   //EXPECT_NEAR ((*sc3ds)[0].rf[4], -0.3051f, 1e-4f);
00882   //EXPECT_NEAR ((*sc3ds)[0].rf[5], 0.0838f, 1e-4f);
00883   //EXPECT_NEAR ((*sc3ds)[0].rf[6], -0.1261f, 1e-4f);
00884   //EXPECT_NEAR ((*sc3ds)[0].rf[7], -0.6074f, 1e-4f);
00885   //EXPECT_NEAR ((*sc3ds)[0].rf[8], -0.7843f, 1e-4f);
00886 
00887   EXPECT_NEAR ((*sc3ds)[0].rf[0], 0.0f, 1e-4f);
00888   EXPECT_NEAR ((*sc3ds)[0].rf[1], 0.0f, 1e-4f);
00889   EXPECT_NEAR ((*sc3ds)[0].rf[2], 0.0f, 1e-4f);
00890   EXPECT_NEAR ((*sc3ds)[0].rf[3], 0.0f, 1e-4f);
00891   EXPECT_NEAR ((*sc3ds)[0].rf[4], 0.0f, 1e-4f);
00892   EXPECT_NEAR ((*sc3ds)[0].rf[5], 0.0f, 1e-4f);
00893   EXPECT_NEAR ((*sc3ds)[0].rf[6], 0.0f, 1e-4f);
00894   EXPECT_NEAR ((*sc3ds)[0].rf[7], 0.0f, 1e-4f);
00895   EXPECT_NEAR ((*sc3ds)[0].rf[8], 0.0f, 1e-4f);
00896 
00897   //EXPECT_EQ ((*sc3ds)[0].descriptor.size (), 64);
00898 
00899   EXPECT_NEAR ((*sc3ds)[94].descriptor[88], 55.2712f, 1e-4f);
00900   EXPECT_NEAR ((*sc3ds)[94].descriptor[584], 71.1088f, 1e-4f);
00901   EXPECT_NEAR ((*sc3ds)[94].descriptor[1106], 79.5896f, 1e-4f);
00902   EXPECT_NEAR ((*sc3ds)[94].descriptor[1560], 0.f, 1e-4f);
00903   EXPECT_NEAR ((*sc3ds)[94].descriptor[1929], 36.0636f, 1e-4f);
00904 
00905   EXPECT_NEAR ((*sc3ds)[108].descriptor[67], 0.f, 1e-4f);
00906   EXPECT_NEAR ((*sc3ds)[108].descriptor[548], 126.141f, 1e-4f);
00907   EXPECT_NEAR ((*sc3ds)[108].descriptor[1091], 30.4704f, 1e-4f);
00908   EXPECT_NEAR ((*sc3ds)[108].descriptor[1421], 38.088f, 1e-4f);
00909   EXPECT_NEAR ((*sc3ds)[108].descriptor[1900], 43.7994f, 1e-4f);
00910 
00911   // Test results when setIndices and/or setSearchSurface are used
00912   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00913   for (size_t i = 0; i < cloud.size (); i++)
00914     test_indices->push_back (static_cast<int> (i));
00915 
00916   testSHOTIndicesAndSearchSurface<ShapeContext3DEstimation<PointXYZ, Normal, ShapeContext1980>, PointXYZ, Normal, ShapeContext1980> (cloudptr, normals, test_indices);
00917 }
00918 
00920 TEST (PCL, USCEstimation)
00921 {
00922   float meshRes = 0.002f;
00923   //size_t nBinsL = 4;
00924   //size_t nBinsK = 4;
00925   //size_t nBinsJ = 4;
00926   float radius = 20.0f * meshRes;
00927   float rmin = radius / 10.0f;
00928   float ptDensityRad = radius / 5.0f;
00929 
00930   // estimate
00931   UniqueShapeContext<PointXYZ, ShapeContext1980> uscd;
00932   uscd.setInputCloud (cloud.makeShared ());
00933   uscd.setSearchMethod (tree);
00934   uscd.setRadiusSearch (radius);
00935   //uscd.setAzimuthBins (nBinsL);
00936   //uscd.setElevationBins (nBinsK);
00937   //uscd.setRadiusBins (nBinsJ);
00938   uscd.setMinimalRadius (rmin);
00939   uscd.setPointDensityRadius (ptDensityRad);
00940   uscd.setLocalRadius (radius);
00941   // Compute the features
00942   PointCloud<ShapeContext1980>::Ptr uscds (new PointCloud<ShapeContext1980>);
00943   uscd.compute (*uscds);
00944   EXPECT_EQ (uscds->size (), cloud.size ());
00945 
00946   EXPECT_NEAR ((*uscds)[160].rf[0], -0.97767f, 1e-4f);
00947   EXPECT_NEAR ((*uscds)[160].rf[1], 0.0353674f, 1e-4f);
00948   EXPECT_NEAR ((*uscds)[160].rf[2], -0.20715f, 1e-4f);
00949   EXPECT_NEAR ((*uscds)[160].rf[3], 0.0125394f, 1e-4f);
00950   EXPECT_NEAR ((*uscds)[160].rf[4], 0.993798f, 1e-4f);
00951   EXPECT_NEAR ((*uscds)[160].rf[5], 0.110493f, 1e-4f);
00952   EXPECT_NEAR ((*uscds)[160].rf[6], 0.209773f, 1e-4f);
00953   EXPECT_NEAR ((*uscds)[160].rf[7], 0.105428f, 1e-4f);
00954   EXPECT_NEAR ((*uscds)[160].rf[8], -0.972049f, 1e-4f);
00955 
00956   //EXPECT_EQ ((*uscds)[0].descriptor.size (), 64);
00957 
00958   EXPECT_NEAR ((*uscds)[160].descriptor[56], 53.0597f, 1e-4f);
00959   EXPECT_NEAR ((*uscds)[160].descriptor[734], 80.1063f, 1e-4f);
00960   EXPECT_NEAR ((*uscds)[160].descriptor[1222], 93.8412f, 1e-4f);
00961   EXPECT_NEAR ((*uscds)[160].descriptor[1605], 0.f, 1e-4f);
00962   EXPECT_NEAR ((*uscds)[160].descriptor[1887], 32.6679f, 1e-4f);
00963 
00964   EXPECT_NEAR ((*uscds)[168].descriptor[72], 65.3358f, 1e-4f);
00965   EXPECT_NEAR ((*uscds)[168].descriptor[430], 88.8147f, 1e-4f);
00966   EXPECT_NEAR ((*uscds)[168].descriptor[987], 0.f, 1e-4f);
00967   EXPECT_NEAR ((*uscds)[168].descriptor[1563], 128.273f, 1e-4f);
00968   EXPECT_NEAR ((*uscds)[168].descriptor[1915], 59.2098f, 1e-4f);
00969 
00970   // Test results when setIndices and/or setSearchSurface are used
00971   boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00972   for (size_t i = 0; i < cloud.size (); i+=3)
00973     test_indices->push_back (static_cast<int> (i));
00974 
00975   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00976   testSHOTIndicesAndSearchSurface<UniqueShapeContext<PointXYZ, ShapeContext1980>, PointXYZ, Normal, ShapeContext1980> (cloud.makeShared (), normals, test_indices);
00977   testSHOTLocalReferenceFrame<UniqueShapeContext<PointXYZ, ShapeContext1980>, PointXYZ, Normal, ShapeContext1980> (cloud.makeShared (), normals, test_indices);
00978 }
00979 
00980 /* ---[ */
00981 int
00982 main (int argc, char** argv)
00983 {
00984   if (argc < 2)
00985   {
00986     std::cerr << "No test file given. Please download `bun0.pcd` and pass its path to the test." << std::endl;
00987     return (-1);
00988   }
00989 
00990   if (loadPCDFile<PointXYZ> (argv[1], cloud) < 0)
00991   {
00992     std::cerr << "Failed to read test file. Please download `bun0.pcd` and pass its path to the test." << std::endl;
00993     return (-1);
00994   }
00995 
00996   indices.resize (cloud.points.size ());
00997   for (size_t i = 0; i < indices.size (); ++i)
00998     indices[i] = static_cast<int> (i);
00999 
01000   tree.reset (new search::KdTree<PointXYZ> (false));
01001   tree->setInputCloud (cloud.makeShared ());
01002 
01003   testing::InitGoogleTest (&argc, argv);
01004   return (RUN_ALL_TESTS ());
01005 }
01006 /* ]--- */


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:36:12