test_search.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2009, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id: test_ii_normals.cpp 4084 2012-01-31 02:05:42Z rusu $
00035  *
00036  */
00037 
00038 #include <gtest/gtest.h>
00039 #include <pcl/search/brute_force.h>
00040 #include <pcl/search/kdtree.h>
00041 #include <pcl/search/organized.h>
00042 #include <pcl/search/octree.h>
00043 #include <pcl/io/pcd_io.h>
00044 #include <boost/smart_ptr/shared_array.hpp>
00045 #include <boost/random/mersenne_twister.hpp>
00046 #include <boost/random/uniform_int.hpp>
00047 #include <boost/random/uniform_real.hpp>
00048 #include <boost/random/variate_generator.hpp>
00049 
00050 #include <pcl/common/time.h>
00051 
00052 using namespace pcl;
00053 using namespace std;
00054 
00056 #define DEBUG_OUT 1
00057 #define EXCESSIVE_TESTING 0
00058 
00059 #define TEST_unorganized_dense_cloud_COMPLETE_KNN     1
00060 #define TEST_unorganized_dense_cloud_VIEW_KNN         1
00061 #define TEST_unorganized_sparse_cloud_COMPLETE_KNN    1
00062 #define TEST_unorganized_sparse_cloud_VIEW_KNN        1
00063 #define TEST_unorganized_grid_cloud_COMPLETE_RADIUS   1
00064 #define TEST_unorganized_dense_cloud_COMPLETE_RADIUS  1
00065 #define TEST_unorganized_dense_cloud_VIEW_RADIUS      1
00066 #define TEST_unorganized_sparse_cloud_COMPLETE_RADIUS 1
00067 #define TEST_unorganized_sparse_cloud_VIEW_RADIUS     1
00068 #define TEST_ORGANIZED_SPARSE_COMPLETE_KNN            1
00069 #define TEST_ORGANIZED_SPARSE_VIEW_KNN                1
00070 #define TEST_ORGANIZED_SPARSE_COMPLETE_RADIUS         1
00071 #define TEST_ORGANIZED_SPARSE_VIEW_RADIUS             1
00072 
00073 #if EXCESSIVE_TESTING
00074 
00075 const unsigned int unorganized_point_count = 100000;
00076 
00078 const unsigned int query_count = 5000;
00079 #else
00080 
00081 const unsigned int unorganized_point_count = 1200;
00082 
00084 const unsigned int query_count = 100;
00085 #endif
00086 
00088 PointCloud<PointXYZ>::Ptr organized_sparse_cloud (new PointCloud<PointXYZ>);
00089 
00091 PointCloud<PointXYZ>::Ptr unorganized_dense_cloud (new PointCloud<PointXYZ>);
00092 
00094 PointCloud<PointXYZ>::Ptr unorganized_sparse_cloud (new PointCloud<PointXYZ>);
00095 
00097 PointCloud<PointXYZ>::Ptr unorganized_grid_cloud (new PointCloud<PointXYZ>);
00098 
00100 boost::variate_generator< boost::mt19937, boost::uniform_int<unsigned> > rand_uint(boost::mt19937 (), boost::uniform_int<unsigned> (0, 10));
00102 boost::variate_generator< boost::mt19937, boost::uniform_real<float> > rand_float(boost::mt19937 (), boost::uniform_real<float> (0, 1));
00103 
00105 std::vector<int> unorganized_input_indices;
00106 
00108 std::vector<int> organized_input_indices;
00109 
00111 pcl::search::BruteForce<pcl::PointXYZ> brute_force;
00112 
00114 pcl::search::KdTree<pcl::PointXYZ> KDTree;
00115 
00117 pcl::search::Octree<pcl::PointXYZ> octree_search (0.1);
00118 
00120 pcl::search::OrganizedNeighbor<pcl::PointXYZ> organized;
00121 
00123 vector<search::Search<PointXYZ>* > unorganized_search_methods;
00124 
00126 vector<search::Search<PointXYZ>* > organized_search_methods;
00127 
00129 vector<int> unorganized_dense_cloud_query_indices;
00130 vector<int> unorganized_sparse_cloud_query_indices;
00131 vector<int> organized_sparse_query_indices;
00132 
00138 bool testUniqueness (const vector<int>& indices, const string& name)
00139 {
00140   bool uniqueness = true;
00141   for (unsigned idx1 = 1; idx1 < indices.size () && uniqueness; ++idx1)
00142   {
00143     // check whether resulting indices are unique
00144     for (unsigned idx2 = 0; idx2 < idx1; ++idx2)
00145     {
00146       if (indices [idx1] == indices [idx2])
00147       {
00148 #if DEBUG_OUT
00149         std::cout << name << " search: index is twice at positions: " << idx1 << " (" << indices [idx1] << ") , " << idx2  << " (" << indices [idx2] << ")" << std::endl;
00150 #endif
00151         // can only be set to false anyway -> no sync required
00152         uniqueness = false;
00153         break;
00154       }
00155     }
00156   }
00157   return uniqueness;
00158 }
00159 
00160 
00166 bool testOrder (const vector<float>& distances, const string& name)
00167 {
00168   bool ordered = true;
00169   for (unsigned idx1 = 1; idx1 < distances.size (); ++idx1)
00170   {
00171     if (distances [idx1-1] > distances [idx1])
00172     {
00173 #if DEBUG_OUT
00174       std::cout << name << " search: not properly sorted: " << idx1 - 1 << "(" << distances [idx1-1] << ") > " 
00175                                                             << idx1     << "(" << distances [idx1]   << ")"<< std::endl;
00176 #endif
00177       ordered = false;
00178       break;
00179     }
00180   }
00181   
00182   return ordered;
00183 }
00184 
00192 template<typename PointT> bool
00193 testResultValidity (const typename PointCloud<PointT>::ConstPtr point_cloud, const vector<bool>& indices_mask, const vector<bool>& nan_mask, const vector<int>& indices, const vector<int>& /*input_indices*/, const string& name)
00194 {
00195   bool validness = true;
00196   for (vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00197   {
00198     if (!indices_mask [*iIt])
00199     {
00200 #if DEBUG_OUT
00201       cerr << name << ": result contains an invalid point: " << *iIt << " not in indices list.\n";
00202       
00203 //      for (vector<int>::const_iterator iIt2 = input_indices.begin (); iIt2 != input_indices.end (); ++iIt2)
00204 //        cout << *iIt2 << "  ";
00205 //      cout << endl;
00206 #endif
00207       validness = false;
00208       break;
00209     }
00210     else if (!nan_mask [*iIt])
00211     {
00212 #if DEBUG_OUT
00213       cerr << name << ": result contains an invalid point: " << *iIt << " = NaN (" << point_cloud->points [*iIt].x << " , " 
00214                                                                                    << point_cloud->points [*iIt].y << " , " 
00215                                                                                    << point_cloud->points [*iIt].z << ")\n";
00216 #endif
00217       validness = false;
00218       break;
00219     }
00220   }
00221   
00222   return validness;
00223 }
00224 
00235 bool compareResults (const std::vector<int>& indices1, const::vector<float>& distances1, const std::string& name1,
00236                      const std::vector<int>& indices2, const::vector<float>& distances2, const std::string& name2, float eps)
00237 {
00238   bool equal = true;
00239   if (indices1.size () != indices2.size ())
00240   {
00241 #if DEBUG_OUT
00242     cerr << "size of results between " << name1 << " search and " << name2 << " search do not match " <<indices1.size () << " vs. " << indices2.size () << endl;
00243 //    for (unsigned idx = 0; idx < std::min (indices1.size (), indices2.size ()); ++idx)
00244 //    {
00245 //      cout << idx <<".\t" << indices1[idx] << "\t(" << distances1[idx] << "),\t" << indices2[idx] << "\t(" << distances2[idx] << ")\n";
00246 //    }    
00247 //    for (unsigned idx = std::min (indices1.size (), indices2.size ()); idx < std::max (indices1.size (), indices2.size ()); ++idx)
00248 //    {
00249 //      if (idx >= indices1.size ())
00250 //        cout << idx <<".\t     \t      ,\t" << indices2[idx] << "\t(" << distances2[idx] << ")\n";
00251 //      else
00252 //        cout << idx <<".\t" << indices1[idx] << "\t(" << distances1[idx] << ")\n";
00253 //    }
00254 #endif
00255     equal = false;
00256   }
00257   else
00258   {
00259     for (unsigned idx = 0; idx < indices1.size (); ++idx)
00260     {
00261       if (indices1[idx] != indices2[idx] && fabs (distances1[idx] - distances2[idx]) > eps)
00262       {
00263 #if DEBUG_OUT
00264         cerr << "results between " << name1 << " search and " << name2 << " search do not match: " << idx << " nearest neighbor: "
00265                 << indices1[idx] << " with distance: " << distances1[idx] << " vs. "
00266                 << indices2[idx] << " with distance: " << distances2[idx] << endl;
00267 #endif
00268         equal = false;
00269         break;
00270       }
00271     }
00272   }
00273   return equal;
00274 }
00275 
00282 template<typename PointT> void
00283 testKNNSearch (typename PointCloud<PointT>::ConstPtr point_cloud, vector<search::Search<PointT>*> search_methods,
00284                 const vector<int>& query_indices, const vector<int>& input_indices = vector<int> () )
00285 {
00286   vector< vector<int> >indices (search_methods.size ());
00287   vector< vector<float> >distances (search_methods.size ());
00288   vector<bool> passed (search_methods.size (), true);
00289   
00290   vector<bool> indices_mask (point_cloud->size (), true);
00291   vector<bool> nan_mask (point_cloud->size (), true);
00292   
00293   if (input_indices.size () != 0)
00294   {
00295     indices_mask.assign (point_cloud->size (), false);
00296     for (vector<int>::const_iterator iIt = input_indices.begin (); iIt != input_indices.end (); ++iIt)
00297       indices_mask [*iIt] = true;
00298   }
00299   
00300   // remove also Nans
00301   #pragma omp parallel for
00302   for (int pIdx = 0; pIdx < int (point_cloud->size ()); ++pIdx)
00303   {
00304     if (!isFinite (point_cloud->points [pIdx]))
00305       nan_mask [pIdx] = false;
00306   }
00307   
00308   boost::shared_ptr<vector<int> > input_indices_;
00309   if (input_indices.size ())
00310     input_indices_.reset (new vector<int> (input_indices));
00311   
00312   #pragma omp parallel for
00313   for (int sIdx = 0; sIdx < int (search_methods.size ()); ++sIdx)
00314     search_methods [sIdx]->setInputCloud (point_cloud, input_indices_);
00315 
00316   // test knn values from 1, 8, 64, 512
00317   for (unsigned knn = 1; knn <= 512; knn <<= 3)
00318   {
00319     // find nn for each point in the cloud
00320     for (vector<int>::const_iterator qIt = query_indices.begin (); qIt != query_indices.end (); ++qIt)
00321     {
00322       #pragma omp parallel for
00323       for (int sIdx = 0; sIdx < int (search_methods.size ()); ++sIdx)
00324       {
00325         search_methods [sIdx]->nearestKSearch (point_cloud->points[*qIt], knn, indices [sIdx], distances [sIdx]);
00326         passed [sIdx] = passed [sIdx] && testUniqueness (indices [sIdx], search_methods [sIdx]->getName ());
00327         passed [sIdx] = passed [sIdx] && testOrder (distances [sIdx], search_methods [sIdx]->getName ());
00328         passed [sIdx] = passed [sIdx] && testResultValidity<PointT>(point_cloud, indices_mask, nan_mask, indices [sIdx], input_indices, search_methods [sIdx]->getName ());
00329       }
00330       
00331       // compare results to each other
00332       #pragma omp parallel for
00333       for (int sIdx = 1; sIdx < int (search_methods.size ()); ++sIdx)
00334       {
00335         passed [sIdx] = passed [sIdx] && compareResults (indices [0],    distances [0],    search_methods [0]->getName (),
00336                                                          indices [sIdx], distances [sIdx], search_methods [sIdx]->getName (), 1e-6f);
00337       }
00338     }
00339   }
00340   for (size_t sIdx = 0; sIdx < search_methods.size (); ++sIdx)
00341   {
00342     cout << search_methods [sIdx]->getName () << ": " << (passed[sIdx]?"passed":"failed") << endl;
00343     EXPECT_TRUE (passed [sIdx]);
00344   }
00345 }
00346 
00353 template<typename PointT> void
00354 testRadiusSearch (typename PointCloud<PointT>::ConstPtr point_cloud, vector<search::Search<PointT>*> search_methods, 
00355                    const vector<int>& query_indices, const vector<int>& input_indices = vector<int> ())
00356 {
00357   vector< vector<int> >indices (search_methods.size ());
00358   vector< vector<float> >distances (search_methods.size ());
00359   vector <bool> passed (search_methods.size (), true);
00360   vector<bool> indices_mask (point_cloud->size (), true);
00361   vector<bool> nan_mask (point_cloud->size (), true);
00362   
00363   if (input_indices.size () != 0)
00364   {
00365     indices_mask.assign (point_cloud->size (), false);
00366     for (vector<int>::const_iterator iIt = input_indices.begin (); iIt != input_indices.end (); ++iIt)
00367       indices_mask [*iIt] = true;
00368   }
00369   
00370   // remove also Nans
00371   #pragma omp parallel for
00372   for (int pIdx = 0; pIdx < int (point_cloud->size ()); ++pIdx)
00373   {
00374     if (!isFinite (point_cloud->points [pIdx]))
00375       nan_mask [pIdx] = false;
00376   }
00377   
00378   boost::shared_ptr<vector<int> > input_indices_;
00379   if (input_indices.size ())
00380     input_indices_.reset (new vector<int> (input_indices));
00381   
00382   #pragma omp parallel for
00383   for (int sIdx = 0; sIdx < int (search_methods.size ()); ++sIdx)
00384     search_methods [sIdx]->setInputCloud (point_cloud, input_indices_);
00385 
00386   // test radii 0.01, 0.02, 0.04, 0.08
00387   for (float radius = 0.01f; radius < 0.1f; radius *= 2.0f)
00388   {
00389     //cout << radius << endl;
00390     // find nn for each point in the cloud
00391     for (vector<int>::const_iterator qIt = query_indices.begin (); qIt != query_indices.end (); ++qIt)
00392     {
00393       #pragma omp parallel for
00394       for (int sIdx = 0; sIdx < static_cast<int> (search_methods.size ()); ++sIdx)
00395       {
00396         search_methods [sIdx]->radiusSearch (point_cloud->points[*qIt], radius, indices [sIdx], distances [sIdx], 0);
00397         passed [sIdx] = passed [sIdx] && testUniqueness (indices [sIdx], search_methods [sIdx]->getName ());
00398         passed [sIdx] = passed [sIdx] && testOrder (distances [sIdx], search_methods [sIdx]->getName ());
00399         passed [sIdx] = passed [sIdx] && testResultValidity<PointT>(point_cloud, indices_mask, nan_mask, indices [sIdx], input_indices, search_methods [sIdx]->getName ());
00400       }
00401       
00402       // compare results to each other
00403       #pragma omp parallel for
00404       for (int sIdx = 1; sIdx < static_cast<int> (search_methods.size ()); ++sIdx)
00405       {
00406         passed [sIdx] = passed [sIdx] && compareResults (indices [0],    distances [0],    search_methods [0]->getName (),
00407                                                          indices [sIdx], distances [sIdx], search_methods [sIdx]->getName (), 1e-6f);
00408       }
00409     }
00410   }
00411   for (unsigned sIdx = 0; sIdx < search_methods.size (); ++sIdx)
00412   {
00413     cout << search_methods [sIdx]->getName () << ": " << (passed[sIdx]?"passed":"failed") << endl;
00414     EXPECT_TRUE (passed [sIdx]);
00415   }
00416 }
00417 
00418 #if TEST_unorganized_dense_cloud_COMPLETE_KNN
00419 // Test search on unorganized point clouds
00420 TEST (PCL, unorganized_dense_cloud_Complete_KNN)
00421 {
00422   testKNNSearch (unorganized_dense_cloud, unorganized_search_methods, unorganized_dense_cloud_query_indices);
00423 }
00424 #endif
00425 
00426 #if TEST_unorganized_dense_cloud_VIEW_KNN
00427 // Test search on unorganized point clouds
00428 TEST (PCL, unorganized_dense_cloud_View_KNN)
00429 {
00430   testKNNSearch (unorganized_dense_cloud, unorganized_search_methods, unorganized_dense_cloud_query_indices, unorganized_input_indices);
00431 }
00432 #endif
00433 
00434 #if TEST_unorganized_sparse_cloud_COMPLETE_KNN
00435 // Test search on unorganized point clouds
00436 TEST (PCL, unorganized_sparse_cloud_Complete_KNN)
00437 {
00438   testKNNSearch (unorganized_sparse_cloud, unorganized_search_methods, unorganized_sparse_cloud_query_indices);
00439 }
00440 #endif
00441 
00442 #if TEST_unorganized_sparse_cloud_VIEW_KNN
00443 TEST (PCL, unorganized_sparse_cloud_View_KNN)
00444 {   
00445   testKNNSearch (unorganized_sparse_cloud, unorganized_search_methods, unorganized_sparse_cloud_query_indices, unorganized_input_indices);
00446 }
00447 #endif
00448 
00449 #if TEST_unorganized_dense_cloud_COMPLETE_RADIUS
00450 // Test search on unorganized point clouds
00451 TEST (PCL, unorganized_dense_cloud_Complete_Radius)
00452 {
00453   testRadiusSearch (unorganized_dense_cloud, unorganized_search_methods, unorganized_dense_cloud_query_indices);
00454 }
00455 #endif
00456 
00457 #if TEST_unorganized_grid_cloud_COMPLETE_RADIUS
00458 // Test search on unorganized point clouds in a grid
00459 TEST (PCL, unorganized_grid_cloud_Complete_Radius)
00460 {
00461   vector<int> query_indices;
00462   query_indices.reserve (query_count);
00463   
00464   unsigned skip = static_cast<unsigned> (unorganized_grid_cloud->size ()) / query_count;
00465   for (unsigned idx = 0; idx < unorganized_grid_cloud->size () && query_indices.size () < query_count; ++idx)
00466      if ((rand () % skip) == 0 && isFinite (unorganized_grid_cloud->points [idx]))
00467        query_indices.push_back (idx);
00468   
00469   testRadiusSearch (unorganized_grid_cloud, unorganized_search_methods, query_indices);
00470 }
00471 #endif
00472 
00473 #if TEST_unorganized_dense_cloud_VIEW_RADIUS
00474 // Test search on unorganized point clouds
00475 TEST (PCL, unorganized_dense_cloud_View_Radius)
00476 {  
00477   testRadiusSearch (unorganized_dense_cloud, unorganized_search_methods, unorganized_dense_cloud_query_indices, unorganized_input_indices);
00478 }
00479 #endif
00480 
00481 #if TEST_unorganized_sparse_cloud_COMPLETE_RADIUS
00482 // Test search on unorganized point clouds
00483 TEST (PCL, unorganized_sparse_cloud_Complete_Radius)
00484 {
00485   testRadiusSearch (unorganized_sparse_cloud, unorganized_search_methods, unorganized_sparse_cloud_query_indices);
00486 }
00487 #endif
00488 
00489 #if TEST_unorganized_sparse_cloud_VIEW_RADIUS
00490 TEST (PCL, unorganized_sparse_cloud_View_Radius)
00491 {   
00492   testRadiusSearch (unorganized_sparse_cloud, unorganized_search_methods, unorganized_sparse_cloud_query_indices, unorganized_input_indices);
00493 }
00494 #endif
00495 
00496 #if TEST_ORGANIZED_SPARSE_COMPLETE_KNN
00497 TEST (PCL, Organized_Sparse_Complete_KNN)
00498 {
00499   testKNNSearch (organized_sparse_cloud, organized_search_methods, organized_sparse_query_indices);
00500 }
00501 #endif
00502 
00503 #if TEST_ORGANIZED_SPARSE_VIEW_KNN
00504 TEST (PCL, Organized_Sparse_View_KNN)
00505 {
00506   testKNNSearch (organized_sparse_cloud, organized_search_methods, organized_sparse_query_indices, organized_input_indices);
00507 }
00508 #endif
00509 
00510 #if TEST_ORGANIZED_SPARSE_COMPLETE_RADIUS
00511 TEST (PCL, Organized_Sparse_Complete_Radius)
00512 {
00513   testRadiusSearch (organized_sparse_cloud, organized_search_methods, organized_sparse_query_indices);
00514 }
00515 #endif
00516 
00517 #if TEST_ORGANIZED_SPARSE_VIEW_RADIUS
00518 TEST (PCL, Organized_Sparse_View_Radius)
00519 {
00520   testRadiusSearch (organized_sparse_cloud, organized_search_methods, organized_sparse_query_indices, organized_input_indices);
00521 }
00522 #endif
00523 
00529 void createQueryIndices (std::vector<int>& query_indices, PointCloud<PointXYZ>::ConstPtr point_cloud, unsigned query_count)
00530 {
00531   query_indices.clear ();
00532   query_indices.reserve (query_count);
00533   
00534   unsigned skip = static_cast<unsigned> (point_cloud->size ()) / query_count;
00535   for (unsigned idx = 0; idx < point_cloud->size () && query_indices.size () < query_count; ++idx)
00536      if ((rand () % skip) == 0 && isFinite (point_cloud->points [idx]))
00537        query_indices.push_back (idx);
00538 }
00539 
00544 void createIndices (std::vector<int>& indices, unsigned max_index)
00545 {
00546   // ~10% of the input cloud
00547   for (unsigned idx = 0; idx <= max_index; ++idx)
00548     if (rand_uint () == 0)
00549       indices.push_back (idx);
00550    
00551   boost::variate_generator< boost::mt19937, boost::uniform_int<> > rand_indices(boost::mt19937 (), boost::uniform_int<> (0, static_cast<int> (indices.size ()) - 1));
00552   // shuffle indices -> not ascending index list
00553   for (unsigned idx = 0; idx < max_index; ++idx)
00554   {
00555     unsigned idx1 = rand_indices ();
00556     unsigned idx2 = rand_indices ();
00557 
00558     std::swap (indices[idx1], indices[idx2]);
00559   }
00560 }
00561 
00562 /* ---[ */
00563 int
00564 main (int argc, char** argv)
00565 {
00566   if (argc < 2)
00567   {
00568     std::cout << "need path to table_scene_mug_stereo_textured.pcd file\n";
00569     return (-1);
00570   }
00571 
00572   pcl::io::loadPCDFile (argv [1], *organized_sparse_cloud);
00573   
00574   // create unorganized cloud
00575   unorganized_dense_cloud->resize (unorganized_point_count);
00576   unorganized_dense_cloud->height = 1;
00577   unorganized_dense_cloud->width = unorganized_point_count;
00578   unorganized_dense_cloud->is_dense = true;
00579   
00580   unorganized_sparse_cloud->resize (unorganized_point_count);
00581   unorganized_sparse_cloud->height = 1;
00582   unorganized_sparse_cloud->width = unorganized_point_count;
00583   unorganized_sparse_cloud->is_dense = false;
00584 
00585   PointXYZ point;
00586   for (unsigned pIdx = 0; pIdx < unorganized_point_count; ++pIdx)
00587   {
00588     point.x = rand_float ();
00589     point.y = rand_float ();
00590     point.z = rand_float ();
00591 
00592     unorganized_dense_cloud->points [pIdx] = point;
00593     
00594     if (rand_uint () == 0)
00595       unorganized_sparse_cloud->points [pIdx].x = unorganized_sparse_cloud->points [pIdx].y = unorganized_sparse_cloud->points [pIdx].z = std::numeric_limits<float>::quiet_NaN ();
00596     else
00597       unorganized_sparse_cloud->points [pIdx] = point;
00598   }
00599   
00600   unorganized_grid_cloud->reserve (1000);
00601   unorganized_grid_cloud->height = 1;
00602   unorganized_grid_cloud->width = 1000;
00603   unorganized_grid_cloud->is_dense = true;
00604   
00605   // values between 0 and 1
00606   for (unsigned xIdx = 0; xIdx < 10; ++xIdx)
00607   {
00608     for (unsigned yIdx = 0; yIdx < 10; ++yIdx)
00609     {
00610       for (unsigned zIdx = 0; zIdx < 10; ++zIdx)
00611       {
00612         point.x = 0.1f * static_cast<float>(xIdx);
00613         point.y = 0.1f * static_cast<float>(yIdx);
00614         point.z = 0.1f * static_cast<float>(zIdx);
00615         unorganized_grid_cloud->push_back (point);
00616       }
00617     }
00618   }
00619   
00620   createIndices (organized_input_indices, static_cast<unsigned> (organized_sparse_cloud->size () - 1));
00621   createIndices (unorganized_input_indices, unorganized_point_count - 1);
00622   
00623   brute_force.setSortedResults (true);
00624   KDTree.setSortedResults (true);
00625   octree_search.setSortedResults (true);
00626   organized.setSortedResults (true);
00627   
00628   unorganized_search_methods.push_back (&brute_force);
00629   unorganized_search_methods.push_back (&KDTree);
00630   unorganized_search_methods.push_back (&octree_search);
00631   
00632   organized_search_methods.push_back (&brute_force);
00633   organized_search_methods.push_back (&KDTree);
00634   organized_search_methods.push_back (&octree_search);
00635   organized_search_methods.push_back (&organized);
00636   
00637   createQueryIndices (unorganized_dense_cloud_query_indices, unorganized_dense_cloud, query_count);
00638   createQueryIndices (unorganized_sparse_cloud_query_indices, unorganized_sparse_cloud, query_count);
00639   createQueryIndices (organized_sparse_query_indices, organized_sparse_cloud, query_count);
00640   
00641   testing::InitGoogleTest (&argc, argv);
00642   return (RUN_ALL_TESTS ());
00643 }
00644 /* ]--- */


pcl
Author(s): Open Perception
autogenerated on Mon Oct 6 2014 03:18:31