test_sampling.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) 2009-2012, Willow Garage, Inc.
00006  *  Copyright (c) 2012-, Open Perception, Inc.
00007  *
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of the copyright holder(s) nor the names of its
00021  *     contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  * $Id: test_filters.cpp 7683 2012-10-23 02:49:03Z rusu $
00038  *
00039  */
00040 
00041 #include <gtest/gtest.h>
00042 #include <pcl/point_types.h>
00043 #include <pcl/io/pcd_io.h>
00044 #include <pcl/features/normal_3d.h>
00045 #include <pcl/filters/covariance_sampling.h>
00046 #include <pcl/filters/normal_space.h>
00047 #include <pcl/filters/random_sample.h>
00048 
00049 
00050 #include <pcl/common/transforms.h>
00051 #include <pcl/common/eigen.h>
00052 
00053 using namespace pcl;
00054 
00055 PointCloud<PointXYZ>::Ptr cloud_walls (new PointCloud<PointXYZ> ()),
00056                           cloud_turtle (new PointCloud<PointXYZ> ());
00057 PointCloud<PointNormal>::Ptr cloud_walls_normals (new PointCloud<PointNormal> ()),
00058                              cloud_turtle_normals (new PointCloud<PointNormal> ());
00059 
00060 
00062 TEST (CovarianceSampling, Filters)
00063 {
00064   CovarianceSampling<PointNormal, PointNormal> covariance_sampling;
00065   covariance_sampling.setInputCloud (cloud_walls_normals);
00066   covariance_sampling.setNormals (cloud_walls_normals);
00067   covariance_sampling.setNumberOfSamples (static_cast<unsigned int> (cloud_walls_normals->size ()) / 4);
00068   double cond_num_walls = covariance_sampling.computeConditionNumber ();
00069   EXPECT_NEAR (113.29773, cond_num_walls, 1e-1);
00070 
00071   IndicesPtr walls_indices (new std::vector<int> ());
00072   covariance_sampling.filter (*walls_indices);
00073 
00074   covariance_sampling.setIndices (walls_indices);
00075   double cond_num_walls_sampled = covariance_sampling.computeConditionNumber ();
00076   EXPECT_NEAR (22.11506, cond_num_walls_sampled, 1e-1);
00077 
00078   EXPECT_EQ (686, (*walls_indices)[0]);
00079   EXPECT_EQ (1900, (*walls_indices)[walls_indices->size () / 4]);
00080   EXPECT_EQ (1278, (*walls_indices)[walls_indices->size () / 2]);
00081   EXPECT_EQ (2960, (*walls_indices)[walls_indices->size () * 3 / 4]);
00082   EXPECT_EQ (2060, (*walls_indices)[walls_indices->size () - 1]);
00083 
00084   covariance_sampling.setInputCloud (cloud_turtle_normals);
00085   covariance_sampling.setNormals (cloud_turtle_normals);
00086   covariance_sampling.setIndices (IndicesPtr ());
00087   covariance_sampling.setNumberOfSamples (static_cast<unsigned int> (cloud_turtle_normals->size ()) / 8);
00088   double cond_num_turtle = covariance_sampling.computeConditionNumber ();
00089   EXPECT_NEAR (cond_num_turtle, 20661.7663, 0.5);
00090 
00091   IndicesPtr turtle_indices (new std::vector<int> ());
00092   covariance_sampling.filter (*turtle_indices);
00093   covariance_sampling.setIndices (turtle_indices);
00094   double cond_num_turtle_sampled = covariance_sampling.computeConditionNumber ();
00095   EXPECT_NEAR (cond_num_turtle_sampled, 5795.5057, 0.5);
00096 
00097   EXPECT_EQ ((*turtle_indices)[0], 80344);
00098   EXPECT_EQ ((*turtle_indices)[turtle_indices->size () / 4], 145982);
00099   EXPECT_EQ ((*turtle_indices)[turtle_indices->size () / 2], 104557);
00100   EXPECT_EQ ((*turtle_indices)[turtle_indices->size () * 3 / 4], 41512);
00101   EXPECT_EQ ((*turtle_indices)[turtle_indices->size () - 1], 136885);
00102 }
00103 
00105 TEST (NormalSpaceSampling, Filters)
00106 {
00107   NormalSpaceSampling<PointNormal, PointNormal> normal_space_sampling;
00108   normal_space_sampling.setInputCloud (cloud_walls_normals);
00109   normal_space_sampling.setNormals (cloud_walls_normals);
00110   normal_space_sampling.setBins (4, 4, 4);
00111   normal_space_sampling.setSeed (0);
00112   normal_space_sampling.setSample (static_cast<unsigned int> (cloud_walls_normals->size ()) / 4);
00113 
00114   IndicesPtr walls_indices (new std::vector<int> ());
00115   normal_space_sampling.filter (*walls_indices);
00116 
00117   CovarianceSampling<PointNormal, PointNormal> covariance_sampling;
00118   covariance_sampling.setInputCloud (cloud_walls_normals);
00119   covariance_sampling.setNormals (cloud_walls_normals);
00120   covariance_sampling.setIndices (walls_indices);
00121   covariance_sampling.setNumberOfSamples (0);
00122   double cond_num_walls_sampled = covariance_sampling.computeConditionNumber ();
00123 
00124 
00125   EXPECT_NEAR (33.04893, cond_num_walls_sampled, 1e-1);
00126 
00127   EXPECT_EQ (1412, (*walls_indices)[0]);
00128   EXPECT_EQ (1943, (*walls_indices)[walls_indices->size () / 4]);
00129   EXPECT_EQ (2771, (*walls_indices)[walls_indices->size () / 2]);
00130   EXPECT_EQ (3215, (*walls_indices)[walls_indices->size () * 3 / 4]);
00131   EXPECT_EQ (2503, (*walls_indices)[walls_indices->size () - 1]);
00132 }
00133 
00135 TEST (RandomSample, Filters)
00136 {
00137   // Test the PointCloud<PointT> method
00138   // Randomly sample 10 points from cloud
00139   RandomSample<PointXYZ> sample (true); // Extract removed indices
00140   sample.setInputCloud (cloud_walls);
00141   sample.setSample (10);
00142 
00143   // Indices
00144   std::vector<int> indices;
00145   sample.filter (indices);
00146 
00147   EXPECT_EQ (int (indices.size ()), 10);
00148 
00149   // Cloud
00150   PointCloud<PointXYZ> cloud_out;
00151   sample.filter(cloud_out);
00152 
00153   EXPECT_EQ (int (cloud_out.width), 10);
00154   EXPECT_EQ (int (indices.size ()), int (cloud_out.size ()));
00155 
00156   for (size_t i = 0; i < indices.size () - 1; ++i)
00157   {
00158     // Check that indices are sorted
00159     EXPECT_LT (indices[i], indices[i+1]);
00160     // Compare original points with sampled indices against sampled points
00161     EXPECT_NEAR (cloud_walls->points[indices[i]].x, cloud_out.points[i].x, 1e-4);
00162     EXPECT_NEAR (cloud_walls->points[indices[i]].y, cloud_out.points[i].y, 1e-4);
00163     EXPECT_NEAR (cloud_walls->points[indices[i]].z, cloud_out.points[i].z, 1e-4);
00164   }
00165 
00166   IndicesConstPtr removed = sample.getRemovedIndices ();
00167   EXPECT_EQ (removed->size (), cloud_walls->size () - 10);
00168   // Organized
00169   // (sdmiller) Removing for now, to debug the Linux 32-bit segfault offline
00170   sample.setKeepOrganized (true);
00171   sample.filter(cloud_out);
00172   removed = sample.getRemovedIndices ();
00173   EXPECT_EQ (int (removed->size ()), cloud_walls->size () - 10);
00174   for (size_t i = 0; i < removed->size (); ++i)
00175   {
00176     EXPECT_TRUE (pcl_isnan (cloud_out.at ((*removed)[i]).x));
00177     EXPECT_TRUE (pcl_isnan (cloud_out.at ((*removed)[i]).y));
00178     EXPECT_TRUE (pcl_isnan (cloud_out.at ((*removed)[i]).z));
00179   }
00180 
00181   EXPECT_EQ (cloud_out.width, cloud_walls->width);
00182   EXPECT_EQ (cloud_out.height, cloud_walls->height);
00183   // Negative
00184   sample.setKeepOrganized (false);
00185   sample.setNegative (true);
00186   sample.filter(cloud_out);
00187   removed = sample.getRemovedIndices ();
00188   EXPECT_EQ (int (removed->size ()), 10);
00189   EXPECT_EQ (int (cloud_out.size ()), int (cloud_walls->size () - 10));
00190 
00191   // Make sure sampling >N works
00192   sample.setSample (static_cast<unsigned int> (cloud_walls->size ()+10));
00193   sample.setNegative (false);
00194   sample.filter (cloud_out);
00195   EXPECT_EQ (cloud_out.size (), cloud_walls->size ());
00196   removed = sample.getRemovedIndices ();
00197   EXPECT_TRUE (removed->empty ());
00198 
00199   // Test the pcl::PCLPointCloud2 method
00200   // Randomly sample 10 points from cloud
00201   pcl::PCLPointCloud2::Ptr cloud_blob (new pcl::PCLPointCloud2 ());
00202   toPCLPointCloud2 (*cloud_walls, *cloud_blob);
00203   RandomSample<pcl::PCLPointCloud2> sample2;
00204   sample2.setInputCloud (cloud_blob);
00205   sample2.setSample (10);
00206 
00207   // Indices
00208   std::vector<int> indices2;
00209   sample2.filter (indices2);
00210 
00211   EXPECT_EQ (int (indices2.size ()), 10);
00212 
00213   // Cloud
00214   pcl::PCLPointCloud2 output_blob;
00215   sample2.filter (output_blob);
00216 
00217   fromPCLPointCloud2 (output_blob, cloud_out);
00218 
00219   EXPECT_EQ (int (cloud_out.width), 10);
00220   EXPECT_EQ (int (indices2.size ()), int (cloud_out.size ()));
00221 
00222   for (size_t i = 0; i < indices2.size () - 1; ++i)
00223   {
00224     // Check that indices are sorted
00225     EXPECT_LT (indices2[i], indices2[i+1]);
00226     // Compare original points with sampled indices against sampled points
00227     EXPECT_NEAR (cloud_walls->points[indices2[i]].x, cloud_out.points[i].x, 1e-4);
00228     EXPECT_NEAR (cloud_walls->points[indices2[i]].y, cloud_out.points[i].y, 1e-4);
00229     EXPECT_NEAR (cloud_walls->points[indices2[i]].z, cloud_out.points[i].z, 1e-4);
00230   }
00231 }
00232 
00233 
00234 /* ---[ */
00235 int
00236 main (int argc, char** argv)
00237 {
00238   // Load two standard PCD files from disk
00239   if (argc < 3)
00240   {
00241     std::cerr << "No test files given. Please download `sac_plane_test.pcd` and 'cturtle.pcd' and pass them path to the test." << std::endl;
00242     return (-1);
00243   }
00244 
00245   // Load in the point clouds
00246   io::loadPCDFile (argv[1], *cloud_walls);
00247   io::loadPCDFile (argv[2], *cloud_turtle);
00248 
00249 
00250 
00251   // Compute the normals for each cloud, and then clean them up of any NaN values
00252   NormalEstimation<PointXYZ,PointNormal> ne;
00253   ne.setInputCloud (cloud_walls);
00254   ne.setRadiusSearch (0.05);
00255   ne.compute (*cloud_walls_normals);
00256   copyPointCloud (*cloud_walls, *cloud_walls_normals);
00257 
00258   std::vector<int> aux_indices;
00259   removeNaNFromPointCloud (*cloud_walls_normals, *cloud_walls_normals, aux_indices);
00260   removeNaNNormalsFromPointCloud (*cloud_walls_normals, *cloud_walls_normals, aux_indices);
00261 
00262   ne = NormalEstimation<PointXYZ, PointNormal> ();
00263   ne.setInputCloud (cloud_turtle);
00264   ne.setKSearch (5);
00265   ne.compute (*cloud_turtle_normals);
00266   copyPointCloud (*cloud_turtle, *cloud_turtle_normals);
00267   removeNaNFromPointCloud (*cloud_turtle_normals, *cloud_turtle_normals, aux_indices);
00268   removeNaNNormalsFromPointCloud (*cloud_turtle_normals, *cloud_turtle_normals, aux_indices);
00269 
00270   testing::InitGoogleTest (&argc, argv);
00271   return (RUN_ALL_TESTS ());
00272 }
00273 /* ]--- */


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