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/3dsc.h>
00047 #include <pcl/features/usc.h>
00048
00049 using namespace pcl;
00050 using namespace pcl::io;
00051 using namespace std;
00052
00053 typedef search::KdTree<PointXYZ>::Ptr KdTreePtr;
00054
00055 PointCloud<PointXYZ> cloud;
00056 vector<int> indices;
00057 KdTreePtr tree;
00058
00060 void
00061 shotCopyPointCloud (const PointCloud<SHOT> &cloud_in, const std::vector<int> &indices,
00062 PointCloud<SHOT> &cloud_out)
00063 {
00064
00065 cloud_out.points.resize (indices.size ());
00066 cloud_out.header = cloud_in.header;
00067 cloud_out.width = static_cast<uint32_t> (indices.size ());
00068 cloud_out.height = 1;
00069 if (cloud_in.is_dense)
00070 cloud_out.is_dense = true;
00071 else
00072
00073
00074 cloud_out.is_dense = false;
00075
00076
00077 for (size_t i = 0; i < indices.size (); ++i)
00078 {
00079 std::copy (cloud_in.points[indices[i]].descriptor.begin (),
00080 cloud_in.points[indices[i]].descriptor.end (),
00081 std::back_inserter(cloud_out.points[i].descriptor));
00082 memcpy (cloud_out.points[i].rf, cloud_in.points[indices[i]].rf, sizeof (float) * 9);
00083 }
00084 }
00085
00087 template <typename FeatureEstimation, typename PointT, typename NormalT, typename OutputT> FeatureEstimation
00088 createSHOTDesc (const typename PointCloud<NormalT>::Ptr & normals,
00089 const int nr_shape_bins = 10,
00090 const int = 30,
00091 const bool = true,
00092 const bool = false)
00093 {
00094 FeatureEstimation f (nr_shape_bins);
00095 f.setInputNormals (normals);
00096 return (f);
00097 }
00098
00100 template <typename FeatureEstimation, typename NormalT, typename OutputT> FeatureEstimation
00101 createSHOTDesc (const typename PointCloud<NormalT>::Ptr & normals,
00102 const int nr_shape_bins = 10,
00103 const int nr_color_bins = 30,
00104 const bool describe_shape = true,
00105 const bool describe_color = false)
00106 {
00107 FeatureEstimation f (describe_shape, describe_color, nr_shape_bins,nr_color_bins);
00108 f.setInputNormals (normals);
00109 return (f);
00110 }
00111
00113 template <> ShapeContext3DEstimation<PointXYZ, Normal, SHOT>
00114 createSHOTDesc<ShapeContext3DEstimation<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (
00115 const PointCloud<Normal>::Ptr & normals,
00116 const int,
00117 const int,
00118 const bool,
00119 const bool)
00120 {
00121 ShapeContext3DEstimation<PointXYZ, Normal, SHOT> sc3d;
00122 sc3d.setAzimuthBins (4);
00123 sc3d.setElevationBins (4);
00124 sc3d.setRadiusBins (4);
00125 sc3d.setMinimalRadius (0.004);
00126 sc3d.setPointDensityRadius (0.008);
00127 sc3d.setInputNormals (normals);
00128 return (sc3d);
00129 }
00130
00132 template <> UniqueShapeContext<PointXYZ, SHOT>
00133 createSHOTDesc<UniqueShapeContext<PointXYZ, SHOT>, PointXYZ, Normal, SHOT> (
00134 const PointCloud<Normal>::Ptr &,
00135 const int,
00136 const int,
00137 const bool,
00138 const bool)
00139 {
00140 UniqueShapeContext<PointXYZ, SHOT> usc;
00141 usc.setAzimuthBins (4);
00142 usc.setElevationBins (4);
00143 usc.setRadiusBins (4);
00144 usc.setMinimalRadius (0.004);
00145 usc.setPointDensityRadius (0.008);
00146 usc.setLocalRadius (0.04f);
00147 return (usc);
00148 }
00149
00151 template <typename FeatureEstimation, typename PointT, typename NormalT, typename OutputT> void
00152 testSHOTIndicesAndSearchSurface (const typename PointCloud<PointT>::Ptr & points,
00153 const typename PointCloud<NormalT>::Ptr & normals,
00154 const boost::shared_ptr<vector<int> > & indices,
00155 const int nr_shape_bins = 10,
00156 const int nr_color_bins = 30,
00157 const bool describe_shape = true,
00158 const bool describe_color = false)
00159 {
00160 double radius = 0.04;
00161
00162
00163
00164 PointCloud<OutputT> full_output, output0, output1, output2;
00165
00166
00167 FeatureEstimation est0 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00168 est0.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00169 est0.setRadiusSearch (radius);
00170 est0.setInputCloud (points);
00171 est0.compute (full_output);
00172
00173 shotCopyPointCloud (full_output, *indices, output0);
00174
00175
00176 typename PointCloud<PointT>::Ptr subpoints (new PointCloud<PointT>);
00177 copyPointCloud (*points, *indices, *subpoints);
00178 FeatureEstimation est1 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00179 est1.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00180 est1.setRadiusSearch (radius);
00181 est1.setInputCloud (subpoints);
00182 est1.setSearchSurface (points);
00183 est1.compute (output1);
00184
00186 FeatureEstimation est2 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00187 est2.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00188 est2.setRadiusSearch (radius);
00189 est2.setInputCloud (points);
00190 est2.setIndices (indices);
00191 est2.compute (output2);
00192
00193
00194 ASSERT_EQ (output0.size (), output1.size ());
00195 ASSERT_EQ (output1.size (), output2.size ());
00196 for (size_t i = 0; i < output1.size (); ++i)
00197 {
00198 for (size_t j = 0; j < output0.points[i].descriptor.size(); ++j)
00199 {
00200 ASSERT_EQ (output0.points[i].descriptor[j], output1.points[i].descriptor[j]);
00201 ASSERT_EQ (output1.points[i].descriptor[j], output2.points[i].descriptor[j]);
00202 }
00203 }
00204
00205
00206
00207
00208 PointCloud<OutputT> output3, output4;
00209
00210 boost::shared_ptr<vector<int> > indices2 (new vector<int> (0));
00211 for (size_t i = 0; i < (indices->size ()/2); ++i)
00212 indices2->push_back (static_cast<int> (i));
00213
00214
00215 FeatureEstimation est3 = createSHOTDesc<FeatureEstimation, PointT, NormalT, OutputT>(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00216 est3.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00217 est3.setRadiusSearch (0.04);
00218 est3.setSearchSurface (points);
00219 est3.setInputCloud (subpoints);
00220 est3.setIndices (indices2);
00221 est3.compute (output3);
00222
00223
00224 shotCopyPointCloud (output0, *indices2, output4);
00225
00226
00227 ASSERT_EQ (output3.size (), output4.size ());
00228 for (size_t i = 0; i < output3.size (); ++i)
00229 for (size_t j = 0; j < output3.points[i].descriptor.size (); ++j)
00230 ASSERT_EQ (output3.points[i].descriptor[j], output4.points[i].descriptor[j]);
00231 }
00232
00234 TEST (PCL, SHOTShapeEstimation)
00235 {
00236
00237 double mr = 0.002;
00238 NormalEstimation<PointXYZ, Normal> n;
00239 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00240
00241 n.setInputCloud (cloud.makeShared ());
00242 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00243 n.setIndices (indicesptr);
00244 n.setSearchMethod (tree);
00245 n.setRadiusSearch (20 * mr);
00246 n.compute (*normals);
00247
00248 EXPECT_NEAR (normals->points[103].normal_x, 0.36683175, 1e-4);
00249 EXPECT_NEAR (normals->points[103].normal_y, -0.44696972, 1e-4);
00250 EXPECT_NEAR (normals->points[103].normal_z, -0.81587529, 1e-4);
00251 EXPECT_NEAR (normals->points[200].normal_x, -0.71414840, 1e-4);
00252 EXPECT_NEAR (normals->points[200].normal_y, -0.06002361, 1e-4);
00253 EXPECT_NEAR (normals->points[200].normal_z, -0.69741613, 1e-4);
00254
00255 EXPECT_NEAR (normals->points[140].normal_x, -0.45109111, 1e-4);
00256 EXPECT_NEAR (normals->points[140].normal_y, -0.19499126, 1e-4);
00257 EXPECT_NEAR (normals->points[140].normal_z, -0.87091631, 1e-4);
00258
00259 SHOTEstimation<PointXYZ, Normal, SHOT> shot;
00260 shot.setInputNormals (normals);
00261 EXPECT_EQ (shot.getInputNormals (), normals);
00262 shot.setRadiusSearch (20 * mr);
00263
00264
00265 PointCloud<SHOT>::Ptr shots (new PointCloud<SHOT> ());
00266
00267
00268 shot.setInputCloud (cloud.makeShared ());
00269 shot.setIndices (indicesptr);
00270 shot.setSearchMethod (tree);
00271
00272
00273 shot.compute (*shots);
00274 EXPECT_EQ (shots->points.size (), indices.size ());
00275
00276 EXPECT_NEAR (shots->points[103].descriptor[9 ], 0.0072018504, 1e-4);
00277 EXPECT_NEAR (shots->points[103].descriptor[10], 0.0023103887, 1e-4);
00278 EXPECT_NEAR (shots->points[103].descriptor[11], 0.0024724449, 1e-4);
00279 EXPECT_NEAR (shots->points[103].descriptor[19], 0.0031367359, 1e-4);
00280 EXPECT_NEAR (shots->points[103].descriptor[20], 0.17439659, 1e-4);
00281 EXPECT_NEAR (shots->points[103].descriptor[21], 0.070665278, 1e-4);
00282 EXPECT_NEAR (shots->points[103].descriptor[42], 0.013304681, 1e-4);
00283 EXPECT_NEAR (shots->points[103].descriptor[53], 0.0073520984, 1e-4);
00284 EXPECT_NEAR (shots->points[103].descriptor[54], 0.013584172, 1e-4);
00285 EXPECT_NEAR (shots->points[103].descriptor[55], 0.0050609680, 1e-4);
00286
00287
00288
00289
00290 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00291 for (size_t i = 0; i < cloud.size (); i+=3)
00292 test_indices->push_back (static_cast<int> (i));
00293
00294 testSHOTIndicesAndSearchSurface<SHOTEstimation<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices);
00295 }
00296
00298 TEST (PCL, GenericSHOTShapeEstimation)
00299 {
00300
00301 const int shapeStep_ = 20;
00302
00303
00304
00305 double mr = 0.002;
00306 NormalEstimation<PointXYZ, Normal> n;
00307 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00308
00309 n.setInputCloud (cloud.makeShared ());
00310 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00311 n.setIndices (indicesptr);
00312 n.setSearchMethod (tree);
00313 n.setRadiusSearch (20 * mr);
00314 n.compute (*normals);
00315
00316 SHOTEstimation<PointXYZ, Normal, SHOT> shot (shapeStep_);
00317 shot.setInputNormals (normals);
00318 EXPECT_EQ (shot.getInputNormals (), normals);
00319
00320 shot.setRadiusSearch (20 * mr);
00321
00322 PointCloud< SHOT >::Ptr shots (new PointCloud< SHOT > ());
00323
00324
00325 shot.setInputCloud (cloud.makeShared ());
00326 shot.setIndices (indicesptr);
00327 shot.setSearchMethod (tree);
00328
00329
00330 shot.compute (*shots);
00331 EXPECT_EQ (shots->points.size (), indices.size ());
00332
00333 EXPECT_NEAR (shots->points[103].descriptor[18], 0.0077019366, 1e-5);
00334 EXPECT_NEAR (shots->points[103].descriptor[19], 0.0024708188, 1e-5);
00335 EXPECT_NEAR (shots->points[103].descriptor[21], 0.0079652183, 1e-5);
00336 EXPECT_NEAR (shots->points[103].descriptor[38], 0.0067090928, 1e-5);
00337 EXPECT_NEAR (shots->points[103].descriptor[39], 0.17498907, 1e-5);
00338 EXPECT_NEAR (shots->points[103].descriptor[40], 0.078413926, 1e-5);
00339 EXPECT_NEAR (shots->points[103].descriptor[81], 0.014228539, 1e-5);
00340 EXPECT_NEAR (shots->points[103].descriptor[103], 0.022390056, 1e-5);
00341 EXPECT_NEAR (shots->points[103].descriptor[105], 0.0058866320, 1e-5);
00342 EXPECT_NEAR (shots->points[103].descriptor[123], 0.019105887, 1e-5);
00343
00344
00345 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00346 for (size_t i = 0; i < cloud.size (); i+=3)
00347 test_indices->push_back (static_cast<int> (i));
00348
00349 testSHOTIndicesAndSearchSurface<SHOTEstimation<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices, shapeStep_);
00350 }
00351
00353 TEST (PCL, SHOTShapeAndColorEstimation)
00354 {
00355 double mr = 0.002;
00356
00357 NormalEstimation<PointXYZ, Normal> n;
00358 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00359
00360 n.setInputCloud (cloud.makeShared ());
00361 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00362 n.setIndices (indicesptr);
00363 n.setSearchMethod (tree);
00364 n.setRadiusSearch (20 * mr);
00365 n.compute (*normals);
00366
00367 search::KdTree<PointXYZRGBA>::Ptr rgbaTree;
00368 rgbaTree.reset (new search::KdTree<PointXYZRGBA> (false));
00369
00370
00371 SHOTEstimation<PointXYZRGBA, Normal, SHOT> shot (true, true);
00372 shot.setInputNormals (normals);
00373 EXPECT_EQ (shot.getInputNormals (), normals);
00374
00375 shot.setRadiusSearch ( 20 * mr);
00376
00377
00378 PointCloud<PointXYZRGBA> cloudWithColors;
00379 for (int i = 0; i < static_cast<int> (cloud.points.size ()); ++i)
00380 {
00381 PointXYZRGBA p;
00382 p.x = cloud.points[i].x;
00383 p.y = cloud.points[i].y;
00384 p.z = cloud.points[i].z;
00385
00386 p.rgba = ( (i%255) << 16 ) + ( ( (255 - i ) %255) << 8) + ( ( i*37 ) %255);
00387 cloudWithColors.push_back(p);
00388 }
00389
00390 rgbaTree->setInputCloud (cloudWithColors.makeShared ());
00391 PointCloud<SHOT>::Ptr shots (new PointCloud<SHOT>);
00392
00393 shot.setInputCloud (cloudWithColors.makeShared ());
00394 shot.setIndices (indicesptr);
00395 shot.setSearchMethod (rgbaTree);
00396
00397
00398 shot.compute (*shots);
00399 EXPECT_EQ (shots->points.size (), indices.size ());
00400
00401 EXPECT_NEAR (shots->points[103].descriptor[10], 0.0020453099, 1e-5);
00402 EXPECT_NEAR (shots->points[103].descriptor[11], 0.0021887729, 1e-5);
00403 EXPECT_NEAR (shots->points[103].descriptor[21], 0.062557608, 1e-5);
00404 EXPECT_NEAR (shots->points[103].descriptor[42], 0.011778189, 1e-5);
00405 EXPECT_NEAR (shots->points[103].descriptor[53], 0.0065085669, 1e-5);
00406 EXPECT_NEAR (shots->points[103].descriptor[54], 0.012025614, 1e-5);
00407 EXPECT_NEAR (shots->points[103].descriptor[55], 0.0044803056, 1e-5);
00408 EXPECT_NEAR (shots->points[103].descriptor[64], 0.064429596, 1e-5);
00409 EXPECT_NEAR (shots->points[103].descriptor[65], 0.046486385, 1e-5);
00410 EXPECT_NEAR (shots->points[103].descriptor[86], 0.011518310, 1e-5);
00411
00412 EXPECT_NEAR (shots->points[103].descriptor[357], 0.0020453099, 1e-5);
00413 EXPECT_NEAR (shots->points[103].descriptor[360], 0.0027993850, 1e-5);
00414 EXPECT_NEAR (shots->points[103].descriptor[386], 0.045115642, 1e-5);
00415 EXPECT_NEAR (shots->points[103].descriptor[387], 0.059068538, 1e-5);
00416 EXPECT_NEAR (shots->points[103].descriptor[389], 0.0047547864, 1e-5);
00417 EXPECT_NEAR (shots->points[103].descriptor[453], 0.0051176427, 1e-5);
00418 EXPECT_NEAR (shots->points[103].descriptor[481], 0.0053625242, 1e-5);
00419 EXPECT_NEAR (shots->points[103].descriptor[482], 0.012025614, 1e-5);
00420 EXPECT_NEAR (shots->points[103].descriptor[511], 0.0057367259, 1e-5);
00421 EXPECT_NEAR (shots->points[103].descriptor[512], 0.048357654, 1e-5);
00422
00423
00424 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00425 for (size_t i = 0; i < cloud.size (); i+=3)
00426 test_indices->push_back (static_cast<int> (i));
00427
00428 testSHOTIndicesAndSearchSurface<SHOTEstimation<PointXYZRGBA, Normal, SHOT>, PointXYZRGBA, Normal, SHOT> (cloudWithColors.makeShared (), normals, test_indices);
00429 }
00430
00432 TEST (PCL, SHOTShapeEstimationOpenMP)
00433 {
00434
00435 double mr = 0.002;
00436 NormalEstimationOMP<PointXYZ, Normal> n (omp_get_max_threads ());
00437 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00438
00439 n.setInputCloud (cloud.makeShared ());
00440 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00441 n.setIndices (indicesptr);
00442 n.setSearchMethod (tree);
00443 n.setRadiusSearch (20 * mr);
00444 n.compute (*normals);
00445
00446 SHOTEstimationOMP<PointXYZ, Normal, SHOT> shot;
00447 shot.setInputNormals (normals);
00448 EXPECT_EQ (shot.getInputNormals (), normals);
00449
00450 shot.setRadiusSearch ( 20 * mr);
00451
00452
00453 PointCloud<SHOT>::Ptr shots (new PointCloud<SHOT>);
00454
00455
00456 shot.setInputCloud (cloud.makeShared ());
00457 shot.setIndices (indicesptr);
00458 shot.setSearchMethod (tree);
00459
00460
00461 shot.compute (*shots);
00462 EXPECT_EQ (shots->points.size (), indices.size ());
00463
00464 EXPECT_NEAR (shots->points[103].descriptor[9 ], 0.0072018504, 1e-4);
00465 EXPECT_NEAR (shots->points[103].descriptor[10], 0.0023103887, 1e-4);
00466 EXPECT_NEAR (shots->points[103].descriptor[11], 0.0024724449, 1e-4);
00467 EXPECT_NEAR (shots->points[103].descriptor[19], 0.0031367359, 1e-4);
00468 EXPECT_NEAR (shots->points[103].descriptor[20], 0.17439659, 1e-4);
00469 EXPECT_NEAR (shots->points[103].descriptor[21], 0.070665278, 1e-4);
00470 EXPECT_NEAR (shots->points[103].descriptor[42], 0.013304681, 1e-4);
00471 EXPECT_NEAR (shots->points[103].descriptor[53], 0.0073520984, 1e-4);
00472 EXPECT_NEAR (shots->points[103].descriptor[54], 0.013584172, 1e-4);
00473 EXPECT_NEAR (shots->points[103].descriptor[55], 0.0050609680, 1e-4);
00474
00475
00476 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00477 for (size_t i = 0; i < cloud.size (); i+=3)
00478 test_indices->push_back (static_cast<int> (i));
00479
00480 testSHOTIndicesAndSearchSurface<SHOTEstimationOMP<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices);
00481 }
00482
00484 TEST (PCL,SHOTShapeAndColorEstimationOpenMP)
00485 {
00486 double mr = 0.002;
00487
00488 NormalEstimation<PointXYZ, Normal> n;
00489 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00490
00491 n.setInputCloud (cloud.makeShared ());
00492 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00493 n.setIndices (indicesptr);
00494 n.setSearchMethod (tree);
00495 n.setRadiusSearch (20 * mr);
00496 n.compute (*normals);
00497
00498 search::KdTree<PointXYZRGBA>::Ptr rgbaTree;
00499
00500 rgbaTree.reset (new search::KdTree<PointXYZRGBA> (false));
00501
00502
00503 SHOTEstimationOMP<PointXYZRGBA, Normal, SHOT> shot (true, true, -1);
00504 shot.setInputNormals (normals);
00505
00506 EXPECT_EQ (shot.getInputNormals (), normals);
00507
00508 shot.setRadiusSearch ( 20 * mr);
00509
00510
00511 PointCloud<PointXYZRGBA> cloudWithColors;
00512 for (int i = 0; i < static_cast<int> (cloud.points.size ()); ++i)
00513 {
00514 PointXYZRGBA p;
00515 p.x = cloud.points[i].x;
00516 p.y = cloud.points[i].y;
00517 p.z = cloud.points[i].z;
00518
00519 p.rgba = ( (i%255) << 16 ) + ( ( (255 - i ) %255) << 8) + ( ( i*37 ) %255);
00520 cloudWithColors.push_back(p);
00521 }
00522
00523 rgbaTree->setInputCloud (cloudWithColors.makeShared ());
00524
00525 PointCloud<SHOT>::Ptr shots (new PointCloud<SHOT> ());
00526
00527 shot.setInputCloud (cloudWithColors.makeShared ());
00528 shot.setIndices (indicesptr);
00529 shot.setSearchMethod (rgbaTree);
00530
00531
00532 shot.compute (*shots);
00533 EXPECT_EQ (shots->points.size (), indices.size ());
00534
00535 EXPECT_NEAR (shots->points[103].descriptor[10], 0.0020453099, 1e-5);
00536 EXPECT_NEAR (shots->points[103].descriptor[11], 0.0021887729, 1e-5);
00537 EXPECT_NEAR (shots->points[103].descriptor[21], 0.062557608, 1e-5);
00538 EXPECT_NEAR (shots->points[103].descriptor[42], 0.011778189, 1e-5);
00539 EXPECT_NEAR (shots->points[103].descriptor[53], 0.0065085669, 1e-5);
00540 EXPECT_NEAR (shots->points[103].descriptor[54], 0.012025614, 1e-5);
00541 EXPECT_NEAR (shots->points[103].descriptor[55], 0.0044803056, 1e-5);
00542 EXPECT_NEAR (shots->points[103].descriptor[64], 0.064429596, 1e-5);
00543 EXPECT_NEAR (shots->points[103].descriptor[65], 0.046486385, 1e-5);
00544 EXPECT_NEAR (shots->points[103].descriptor[86], 0.011518310, 1e-5);
00545
00546 EXPECT_NEAR (shots->points[103].descriptor[357], 0.0020453099, 1e-5);
00547 EXPECT_NEAR (shots->points[103].descriptor[360], 0.0027993850, 1e-5);
00548 EXPECT_NEAR (shots->points[103].descriptor[386], 0.045115642, 1e-5);
00549 EXPECT_NEAR (shots->points[103].descriptor[387], 0.059068538, 1e-5);
00550 EXPECT_NEAR (shots->points[103].descriptor[389], 0.0047547864, 1e-5);
00551 EXPECT_NEAR (shots->points[103].descriptor[453], 0.0051176427, 1e-5);
00552 EXPECT_NEAR (shots->points[103].descriptor[481], 0.0053625242, 1e-5);
00553 EXPECT_NEAR (shots->points[103].descriptor[482], 0.012025614, 1e-5);
00554 EXPECT_NEAR (shots->points[103].descriptor[511], 0.0057367259, 1e-5);
00555 EXPECT_NEAR (shots->points[103].descriptor[512], 0.048357654, 1e-5);
00556
00557
00558 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00559 for (size_t i = 0; i < cloud.size (); i+=3)
00560 test_indices->push_back (static_cast<int> (i));
00561
00562 testSHOTIndicesAndSearchSurface<SHOTEstimationOMP<PointXYZRGBA, Normal, SHOT>, PointXYZRGBA, Normal, SHOT> (cloudWithColors.makeShared (), normals, test_indices);
00563 }
00564
00566 TEST (PCL, 3DSCEstimation)
00567 {
00568 float meshRes = 0.002f;
00569 size_t nBinsL = 4;
00570 size_t nBinsK = 4;
00571 size_t nBinsJ = 4;
00572 float radius = 20.0f * meshRes;
00573 float rmin = radius / 10.0f;
00574 float ptDensityRad = radius / 5.0f;
00575
00576 PointCloud<PointXYZ>::Ptr cloudptr = cloud.makeShared ();
00577
00578
00579 NormalEstimation<PointXYZ, Normal> ne;
00580 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00581
00582 ne.setInputCloud (cloudptr);
00583 ne.setSearchMethod (tree);
00584 ne.setRadiusSearch (radius);
00585
00586 ne.compute (*normals);
00587 ShapeContext3DEstimation<PointXYZ, Normal, SHOT> sc3d;
00588 sc3d.setInputCloud (cloudptr);
00589 sc3d.setInputNormals (normals);
00590 sc3d.setSearchMethod (tree);
00591 sc3d.setRadiusSearch (radius);
00592 sc3d.setAzimuthBins (nBinsL);
00593 sc3d.setElevationBins (nBinsK);
00594 sc3d.setRadiusBins (nBinsJ);
00595 sc3d.setMinimalRadius (rmin);
00596 sc3d.setPointDensityRadius (ptDensityRad);
00597
00598 PointCloud<SHOT>::Ptr sc3ds (new PointCloud<SHOT> ());
00599 sc3d.compute (*sc3ds);
00600 EXPECT_EQ (sc3ds->size (), cloud.size ());
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 EXPECT_NEAR ((*sc3ds)[0].rf[0], 0.0f, 1e-4f);
00614 EXPECT_NEAR ((*sc3ds)[0].rf[1], 0.0f, 1e-4f);
00615 EXPECT_NEAR ((*sc3ds)[0].rf[2], 0.0f, 1e-4f);
00616 EXPECT_NEAR ((*sc3ds)[0].rf[3], 0.0f, 1e-4f);
00617 EXPECT_NEAR ((*sc3ds)[0].rf[4], 0.0f, 1e-4f);
00618 EXPECT_NEAR ((*sc3ds)[0].rf[5], 0.0f, 1e-4f);
00619 EXPECT_NEAR ((*sc3ds)[0].rf[6], 0.0f, 1e-4f);
00620 EXPECT_NEAR ((*sc3ds)[0].rf[7], 0.0f, 1e-4f);
00621 EXPECT_NEAR ((*sc3ds)[0].rf[8], 0.0f, 1e-4f);
00622
00623 EXPECT_EQ ((*sc3ds)[0].descriptor.size (), 64);
00624 EXPECT_NEAR ((*sc3ds)[0].descriptor[4], 52.2474f, 1e-4f);
00625 EXPECT_NEAR ((*sc3ds)[0].descriptor[6], 150.901611328125, 1e-4f);
00626 EXPECT_NEAR ((*sc3ds)[0].descriptor[7], 169.09703063964844, 1e-4f);
00627 EXPECT_NEAR ((*sc3ds)[0].descriptor[8], 0, 1e-4f);
00628 EXPECT_NEAR ((*sc3ds)[0].descriptor[21], 39.1745f, 1e-4f);
00629
00630 EXPECT_NEAR ((*sc3ds)[2].descriptor[4], 0.0f, 1e-4f);
00631 EXPECT_NEAR ((*sc3ds)[2].descriptor[6], 73.7986f, 1e-4f);
00632 EXPECT_NEAR ((*sc3ds)[2].descriptor[7], 209.97763061523438, 1e-4f);
00633 EXPECT_NEAR ((*sc3ds)[2].descriptor[9], 68.5553f, 1e-4f);
00634 EXPECT_NEAR ((*sc3ds)[2].descriptor[16], 0.0f, 1e-4f);
00635 EXPECT_NEAR ((*sc3ds)[2].descriptor[17], 0.0f, 1e-4f);
00636 EXPECT_NEAR ((*sc3ds)[2].descriptor[18], 0.0f, 1e-4f);
00637 EXPECT_NEAR ((*sc3ds)[2].descriptor[20], 0.0f, 1e-4f);
00638 EXPECT_NEAR ((*sc3ds)[2].descriptor[21], 39.1745f, 1e-4f);
00639 EXPECT_NEAR ((*sc3ds)[2].descriptor[22], 154.2060f, 1e-4f);
00640 EXPECT_NEAR ((*sc3ds)[2].descriptor[23], 275.63433837890625, 1e-4f);
00641
00642
00643 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00644 for (size_t i = 0; i < cloud.size (); i++)
00645 test_indices->push_back (static_cast<int> (i));
00646
00647 testSHOTIndicesAndSearchSurface<ShapeContext3DEstimation<PointXYZ, Normal, SHOT>, PointXYZ, Normal, SHOT> (cloudptr, normals, test_indices);
00648 }
00649
00651 TEST (PCL, USCEstimation)
00652 {
00653 float meshRes = 0.002f;
00654 size_t nBinsL = 4;
00655 size_t nBinsK = 4;
00656 size_t nBinsJ = 4;
00657 float radius = 20.0f * meshRes;
00658 float rmin = radius / 10.0f;
00659 float ptDensityRad = radius / 5.0f;
00660
00661
00662 UniqueShapeContext<PointXYZ, SHOT> uscd;
00663 uscd.setInputCloud (cloud.makeShared ());
00664 uscd.setSearchMethod (tree);
00665 uscd.setRadiusSearch (radius);
00666 uscd.setAzimuthBins (nBinsL);
00667 uscd.setElevationBins (nBinsK);
00668 uscd.setRadiusBins (nBinsJ);
00669 uscd.setMinimalRadius (rmin);
00670 uscd.setPointDensityRadius (ptDensityRad);
00671 uscd.setLocalRadius (radius);
00672
00673 PointCloud<SHOT>::Ptr uscds (new PointCloud<SHOT>);
00674 uscd.compute (*uscds);
00675 EXPECT_EQ (uscds->size (), cloud.size ());
00676
00677 EXPECT_NEAR ((*uscds)[0].rf[0], 0.9876f, 1e-4f);
00678 EXPECT_NEAR ((*uscds)[0].rf[1], -0.1408f, 1e-4f);
00679 EXPECT_NEAR ((*uscds)[0].rf[2], -0.06949f, 1e-4f);
00680 EXPECT_NEAR ((*uscds)[0].rf[3], -0.06984f, 1e-4f);
00681 EXPECT_NEAR ((*uscds)[0].rf[4], -0.7904f, 1e-4f);
00682 EXPECT_NEAR ((*uscds)[0].rf[5], 0.6086f, 1e-4f);
00683 EXPECT_NEAR ((*uscds)[0].rf[6], -0.1406f, 1e-4f);
00684 EXPECT_NEAR ((*uscds)[0].rf[7], -0.5962f, 1e-4f);
00685 EXPECT_NEAR ((*uscds)[0].rf[8], -0.7904f, 1e-4f);
00686
00687 EXPECT_EQ ((*uscds)[0].descriptor.size (), 64);
00688 EXPECT_NEAR ((*uscds)[0].descriptor[4], 52.2474f, 1e-4f);
00689 EXPECT_NEAR ((*uscds)[0].descriptor[5], 39.1745f, 1e-4f);
00690 EXPECT_NEAR ((*uscds)[0].descriptor[6], 176.2354f, 1e-4f);
00691 EXPECT_NEAR ((*uscds)[0].descriptor[7], 199.4478f, 1e-4f);
00692 EXPECT_NEAR ((*uscds)[0].descriptor[8], 0.0f, 1e-4f);
00693
00694 EXPECT_NEAR ((*uscds)[2].descriptor[6], 110.1472f, 1e-4f);
00695 EXPECT_NEAR ((*uscds)[2].descriptor[7], 145.5597f, 1e-4f);
00696 EXPECT_NEAR ((*uscds)[2].descriptor[8], 69.6632f, 1e-4f);
00697 EXPECT_NEAR ((*uscds)[2].descriptor[22], 57.2765f, 1e-4f);
00698 EXPECT_NEAR ((*uscds)[2].descriptor[23], 172.8134f, 1e-4f);
00699 EXPECT_NEAR ((*uscds)[2].descriptor[25], 68.5554f, 1e-4f);
00700 EXPECT_NEAR ((*uscds)[2].descriptor[26], 0.0f, 1e-4f);
00701 EXPECT_NEAR ((*uscds)[2].descriptor[27], 0.0f, 1e-4f);
00702 EXPECT_NEAR ((*uscds)[2].descriptor[37], 39.1745f, 1e-4f);
00703 EXPECT_NEAR ((*uscds)[2].descriptor[38], 71.5957f, 1e-4f);
00704
00705
00706 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00707 for (size_t i = 0; i < cloud.size (); i+=3)
00708 test_indices->push_back (static_cast<int> (i));
00709
00710 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00711 testSHOTIndicesAndSearchSurface<UniqueShapeContext<PointXYZ, SHOT>, PointXYZ, Normal, SHOT> (cloud.makeShared (), normals, test_indices);
00712 }
00713
00714 #ifndef PCL_ONLY_CORE_POINT_TYPES
00715
00716 template <> UniqueShapeContext<PointXYZ, Eigen::MatrixXf>
00717 createSHOTDesc<UniqueShapeContext<PointXYZ, Eigen::MatrixXf>, PointXYZ, Normal, Eigen::MatrixXf> (
00718 const PointCloud<Normal>::Ptr &,
00719 const int,
00720 const int,
00721 const bool,
00722 const bool)
00723 {
00724 UniqueShapeContext<PointXYZ, Eigen::MatrixXf> usc;
00725 usc.setAzimuthBins (4);
00726 usc.setElevationBins (4);
00727 usc.setRadiusBins (4);
00728 usc.setMinimalRadius (0.004);
00729 usc.setPointDensityRadius (0.008);
00730 usc.setLocalRadius (0.04f);
00731 return (usc);
00732 }
00733
00735 template <> ShapeContext3DEstimation<PointXYZ, Normal, Eigen::MatrixXf>
00736 createSHOTDesc<ShapeContext3DEstimation<PointXYZ, Normal, Eigen::MatrixXf>, PointXYZ, Normal, Eigen::MatrixXf> (
00737 const PointCloud<Normal>::Ptr & normals,
00738 const int,
00739 const int,
00740 const bool,
00741 const bool)
00742 {
00743 ShapeContext3DEstimation<PointXYZ, Normal, Eigen::MatrixXf> sc3d;
00744 sc3d.setAzimuthBins (4);
00745 sc3d.setElevationBins (4);
00746 sc3d.setRadiusBins (4);
00747 sc3d.setMinimalRadius (0.004);
00748 sc3d.setPointDensityRadius (0.008);
00749 sc3d.setInputNormals (normals);
00750 return (sc3d);
00751 }
00752
00754 template <typename FeatureEstimation, typename PointT, typename NormalT> void
00755 testSHOTIndicesAndSearchSurfaceEigen (const typename PointCloud<PointT>::Ptr & points,
00756 const typename PointCloud<NormalT>::Ptr & normals,
00757 const boost::shared_ptr<vector<int> > & indices,
00758 const int nr_shape_bins = 10,
00759 const int nr_color_bins = 30,
00760 const bool describe_shape = true,
00761 const bool describe_color = false)
00762 {
00763 double radius = 0.04;
00764
00765
00766
00767 PointCloud<Eigen::MatrixXf> full_output, output0, output1, output2;
00768
00769
00770 FeatureEstimation est0 = createSHOTDesc<FeatureEstimation, PointT, NormalT, Eigen::MatrixXf>(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00771 est0.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00772 est0.setRadiusSearch (radius);
00773 est0.setInputCloud (points);
00774 est0.computeEigen (full_output);
00775
00776 output0 = PointCloud<Eigen::MatrixXf> (full_output, *indices);
00777
00778
00779 typename PointCloud<PointT>::Ptr subpoints (new PointCloud<PointT>);
00780 copyPointCloud (*points, *indices, *subpoints);
00781 FeatureEstimation est1 = createSHOTDesc<FeatureEstimation, PointT, NormalT, Eigen::MatrixXf>(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00782 est1.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00783 est1.setRadiusSearch (radius);
00784 est1.setInputCloud (subpoints);
00785 est1.setSearchSurface (points);
00786 est1.computeEigen (output1);
00787
00789 FeatureEstimation est2 = createSHOTDesc<FeatureEstimation, PointT, NormalT, Eigen::MatrixXf>(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00790 est2.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00791 est2.setRadiusSearch (radius);
00792 est2.setInputCloud (points);
00793 est2.setIndices (indices);
00794 est2.computeEigen (output2);
00795
00796
00797 ASSERT_EQ (output0.points.rows (), output1.points.rows ());
00798 ASSERT_EQ (output1.points.rows (), output2.points.rows ());
00799 for (int i = 0; i < output1.points.rows (); ++i)
00800 {
00801 for (int j = 0; j < output0.points.cols (); ++j)
00802 {
00803 ASSERT_EQ (output0.points (i, j), output1.points (i, j));
00804 ASSERT_EQ (output1.points (i, j), output2.points (i, j));
00805 }
00806 }
00807
00808
00809
00810
00811 PointCloud<Eigen::MatrixXf> output3, output4;
00812
00813 boost::shared_ptr<vector<int> > indices2 (new vector<int> (0));
00814 for (size_t i = 0; i < (indices->size ()/2); ++i)
00815 indices2->push_back (static_cast<int> (i));
00816
00817
00818 FeatureEstimation est3 = createSHOTDesc<FeatureEstimation, PointT, NormalT, Eigen::MatrixXf>(normals, nr_shape_bins,nr_color_bins,describe_shape,describe_color);
00819 est3.setSearchMethod (typename search::KdTree<PointT>::Ptr (new search::KdTree<PointT>));
00820 est3.setRadiusSearch (0.04);
00821 est3.setSearchSurface (points);
00822 est3.setInputCloud (subpoints);
00823 est3.setIndices (indices2);
00824 est3.computeEigen (output3);
00825
00826
00827 output4 = PointCloud<Eigen::MatrixXf> (output0, *indices2);
00828
00829
00830 ASSERT_EQ (output3.points.rows (), output4.points.rows ());
00831 for (int i = 0; i < output3.points.rows (); ++i)
00832 for (int j = 0; j < output3.points.cols (); ++j)
00833 ASSERT_EQ (output3.points (i, j), output4.points (i, j));
00834 }
00835
00837 TEST (PCL, SHOTShapeEstimationEigen)
00838 {
00839
00840 double mr = 0.002;
00841 NormalEstimation<PointXYZ, Normal> n;
00842 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00843
00844 n.setInputCloud (cloud.makeShared ());
00845 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00846 n.setIndices (indicesptr);
00847 n.setSearchMethod (tree);
00848 n.setRadiusSearch (20 * mr);
00849 n.compute (*normals);
00850
00851 EXPECT_NEAR (normals->points[103].normal_x, 0.36683175, 1e-4);
00852 EXPECT_NEAR (normals->points[103].normal_y, -0.44696972, 1e-4);
00853 EXPECT_NEAR (normals->points[103].normal_z, -0.81587529, 1e-4);
00854 EXPECT_NEAR (normals->points[200].normal_x, -0.71414840, 1e-4);
00855 EXPECT_NEAR (normals->points[200].normal_y, -0.06002361, 1e-4);
00856 EXPECT_NEAR (normals->points[200].normal_z, -0.69741613, 1e-4);
00857
00858 EXPECT_NEAR (normals->points[140].normal_x, -0.45109111, 1e-4);
00859 EXPECT_NEAR (normals->points[140].normal_y, -0.19499126, 1e-4);
00860 EXPECT_NEAR (normals->points[140].normal_z, -0.87091631, 1e-4);
00861
00862 SHOTEstimation<PointXYZ, Normal, Eigen::MatrixXf> shot;
00863 shot.setInputNormals (normals);
00864 EXPECT_EQ (shot.getInputNormals (), normals);
00865 shot.setRadiusSearch (20 * mr);
00866
00867
00868 PointCloud<Eigen::MatrixXf>::Ptr shots (new PointCloud<Eigen::MatrixXf>);
00869
00870
00871 shot.setInputCloud (cloud.makeShared ());
00872 shot.setIndices (indicesptr);
00873 shot.setSearchMethod (tree);
00874
00875
00876 shot.computeEigen (*shots);
00877 EXPECT_EQ (shots->points.rows (), indices.size ());
00878
00879 EXPECT_NEAR (shots->points (103, 9 ), 0.0072018504, 1e-4);
00880 EXPECT_NEAR (shots->points (103, 10), 0.0023103887, 1e-4);
00881 EXPECT_NEAR (shots->points (103, 11), 0.0024724449, 1e-4);
00882 EXPECT_NEAR (shots->points (103, 19), 0.0031367359, 1e-4);
00883 EXPECT_NEAR (shots->points (103, 20), 0.17439659, 1e-4);
00884 EXPECT_NEAR (shots->points (103, 21), 0.070665278, 1e-4);
00885 EXPECT_NEAR (shots->points (103, 42), 0.013304681, 1e-4);
00886 EXPECT_NEAR (shots->points (103, 53), 0.0073520984, 1e-4);
00887 EXPECT_NEAR (shots->points (103, 54), 0.013584172, 1e-4);
00888 EXPECT_NEAR (shots->points (103, 55), 0.0050609680, 1e-4);
00889
00890
00891 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00892 for (size_t i = 0; i < cloud.points.size (); i+=3)
00893 test_indices->push_back (static_cast<int> (i));
00894
00895 testSHOTIndicesAndSearchSurfaceEigen<SHOTEstimation<PointXYZ, Normal, Eigen::MatrixXf>, PointXYZ, Normal> (cloud.makeShared (), normals, test_indices);
00896
00897 }
00898
00900 TEST (PCL, GenericSHOTShapeEstimationEigen)
00901 {
00902
00903 const int shapeStep_ = 20;
00904
00905
00906
00907 double mr = 0.002;
00908 NormalEstimation<PointXYZ, Normal> n;
00909 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00910
00911 n.setInputCloud (cloud.makeShared ());
00912 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00913 n.setIndices (indicesptr);
00914 n.setSearchMethod (tree);
00915 n.setRadiusSearch (20 * mr);
00916 n.compute (*normals);
00917
00918 SHOTEstimation<PointXYZ, Normal, Eigen::MatrixXf> shot (shapeStep_);
00919 shot.setInputNormals (normals);
00920 EXPECT_EQ (shot.getInputNormals (), normals);
00921
00922 shot.setRadiusSearch (20 * mr);
00923
00924 PointCloud<Eigen::MatrixXf>::Ptr shots (new PointCloud<Eigen::MatrixXf>);
00925
00926
00927 shot.setInputCloud (cloud.makeShared ());
00928 shot.setIndices (indicesptr);
00929 shot.setSearchMethod (tree);
00930
00931
00932 shot.computeEigen (*shots);
00933 EXPECT_EQ (shots->points.rows (), indices.size ());
00934
00935 EXPECT_NEAR (shots->points (103, 18), 0.0077019366, 1e-5);
00936 EXPECT_NEAR (shots->points (103, 19), 0.0024708188, 1e-5);
00937 EXPECT_NEAR (shots->points (103, 21), 0.0079652183, 1e-5);
00938 EXPECT_NEAR (shots->points (103, 38), 0.0067090928, 1e-5);
00939 EXPECT_NEAR (shots->points (103, 39), 0.17498907, 1e-5);
00940 EXPECT_NEAR (shots->points (103, 40), 0.078413926, 1e-5);
00941 EXPECT_NEAR (shots->points (103, 81), 0.014228539, 1e-5);
00942 EXPECT_NEAR (shots->points (103, 103), 0.022390056, 1e-5);
00943 EXPECT_NEAR (shots->points (103, 105), 0.0058866320, 1e-5);
00944 EXPECT_NEAR (shots->points (103, 123), 0.019105887, 1e-5);
00945
00946
00947 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
00948 for (size_t i = 0; i < cloud.size (); i+=3)
00949 test_indices->push_back (static_cast<int> (i));
00950
00951 testSHOTIndicesAndSearchSurfaceEigen<SHOTEstimation<PointXYZ, Normal, Eigen::MatrixXf>, PointXYZ, Normal> (cloud.makeShared (), normals, test_indices, shapeStep_);
00952 }
00953
00955 TEST (PCL, SHOTShapeAndColorEstimationEigen)
00956 {
00957 double mr = 0.002;
00958
00959 NormalEstimation<PointXYZ, Normal> n;
00960 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00961
00962 n.setInputCloud (cloud.makeShared ());
00963 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00964 n.setIndices (indicesptr);
00965 n.setSearchMethod (tree);
00966 n.setRadiusSearch (20 * mr);
00967 n.compute (*normals);
00968
00969 search::KdTree<PointXYZRGBA>::Ptr rgbaTree;
00970 rgbaTree.reset (new search::KdTree<PointXYZRGBA> (false));
00971
00972
00973 SHOTEstimation<PointXYZRGBA, Normal, Eigen::MatrixXf> shot (true, true);
00974 shot.setInputNormals (normals);
00975 EXPECT_EQ (shot.getInputNormals (), normals);
00976
00977 shot.setRadiusSearch (20 * mr);
00978
00979
00980 PointCloud<PointXYZRGBA> cloudWithColors;
00981 for (int i = 0; i < static_cast<int> (cloud.points.size ()); ++i)
00982 {
00983 PointXYZRGBA p;
00984 p.x = cloud.points[i].x;
00985 p.y = cloud.points[i].y;
00986 p.z = cloud.points[i].z;
00987
00988 p.rgba = ( (i%255) << 16 ) + ( ( (255 - i ) %255) << 8) + ( ( i*37 ) %255);
00989 cloudWithColors.push_back (p);
00990 }
00991
00992 rgbaTree->setInputCloud (cloudWithColors.makeShared ());
00993 PointCloud<Eigen::MatrixXf>::Ptr shots (new PointCloud<Eigen::MatrixXf>);
00994
00995 shot.setInputCloud (cloudWithColors.makeShared ());
00996 shot.setIndices (indicesptr);
00997 shot.setSearchMethod (rgbaTree);
00998
00999
01000 shot.computeEigen (*shots);
01001 EXPECT_EQ (shots->points.rows (), indices.size ());
01002
01003 EXPECT_NEAR (shots->points (103, 10), 0.0020453099, 1e-5);
01004 EXPECT_NEAR (shots->points (103, 11), 0.0021887729, 1e-5);
01005 EXPECT_NEAR (shots->points (103, 21), 0.062557608, 1e-5);
01006 EXPECT_NEAR (shots->points (103, 42), 0.011778189, 1e-5);
01007 EXPECT_NEAR (shots->points (103, 53), 0.0065085669, 1e-5);
01008 EXPECT_NEAR (shots->points (103, 54), 0.012025614, 1e-5);
01009 EXPECT_NEAR (shots->points (103, 55), 0.0044803056, 1e-5);
01010 EXPECT_NEAR (shots->points (103, 64), 0.064429596, 1e-5);
01011 EXPECT_NEAR (shots->points (103, 65), 0.046486385, 1e-5);
01012 EXPECT_NEAR (shots->points (103, 86), 0.011518310, 1e-5);
01013
01014 EXPECT_NEAR (shots->points (103, 357), 0.0020453099, 1e-5);
01015 EXPECT_NEAR (shots->points (103, 360), 0.0027993850, 1e-5);
01016 EXPECT_NEAR (shots->points (103, 386), 0.045115642, 1e-5);
01017 EXPECT_NEAR (shots->points (103, 387), 0.059068538, 1e-5);
01018 EXPECT_NEAR (shots->points (103, 389), 0.0047547864, 1e-5);
01019 EXPECT_NEAR (shots->points (103, 453), 0.0051176427, 1e-5);
01020 EXPECT_NEAR (shots->points (103, 481), 0.0053625242, 1e-5);
01021 EXPECT_NEAR (shots->points (103, 482), 0.012025614, 1e-5);
01022 EXPECT_NEAR (shots->points (103, 511), 0.0057367259, 1e-5);
01023 EXPECT_NEAR (shots->points (103, 512), 0.048357654, 1e-5);
01024
01025
01026 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
01027 for (size_t i = 0; i < cloud.size (); i+=3)
01028 test_indices->push_back (static_cast<int> (i));
01029
01030 testSHOTIndicesAndSearchSurfaceEigen<SHOTEstimation<PointXYZRGBA, Normal, Eigen::MatrixXf>, PointXYZRGBA, Normal> (cloudWithColors.makeShared (), normals, test_indices);
01031 }
01032
01034 TEST (PCL, 3DSCEstimationEigen)
01035 {
01036 float meshRes = 0.002f;
01037 size_t nBinsL = 4;
01038 size_t nBinsK = 4;
01039 size_t nBinsJ = 4;
01040 float radius = 20.0f * meshRes;
01041 float rmin = radius / 10.0f;
01042 float ptDensityRad = radius / 5.0f;
01043
01044 PointCloud<PointXYZ>::Ptr cloudptr = cloud.makeShared ();
01045
01046
01047 NormalEstimation<PointXYZ, Normal> ne;
01048 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
01049
01050 ne.setInputCloud (cloudptr);
01051 ne.setSearchMethod (tree);
01052 ne.setRadiusSearch (radius);
01053
01054 ne.compute (*normals);
01055 ShapeContext3DEstimation<PointXYZ, Normal, Eigen::MatrixXf> sc3d;
01056 sc3d.setInputCloud (cloudptr);
01057 sc3d.setInputNormals (normals);
01058 sc3d.setSearchMethod (tree);
01059 sc3d.setRadiusSearch (radius);
01060 sc3d.setAzimuthBins (nBinsL);
01061 sc3d.setElevationBins (nBinsK);
01062 sc3d.setRadiusBins (nBinsJ);
01063 sc3d.setMinimalRadius (rmin);
01064 sc3d.setPointDensityRadius (ptDensityRad);
01065
01066 PointCloud<Eigen::MatrixXf>::Ptr sc3ds (new PointCloud<Eigen::MatrixXf>);
01067 sc3d.computeEigen (*sc3ds);
01068 EXPECT_EQ (sc3ds->points.rows (), cloud.size ());
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 EXPECT_NEAR (sc3ds->points (0, 0), 0.0f, 1e-4f);
01082 EXPECT_NEAR (sc3ds->points (0, 1), 0.0f, 1e-4f);
01083 EXPECT_NEAR (sc3ds->points (0, 2), 0.0f, 1e-4f);
01084 EXPECT_NEAR (sc3ds->points (0, 3), 0.0f, 1e-4f);
01085 EXPECT_NEAR (sc3ds->points (0, 4), 0.0f, 1e-4f);
01086 EXPECT_NEAR (sc3ds->points (0, 5), 0.0f, 1e-4f);
01087 EXPECT_NEAR (sc3ds->points (0, 6), 0.0f, 1e-4f);
01088 EXPECT_NEAR (sc3ds->points (0, 7), 0.0f, 1e-4f);
01089 EXPECT_NEAR (sc3ds->points (0, 8), 0.0f, 1e-4f);
01090
01091 EXPECT_EQ (sc3ds->points.row (0).size (), 64 + 9);
01092 EXPECT_NEAR (sc3ds->points (0, 9 + 4), 52.2474f, 1e-4f);
01093 EXPECT_NEAR (sc3ds->points (0, 9 + 6), 150.901611328125, 1e-4f);
01094 EXPECT_NEAR (sc3ds->points (0, 9 + 7), 169.09703063964844, 1e-4f);
01095 EXPECT_NEAR (sc3ds->points (0, 9 + 8), 0, 1e-4f);
01096 EXPECT_NEAR (sc3ds->points (0, 9 + 21), 39.1745f, 1e-4f);
01097
01098 EXPECT_NEAR (sc3ds->points (2, 9 + 4), 0.0f, 1e-4f);
01099 EXPECT_NEAR (sc3ds->points (2, 9 + 6), 73.7986f, 1e-4f);
01100 EXPECT_NEAR (sc3ds->points (2, 9 + 7), 209.97763061523438, 1e-4f);
01101
01102 EXPECT_NEAR (sc3ds->points (2, 9 + 9), 68.5553f, 1e-4f);
01103 EXPECT_NEAR (sc3ds->points (2, 9 + 16), 0.0f, 1e-4f);
01104 EXPECT_NEAR (sc3ds->points (2, 9 + 17), 0.0f, 1e-4f);
01105 EXPECT_NEAR (sc3ds->points (2, 9 + 18), 0.0f, 1e-4f);
01106 EXPECT_NEAR (sc3ds->points (2, 9 + 20), 0.0f, 1e-4f);
01107
01108 EXPECT_NEAR (sc3ds->points (2, 9 + 21), 39.1745f, 1e-4f);
01109 EXPECT_NEAR (sc3ds->points (2, 9 + 22), 154.2060f, 1e-4f);
01110 EXPECT_NEAR (sc3ds->points (2, 9 + 23), 275.63433837890625, 1e-4f);
01111
01112
01113 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
01114 for (size_t i = 0; i < cloud.size (); i++)
01115 test_indices->push_back (static_cast<int> (i));
01116
01117 testSHOTIndicesAndSearchSurfaceEigen<ShapeContext3DEstimation<PointXYZ, Normal, Eigen::MatrixXf>, PointXYZ, Normal> (cloudptr, normals, test_indices);
01118 }
01119
01121 TEST (PCL, USCEstimationEigen)
01122 {
01123 float meshRes = 0.002f;
01124 size_t nBinsL = 4;
01125 size_t nBinsK = 4;
01126 size_t nBinsJ = 4;
01127 float radius = 20.0f * meshRes;
01128 float rmin = radius / 10.0f;
01129 float ptDensityRad = radius / 5.0f;
01130
01131
01132 UniqueShapeContext<PointXYZ, Eigen::MatrixXf> uscd;
01133 uscd.setInputCloud (cloud.makeShared ());
01134 uscd.setSearchMethod (tree);
01135 uscd.setRadiusSearch (radius);
01136 uscd.setAzimuthBins (nBinsL);
01137 uscd.setElevationBins (nBinsK);
01138 uscd.setRadiusBins (nBinsJ);
01139 uscd.setMinimalRadius (rmin);
01140 uscd.setPointDensityRadius (ptDensityRad);
01141 uscd.setLocalRadius (radius);
01142
01143 PointCloud<Eigen::MatrixXf>::Ptr uscds (new PointCloud<Eigen::MatrixXf>);
01144 uscd.computeEigen (*uscds);
01145 EXPECT_EQ (uscds->points.rows (), cloud.size ());
01146
01147 EXPECT_NEAR (uscds->points (0, 0), 0.9876f, 1e-4f);
01148 EXPECT_NEAR (uscds->points (0, 1), -0.1408f, 1e-4f);
01149 EXPECT_NEAR (uscds->points (0, 2), -0.06949f, 1e-4f);
01150 EXPECT_NEAR (uscds->points (0, 3), -0.06984f, 1e-4f);
01151 EXPECT_NEAR (uscds->points (0, 4), -0.7904f, 1e-4f);
01152 EXPECT_NEAR (uscds->points (0, 5), 0.6086f, 1e-4f);
01153 EXPECT_NEAR (uscds->points (0, 6), -0.1406f, 1e-4f);
01154 EXPECT_NEAR (uscds->points (0, 7), -0.5962f, 1e-4f);
01155 EXPECT_NEAR (uscds->points (0, 8), -0.7904f, 1e-4f);
01156
01157 EXPECT_EQ (uscds->points.row (0).size (), 9+64);
01158 EXPECT_NEAR (uscds->points (0, 9 + 4), 52.2474f, 1e-4f);
01159 EXPECT_NEAR (uscds->points (0, 9 + 5), 39.1745f, 1e-4f);
01160 EXPECT_NEAR (uscds->points (0, 9 + 6), 176.2354f, 1e-4f);
01161 EXPECT_NEAR (uscds->points (0, 9 + 7), 199.4478f, 1e-4f);
01162 EXPECT_NEAR (uscds->points (0, 9 + 8), 0.0f, 1e-4f);
01163
01164 EXPECT_NEAR (uscds->points (2, 9 + 6), 110.1472f, 1e-4f);
01165 EXPECT_NEAR (uscds->points (2, 9 + 7), 145.5597f, 1e-4f);
01166 EXPECT_NEAR (uscds->points (2, 9 + 8), 69.6632f, 1e-4f);
01167 EXPECT_NEAR (uscds->points (2, 9 + 22), 57.2765f, 1e-4f);
01168 EXPECT_NEAR (uscds->points (2, 9 + 23), 172.8134f, 1e-4f);
01169 EXPECT_NEAR (uscds->points (2, 9 + 25), 68.5554f, 1e-4f);
01170 EXPECT_NEAR (uscds->points (2, 9 + 26), 0.0f, 1e-4f);
01171 EXPECT_NEAR (uscds->points (2, 9 + 27), 0.0f, 1e-4f);
01172 EXPECT_NEAR (uscds->points (2, 9 + 37), 39.1745f, 1e-4f);
01173 EXPECT_NEAR (uscds->points (2, 9 + 38), 71.5957f, 1e-4f);
01174
01175
01176 boost::shared_ptr<vector<int> > test_indices (new vector<int> (0));
01177 for (size_t i = 0; i < cloud.size (); i+=3)
01178 test_indices->push_back (static_cast<int> (i));
01179
01180 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
01181 testSHOTIndicesAndSearchSurfaceEigen<UniqueShapeContext<PointXYZ, Eigen::MatrixXf>, PointXYZ, Normal> (cloud.makeShared (), normals, test_indices);
01182 }
01183 #endif
01184
01185
01186 int
01187 main (int argc, char** argv)
01188 {
01189 if (argc < 2)
01190 {
01191 std::cerr << "No test file given. Please download `bun0.pcd` and pass its path to the test." << std::endl;
01192 return (-1);
01193 }
01194
01195 if (loadPCDFile<PointXYZ> (argv[1], cloud) < 0)
01196 {
01197 std::cerr << "Failed to read test file. Please download `bun0.pcd` and pass its path to the test." << std::endl;
01198 return (-1);
01199 }
01200
01201 indices.resize (cloud.points.size ());
01202 for (size_t i = 0; i < indices.size (); ++i)
01203 indices[i] = static_cast<int> (i);
01204
01205 tree.reset (new search::KdTree<PointXYZ> (false));
01206 tree->setInputCloud (cloud.makeShared ());
01207
01208 testing::InitGoogleTest (&argc, argv);
01209 return (RUN_ALL_TESTS ());
01210 }
01211