00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 #include <gtest/gtest.h>
00041 #include <pcl/point_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     
00169     
00170     
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     
00191     
00192     
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   
00213   
00214   PointCloud<OutputT> full_output, output0, output1, output2;
00215 
00216   
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   
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   
00244   checkDesc<OutputT> (output0, output1);
00245   checkDesc<OutputT> (output1, output2);
00246 
00247   
00248   
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   
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   
00266   shotCopyPointCloud<OutputT> (output0, *indices2, output4); 
00267 
00268   
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   
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   
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   
00335   checkDesc<OutputT> (output, output2);
00336 }
00337 
00339 TEST (PCL, SHOTShapeEstimation)
00340 {
00341   
00342   double mr = 0.002;
00343   NormalEstimation<PointXYZ, Normal> n;
00344   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00345   
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 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394   
00395   SHOTEstimation<PointXYZ, Normal, SHOT352> shot352;
00396   shot352.setInputNormals (normals);
00397   EXPECT_EQ (shot352.getInputNormals (), normals);
00398   shot352.setRadiusSearch (20 * mr);
00399 
00400   
00401   PointCloud<SHOT352>::Ptr shots352 (new PointCloud<SHOT352> ());
00402 
00403   
00404   shot352.setInputCloud (cloud.makeShared ());
00405   shot352.setIndices (indicesptr);
00406   shot352.setSearchMethod (tree);
00407 
00408   
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   
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   
00431   
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 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00495 TEST (PCL, SHOTShapeAndColorEstimation)
00496 {
00497   double mr = 0.002;
00498   
00499   NormalEstimation<PointXYZ, Normal> n;
00500   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00501   
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   
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 
00527 
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 
00560 
00561 
00562 
00563 
00564 
00565 
00566 
00567   
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   
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   
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   
00612   
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   
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   
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 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668   
00669   SHOTEstimationOMP<PointXYZ, Normal, SHOT352> shot352;
00670   shot352.setInputNormals (normals);
00671   EXPECT_EQ (shot352.getInputNormals (), normals);
00672 
00673   shot352.setRadiusSearch ( 20 * mr);
00674 
00675   
00676   PointCloud<SHOT352>::Ptr shots352 (new PointCloud<SHOT352>);
00677 
00678   
00679   shot352.setInputCloud (cloud.makeShared ());
00680   shot352.setIndices (indicesptr);
00681   shot352.setSearchMethod (tree);
00682 
00683   
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   
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   
00704   
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   
00715   NormalEstimation<PointXYZ, Normal> n;
00716   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00717   
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   
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 
00744 
00745 
00746 
00747 
00748 
00749 
00750 
00751 
00752 
00753 
00754 
00755 
00756 
00757 
00758 
00759 
00760 
00761 
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773 
00774 
00775 
00776 
00777 
00778 
00779 
00780 
00781 
00782 
00783 
00784 
00785 
00786   
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   
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   
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   
00832   
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   
00843   
00844   
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   
00852   NormalEstimation<PointXYZ, Normal> ne;
00853   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00854   
00855   ne.setInputCloud (cloudptr);
00856   ne.setSearchMethod (tree);
00857   ne.setRadiusSearch (radius);
00858   
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   
00867   
00868   
00869   sc3d.setMinimalRadius (rmin);
00870   sc3d.setPointDensityRadius (ptDensityRad);
00871   
00872   PointCloud<ShapeContext1980>::Ptr sc3ds (new PointCloud<ShapeContext1980> ());
00873   sc3d.compute (*sc3ds);
00874   EXPECT_EQ (sc3ds->size (), cloud.size ());
00875 
00876   
00877   
00878   
00879   
00880   
00881   
00882   
00883   
00884   
00885   
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   
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   
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   
00924   
00925   
00926   float radius = 20.0f * meshRes;
00927   float rmin = radius / 10.0f;
00928   float ptDensityRad = radius / 5.0f;
00929 
00930   
00931   UniqueShapeContext<PointXYZ, ShapeContext1980> uscd;
00932   uscd.setInputCloud (cloud.makeShared ());
00933   uscd.setSearchMethod (tree);
00934   uscd.setRadiusSearch (radius);
00935   
00936   
00937   
00938   uscd.setMinimalRadius (rmin);
00939   uscd.setPointDensityRadius (ptDensityRad);
00940   uscd.setLocalRadius (radius);
00941   
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   
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   
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