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
00039 #include <gtest/gtest.h>
00040
00041 #include <boost/make_shared.hpp>
00042 #include <pcl/point_types.h>
00043 #include <pcl/io/pcd_io.h>
00044 #include <pcl/kdtree/kdtree_flann.h>
00045 #include <pcl/features/feature.h>
00046 #include <pcl/features/normal_3d_omp.h>
00047
00048 #include <pcl/features/moment_invariants.h>
00049 #include <pcl/features/boundary.h>
00050 #include <pcl/features/principal_curvatures.h>
00051 #include <pcl/features/pfh.h>
00052 #include <pcl/features/fpfh.h>
00053 #include <pcl/features/fpfh_omp.h>
00054 #include <pcl/features/vfh.h>
00055 #include <pcl/features/rsd.h>
00056 #include <pcl/features/intensity_gradient.h>
00057 #include <pcl/features/intensity_spin.h>
00058 #include <pcl/features/rift.h>
00059
00060 using namespace pcl;
00061 using namespace pcl::io;
00062 using namespace std;
00063
00064 typedef KdTree<PointXYZ>::Ptr KdTreePtr;
00065
00066 PointCloud<PointXYZ> cloud;
00067 vector<int> indices;
00068 KdTreePtr tree;
00069
00071 TEST (PCL, BaseFeature)
00072 {
00073
00074 Eigen::Vector4f centroid3;
00075 compute3DCentroid (cloud, indices, centroid3);
00076 EXPECT_NEAR (centroid3[0], -0.0290809, 1e-4);
00077 EXPECT_NEAR (centroid3[1], 0.102653, 1e-4);
00078 EXPECT_NEAR (centroid3[2], 0.027302, 1e-4);
00079 EXPECT_NEAR (centroid3[3], 0, 1e-4);
00080
00081
00082 compute3DCentroid (cloud, centroid3);
00083 EXPECT_NEAR (centroid3[0], -0.0290809, 1e-4);
00084 EXPECT_NEAR (centroid3[1], 0.102653, 1e-4);
00085 EXPECT_NEAR (centroid3[2], 0.027302, 1e-4);
00086 EXPECT_NEAR (centroid3[3], 0, 1e-4);
00087
00088
00089 Eigen::VectorXf centroidn;
00090 computeNDCentroid (cloud, indices, centroidn);
00091 EXPECT_NEAR (centroidn[0], -0.0290809, 1e-4);
00092 EXPECT_NEAR (centroidn[1], 0.102653, 1e-4);
00093 EXPECT_NEAR (centroidn[2], 0.027302, 1e-4);
00094
00095
00096 computeNDCentroid (cloud, centroidn);
00097 EXPECT_NEAR (centroidn[0], -0.0290809, 1e-4);
00098 EXPECT_NEAR (centroidn[1], 0.102653, 1e-4);
00099 EXPECT_NEAR (centroidn[2], 0.027302, 1e-4);
00100
00101
00102 Eigen::Matrix3f covariance_matrix;
00103 computeCovarianceMatrix (cloud, indices, centroid3, covariance_matrix);
00104 EXPECT_NEAR (covariance_matrix (0, 0), 0.710046, 1e-4);
00105 EXPECT_NEAR (covariance_matrix (0, 1), -0.234843, 1e-4);
00106 EXPECT_NEAR (covariance_matrix (0, 2), 0.0704933, 1e-4);
00107 EXPECT_NEAR (covariance_matrix (1, 0), -0.234843, 1e-4);
00108 EXPECT_NEAR (covariance_matrix (1, 1), 0.68695, 1e-4);
00109 EXPECT_NEAR (covariance_matrix (1, 2), -0.220504, 1e-4);
00110 EXPECT_NEAR (covariance_matrix (2, 0), 0.0704933, 1e-4);
00111 EXPECT_NEAR (covariance_matrix (2, 1), -0.220504, 1e-4);
00112 EXPECT_NEAR (covariance_matrix (2, 2), 0.195448, 1e-4);
00113
00114
00115 computeCovarianceMatrix (cloud, centroid3, covariance_matrix);
00116 EXPECT_NEAR (covariance_matrix (0, 0), 0.710046, 1e-4);
00117 EXPECT_NEAR (covariance_matrix (0, 1), -0.234843, 1e-4);
00118 EXPECT_NEAR (covariance_matrix (0, 2), 0.0704933, 1e-4);
00119 EXPECT_NEAR (covariance_matrix (1, 0), -0.234843, 1e-4);
00120 EXPECT_NEAR (covariance_matrix (1, 1), 0.68695, 1e-4);
00121 EXPECT_NEAR (covariance_matrix (1, 2), -0.220504, 1e-4);
00122 EXPECT_NEAR (covariance_matrix (2, 0), 0.0704933, 1e-4);
00123 EXPECT_NEAR (covariance_matrix (2, 1), -0.220504, 1e-4);
00124 EXPECT_NEAR (covariance_matrix (2, 2), 0.195448, 1e-4);
00125
00126
00127 computeCovarianceMatrixNormalized (cloud, indices, centroid3, covariance_matrix);
00128 EXPECT_NEAR (covariance_matrix (0, 0), 1.7930e-03, 1e-5);
00129 EXPECT_NEAR (covariance_matrix (0, 1), -5.9304e-04, 1e-5);
00130 EXPECT_NEAR (covariance_matrix (0, 2), 1.7801e-04, 1e-5);
00131 EXPECT_NEAR (covariance_matrix (1, 0), -5.9304e-04, 1e-5);
00132 EXPECT_NEAR (covariance_matrix (1, 1), 1.7347e-03, 1e-5);
00133 EXPECT_NEAR (covariance_matrix (1, 2), -5.5683e-04, 1e-5);
00134 EXPECT_NEAR (covariance_matrix (2, 0), 1.7801e-04, 1e-5);
00135 EXPECT_NEAR (covariance_matrix (2, 1), -5.5683e-04, 1e-5);
00136 EXPECT_NEAR (covariance_matrix (2, 2), 4.9356e-04, 1e-5);
00137
00138
00139 computeCovarianceMatrixNormalized (cloud, centroid3, covariance_matrix);
00140 EXPECT_NEAR (covariance_matrix (0, 0), 1.7930e-03, 1e-5);
00141 EXPECT_NEAR (covariance_matrix (0, 1), -5.9304e-04, 1e-5);
00142 EXPECT_NEAR (covariance_matrix (0, 2), 1.7801e-04, 1e-5);
00143 EXPECT_NEAR (covariance_matrix (1, 0), -5.9304e-04, 1e-5);
00144 EXPECT_NEAR (covariance_matrix (1, 1), 1.7347e-03, 1e-5);
00145 EXPECT_NEAR (covariance_matrix (1, 2), -5.5683e-04, 1e-5);
00146 EXPECT_NEAR (covariance_matrix (2, 0), 1.7801e-04, 1e-5);
00147 EXPECT_NEAR (covariance_matrix (2, 1), -5.5683e-04, 1e-5);
00148 EXPECT_NEAR (covariance_matrix (2, 2), 4.9356e-04, 1e-5);
00149
00150
00151
00152 Eigen::Vector4f plane_parameters;
00153 float curvature;
00154 solvePlaneParameters (covariance_matrix, centroid3, plane_parameters, curvature);
00155 EXPECT_NEAR (fabs (plane_parameters[0]), 0.035592, 1e-4);
00156 EXPECT_NEAR (fabs (plane_parameters[1]), 0.369596, 1e-4);
00157 EXPECT_NEAR (fabs (plane_parameters[2]), 0.928511, 1e-4);
00158 EXPECT_NEAR (fabs (plane_parameters[3]), 0.0622552, 1e-4);
00159 EXPECT_NEAR (curvature, 0.0693136, 1e-4);
00160
00161
00162 float nx, ny, nz;
00163 solvePlaneParameters (covariance_matrix, nx, ny, nz, curvature);
00164 EXPECT_NEAR (fabs (nx), 0.035592, 1e-4);
00165 EXPECT_NEAR (fabs (ny), 0.369596, 1e-4);
00166 EXPECT_NEAR (fabs (nz), 0.928511, 1e-4);
00167 EXPECT_NEAR (curvature, 0.0693136, 1e-4);
00168 }
00169
00171 TEST (PCL, NormalEstimation)
00172 {
00173 Eigen::Vector4f plane_parameters;
00174 float curvature;
00175
00176 NormalEstimation<PointXYZ, Normal> n;
00177
00178
00179 n.computePointNormal (cloud, indices, plane_parameters, curvature);
00180 EXPECT_NEAR (fabs (plane_parameters[0]), 0.035592, 1e-4);
00181 EXPECT_NEAR (fabs (plane_parameters[1]), 0.369596, 1e-4);
00182 EXPECT_NEAR (fabs (plane_parameters[2]), 0.928511, 1e-4);
00183 EXPECT_NEAR (fabs (plane_parameters[3]), 0.0622552, 1e-4);
00184 EXPECT_NEAR (curvature, 0.0693136, 1e-4);
00185
00186 float nx, ny, nz;
00187
00188 n.computePointNormal (cloud, indices, nx, ny, nz, curvature);
00189 EXPECT_NEAR (fabs (nx), 0.035592, 1e-4);
00190 EXPECT_NEAR (fabs (ny), 0.369596, 1e-4);
00191 EXPECT_NEAR (fabs (nz), 0.928511, 1e-4);
00192 EXPECT_NEAR (curvature, 0.0693136, 1e-4);
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00224
00225
00226 PointCloud<PointXYZ>::Ptr cloudptr = cloud.makeShared ();
00227 n.setInputCloud (cloudptr);
00228 EXPECT_EQ (n.getInputCloud (), cloudptr);
00229 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00230 n.setIndices (indicesptr);
00231 EXPECT_EQ (n.getIndices (), indicesptr);
00232 n.setSearchMethod (tree);
00233 EXPECT_EQ (n.getSearchMethod (), tree);
00234 n.setKSearch (indices.size ());
00235
00236
00237 n.compute (*normals);
00238 EXPECT_EQ (normals->points.size (), indices.size ());
00239
00240 for (size_t i = 0; i < normals->points.size (); ++i)
00241 {
00242 EXPECT_NEAR (normals->points[i].normal[0], -0.035592, 1e-4);
00243 EXPECT_NEAR (normals->points[i].normal[1], -0.369596, 1e-4);
00244 EXPECT_NEAR (normals->points[i].normal[2], -0.928511, 1e-4);
00245 EXPECT_NEAR (normals->points[i].curvature, 0.0693136, 1e-4);
00246 }
00247
00248 PointCloud<PointXYZ>::Ptr surfaceptr = cloudptr;
00249 n.setSearchSurface (surfaceptr);
00250 EXPECT_EQ (n.getSearchSurface (), surfaceptr);
00251 }
00252
00254 TEST (PCL, NormalEstimationOpenMP)
00255 {
00256 NormalEstimationOMP<PointXYZ, Normal> n (4);
00257
00258
00259 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00260
00261
00262 PointCloud<PointXYZ>::Ptr cloudptr = cloud.makeShared ();
00263 n.setInputCloud (cloudptr);
00264 EXPECT_EQ (n.getInputCloud (), cloudptr);
00265 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00266 n.setIndices (indicesptr);
00267 EXPECT_EQ (n.getIndices (), indicesptr);
00268 n.setSearchMethod (tree);
00269 EXPECT_EQ (n.getSearchMethod (), tree);
00270 n.setKSearch (indices.size ());
00271
00272
00273 n.compute (*normals);
00274 EXPECT_EQ (normals->points.size (), indices.size ());
00275
00276 for (size_t i = 0; i < normals->points.size (); ++i)
00277 {
00278 EXPECT_NEAR (normals->points[i].normal[0], -0.035592, 1e-4);
00279 EXPECT_NEAR (normals->points[i].normal[1], -0.369596, 1e-4);
00280 EXPECT_NEAR (normals->points[i].normal[2], -0.928511, 1e-4);
00281 EXPECT_NEAR (normals->points[i].curvature, 0.0693136, 1e-4);
00282 }
00283 }
00284
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00318 TEST (PCL, MomentInvariantsEstimation)
00319 {
00320 float j1, j2, j3;
00321
00322 MomentInvariantsEstimation<PointXYZ, MomentInvariants> mi;
00323
00324
00325 mi.computePointMomentInvariants (cloud, indices, j1, j2, j3);
00326 EXPECT_NEAR (j1, 1.59244, 1e-4);
00327 EXPECT_NEAR (j2, 0.652063, 1e-4);
00328 EXPECT_NEAR (j3, 0.053917, 1e-4);
00329
00330
00331 mi.computePointMomentInvariants (cloud, indices, j1, j2, j3);
00332 EXPECT_NEAR (j1, 1.59244, 1e-4);
00333 EXPECT_NEAR (j2, 0.652063, 1e-4);
00334 EXPECT_NEAR (j3, 0.053917, 1e-4);
00335
00336
00337 PointCloud<MomentInvariants>::Ptr moments (new PointCloud<MomentInvariants> ());
00338
00339
00340 mi.setInputCloud (cloud.makeShared ());
00341 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00342 mi.setIndices (indicesptr);
00343 mi.setSearchMethod (tree);
00344 mi.setKSearch (indices.size ());
00345
00346
00347 mi.compute (*moments);
00348 EXPECT_EQ (moments->points.size (), indices.size ());
00349
00350 for (size_t i = 0; i < moments->points.size (); ++i)
00351 {
00352 EXPECT_NEAR (moments->points[i].j1, 1.59244, 1e-4);
00353 EXPECT_NEAR (moments->points[i].j2, 0.652063, 1e-4);
00354 EXPECT_NEAR (moments->points[i].j3, 0.053917, 1e-4);
00355 }
00356 }
00357
00359 TEST (PCL, BoundaryEstimation)
00360 {
00361 Eigen::Vector3f u = Eigen::Vector3f::Zero ();
00362 Eigen::Vector3f v = Eigen::Vector3f::Zero ();
00363
00364
00365 NormalEstimation<PointXYZ, Normal> n;
00366 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00367
00368 n.setInputCloud (cloud.makeShared ());
00369 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00370 n.setIndices (indicesptr);
00371 n.setSearchMethod (tree);
00372 n.setKSearch (indices.size ());
00373
00374 n.compute (*normals);
00375
00376 BoundaryEstimation<PointXYZ, Normal, Boundary> b;
00377 b.setInputNormals (normals);
00378 EXPECT_EQ (b.getInputNormals (), normals);
00379
00380
00381 for (size_t i = 0; i < normals->points.size (); ++i)
00382 {
00383 b.getCoordinateSystemOnPlane (normals->points[i], u, v);
00384 pcl::Vector3fMap n4uv = normals->points[i].getNormalVector3fMap ();
00385 EXPECT_NEAR (n4uv.dot(u), 0, 1e-4);
00386 EXPECT_NEAR (n4uv.dot(v), 0, 1e-4);
00387 EXPECT_NEAR (u.dot(v), 0, 1e-4);
00388 }
00389
00390
00391 bool pt = false;
00392 pt = b.isBoundaryPoint (cloud, 0, indices, u, v, M_PI / 2.0);
00393 EXPECT_EQ (pt, false);
00394 pt = b.isBoundaryPoint (cloud, indices.size () / 3, indices, u, v, M_PI / 2.0);
00395 EXPECT_EQ (pt, false);
00396 pt = b.isBoundaryPoint (cloud, indices.size () / 2, indices, u, v, M_PI / 2.0);
00397 EXPECT_EQ (pt, false);
00398 pt = b.isBoundaryPoint (cloud, indices.size () - 1, indices, u, v, M_PI / 2.0);
00399 EXPECT_EQ (pt, true);
00400
00401
00402 pt = false;
00403 pt = b.isBoundaryPoint (cloud, cloud.points[0], indices, u, v, M_PI / 2.0);
00404 EXPECT_EQ (pt, false);
00405 pt = b.isBoundaryPoint (cloud, cloud.points[indices.size () / 3], indices, u, v, M_PI / 2.0);
00406 EXPECT_EQ (pt, false);
00407 pt = b.isBoundaryPoint (cloud, cloud.points[indices.size () / 2], indices, u, v, M_PI / 2.0);
00408 EXPECT_EQ (pt, false);
00409 pt = b.isBoundaryPoint (cloud, cloud.points[indices.size () - 1], indices, u, v, M_PI / 2.0);
00410 EXPECT_EQ (pt, true);
00411
00412
00413 PointCloud<Boundary>::Ptr bps (new PointCloud<Boundary> ());
00414
00415
00416 b.setInputCloud (cloud.makeShared ());
00417 b.setIndices (indicesptr);
00418 b.setSearchMethod (tree);
00419 b.setKSearch (indices.size ());
00420
00421
00422 b.compute (*bps);
00423 EXPECT_EQ (bps->points.size (), indices.size ());
00424
00425 pt = bps->points[0].boundary_point;
00426 EXPECT_EQ (pt, false);
00427 pt = bps->points[indices.size () / 3].boundary_point;
00428 EXPECT_EQ (pt, false);
00429 pt = bps->points[indices.size () / 2].boundary_point;
00430 EXPECT_EQ (pt, false);
00431 pt = bps->points[indices.size () - 1].boundary_point;
00432 EXPECT_EQ (pt, true);
00433 }
00434
00436 TEST (PCL, PrincipalCurvaturesEstimation)
00437 {
00438 float pcx, pcy, pcz, pc1, pc2;
00439
00440
00441 NormalEstimation<PointXYZ, Normal> n;
00442 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00443
00444 n.setInputCloud (cloud.makeShared ());
00445 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00446 n.setIndices (indicesptr);
00447 n.setSearchMethod (tree);
00448 n.setKSearch (10);
00449
00450 n.compute (*normals);
00451
00452 PrincipalCurvaturesEstimation<PointXYZ, Normal, PrincipalCurvatures> pc;
00453 pc.setInputNormals (normals);
00454 EXPECT_EQ (pc.getInputNormals (), normals);
00455
00456
00457 pc.computePointPrincipalCurvatures (*normals, 0, indices, pcx, pcy, pcz, pc1, pc2);
00458 EXPECT_NEAR (fabs (pcx), 0.98509, 1e-4);
00459 EXPECT_NEAR (fabs (pcy), 0.10714, 1e-4);
00460 EXPECT_NEAR (fabs (pcz), 0.13462, 1e-4);
00461 EXPECT_NEAR (pc1, 95.26991, 1e-3);
00462 EXPECT_NEAR (pc2, 77.0189, 1e-3);
00463
00464 pc.computePointPrincipalCurvatures (*normals, 2, indices, pcx, pcy, pcz, pc1, pc2);
00465 EXPECT_NEAR (pcx, 0.98079, 1e-4);
00466 EXPECT_NEAR (pcy, -0.04019, 1e-4);
00467 EXPECT_NEAR (pcz, 0.19086, 1e-4);
00468 EXPECT_NEAR (pc1, 108.01375, 1e-4);
00469 EXPECT_NEAR (pc2, 77.27593, 1e-4);
00470
00471 pc.computePointPrincipalCurvatures (*normals, indices.size () - 3, indices, pcx, pcy, pcz, pc1, pc2);
00472 EXPECT_NEAR (pcx, 0.86725, 1e-4);
00473 EXPECT_NEAR (pcy, -0.37599, 1e-4);
00474 EXPECT_NEAR (pcz, 0.32635, 1e-4);
00475 EXPECT_NEAR (pc1, 102.82327, 1e-4);
00476 EXPECT_NEAR (pc2, 71.0906, 1e-4);
00477
00478 pc.computePointPrincipalCurvatures (*normals, indices.size () - 1, indices, pcx, pcy, pcz, pc1, pc2);
00479 EXPECT_NEAR (pcx, 0.86725, 1e-4);
00480 EXPECT_NEAR (pcy, -0.37599, 1e-4);
00481 EXPECT_NEAR (pcz, 0.32636, 1e-4);
00482 EXPECT_NEAR (pc1, 102.82323, 1e-4);
00483 EXPECT_NEAR (pc2, 71.09056, 1e-4);
00484
00485
00486 PointCloud<PrincipalCurvatures>::Ptr pcs (new PointCloud<PrincipalCurvatures> ());
00487
00488
00489 pc.setInputCloud (cloud.makeShared ());
00490 pc.setIndices (indicesptr);
00491 pc.setSearchMethod (tree);
00492 pc.setKSearch (indices.size ());
00493
00494
00495 pc.compute (*pcs);
00496 EXPECT_EQ (pcs->points.size (), indices.size ());
00497
00498
00499 EXPECT_NEAR (fabs (pcs->points[0].principal_curvature[0]), 0.98509, 1e-4);
00500 EXPECT_NEAR (fabs (pcs->points[0].principal_curvature[1]), 0.10713, 1e-4);
00501 EXPECT_NEAR (fabs (pcs->points[0].principal_curvature[2]), 0.13462, 1e-4);
00502 EXPECT_NEAR (fabs (pcs->points[0].pc1), 95.26995, 1e-3);
00503 EXPECT_NEAR (fabs (pcs->points[0].pc2), 77.01882, 1e-3);
00504
00505 EXPECT_NEAR (pcs->points[2].principal_curvature[0], 0.98079, 1e-4);
00506 EXPECT_NEAR (pcs->points[2].principal_curvature[1], -0.04019, 1e-4);
00507 EXPECT_NEAR (pcs->points[2].principal_curvature[2], 0.19086, 1e-4);
00508 EXPECT_NEAR (pcs->points[2].pc1, 108.0137481, 1e-4);
00509 EXPECT_NEAR (pcs->points[2].pc2, 77.2759780, 1e-4);
00510
00511 EXPECT_NEAR (pcs->points[indices.size () - 3].principal_curvature[0], 0.86725, 1e-4);
00512 EXPECT_NEAR (pcs->points[indices.size () - 3].principal_curvature[1], -0.37599, 1e-4);
00513 EXPECT_NEAR (pcs->points[indices.size () - 3].principal_curvature[2], 0.32636, 1e-4);
00514 EXPECT_NEAR (pcs->points[indices.size () - 3].pc1, 102.82320, 1e-4);
00515 EXPECT_NEAR (pcs->points[indices.size () - 3].pc2, 71.09062, 1e-4);
00516
00517 EXPECT_NEAR (pcs->points[indices.size () - 1].principal_curvature[0], 0.86725, 1e-4);
00518 EXPECT_NEAR (pcs->points[indices.size () - 1].principal_curvature[1], -0.37599, 1e-4);
00519 EXPECT_NEAR (pcs->points[indices.size () - 1].principal_curvature[2], 0.32636, 1e-4);
00520 EXPECT_NEAR (pcs->points[indices.size () - 1].pc1, 102.82326, 1e-4);
00521 EXPECT_NEAR (pcs->points[indices.size () - 1].pc2, 71.09061, 1e-4);
00522 }
00523
00525 TEST (PCL, PFHEstimation)
00526 {
00527 float f1, f2, f3, f4;
00528
00529
00530 NormalEstimation<PointXYZ, Normal> n;
00531 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00532
00533 n.setInputCloud (cloud.makeShared ());
00534 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00535 n.setIndices (indicesptr);
00536 n.setSearchMethod (tree);
00537 n.setKSearch (10);
00538
00539 n.compute (*normals);
00540
00541 PFHEstimation<PointXYZ, Normal, PFHSignature125> pfh;
00542 pfh.setInputNormals (normals);
00543 EXPECT_EQ (pfh.getInputNormals (), normals);
00544
00545
00546 pfh.computePairFeatures (cloud, *normals, 0, 12, f1, f2, f3, f4);
00547 EXPECT_NEAR (f1, -0.0725751, 1e-4);
00548 EXPECT_NEAR (f2, -0.0402214, 1e-4);
00549 EXPECT_NEAR (f3, 0.0681325, 1e-4);
00550 EXPECT_NEAR (f4, 0.006130435, 1e-4);
00551
00552
00553 int nr_subdiv = 3;
00554 Eigen::VectorXf pfh_histogram (nr_subdiv * nr_subdiv * nr_subdiv);
00555 pfh.computePointPFHSignature (cloud, *normals, indices, nr_subdiv, pfh_histogram);
00556 EXPECT_NEAR (pfh_histogram[0], 0.534875, 1e-4);
00557 EXPECT_NEAR (pfh_histogram[1], 1.48149, 1e-4);
00558 EXPECT_NEAR (pfh_histogram[2], 0.211284, 1e-4);
00559 EXPECT_NEAR (pfh_histogram[3], 0.751871, 1e-4);
00560 EXPECT_NEAR (pfh_histogram[4], 3.25473, 1e-4);
00561 EXPECT_NEAR (pfh_histogram[5], 0.190981, 1e-4);
00562 EXPECT_NEAR (pfh_histogram[6], 1.07038, 1e-4);
00563 EXPECT_NEAR (pfh_histogram[7], 2.53465, 1e-4);
00564 EXPECT_NEAR (pfh_histogram[8], 0.190346, 1e-4);
00565 EXPECT_NEAR (pfh_histogram[9], 1.78031, 1e-4);
00566 EXPECT_NEAR (pfh_histogram[10], 4.37654, 1e-4);
00567 EXPECT_NEAR (pfh_histogram[11], 0.707457, 1e-4);
00568 EXPECT_NEAR (pfh_histogram[12], 2.16224, 1e-4);
00569 EXPECT_NEAR (pfh_histogram[13], 18.23467, 1e-4);
00570 EXPECT_NEAR (pfh_histogram[14], 0.737912, 1e-4);
00571 EXPECT_NEAR (pfh_histogram[15], 3.29406, 1e-4);
00572 EXPECT_NEAR (pfh_histogram[16], 8.59094, 1e-4);
00573 EXPECT_NEAR (pfh_histogram[17], 0.831817, 1e-4);
00574 EXPECT_NEAR (pfh_histogram[18], 5.92704, 1e-4);
00575 EXPECT_NEAR (pfh_histogram[19], 3.8936, 1e-4);
00576 EXPECT_NEAR (pfh_histogram[20], 1.00313, 1e-4);
00577 EXPECT_NEAR (pfh_histogram[21], 11.1144, 1e-4);
00578 EXPECT_NEAR (pfh_histogram[22], 11.2659, 1e-4);
00579 EXPECT_NEAR (pfh_histogram[23], 1.32352, 1e-4);
00580 EXPECT_NEAR (pfh_histogram[24], 6.23105, 1e-4);
00581 EXPECT_NEAR (pfh_histogram[25], 6.21518, 1e-4);
00582 EXPECT_NEAR (pfh_histogram[26], 1.83741, 1e-4);
00583
00584
00585 PointCloud<PFHSignature125>::Ptr pfhs (new PointCloud<PFHSignature125> ());
00586
00587
00588 pfh.setInputCloud (cloud.makeShared ());
00589 pfh.setIndices (indicesptr);
00590 pfh.setSearchMethod (tree);
00591 pfh.setNrSubdivisions (3);
00592 pfh.setKSearch (indices.size ());
00593
00594
00595 pfh.compute (*pfhs);
00596 EXPECT_EQ (pfhs->points.size (), indices.size ());
00597
00598 for (size_t i = 0; i < pfhs->points.size (); ++i)
00599 {
00600 EXPECT_NEAR (pfhs->points[i].histogram[0], 0.534875, 1e-4);
00601 EXPECT_NEAR (pfhs->points[i].histogram[1], 1.48149, 1e-4);
00602 EXPECT_NEAR (pfhs->points[i].histogram[2], 0.211284, 1e-4);
00603 EXPECT_NEAR (pfhs->points[i].histogram[3], 0.751871, 1e-4);
00604 EXPECT_NEAR (pfhs->points[i].histogram[4], 3.25473, 1e-4);
00605 EXPECT_NEAR (pfhs->points[i].histogram[5], 0.190981, 1e-4);
00606 EXPECT_NEAR (pfhs->points[i].histogram[6], 1.07038, 1e-4);
00607 EXPECT_NEAR (pfhs->points[i].histogram[7], 2.53465, 1e-4);
00608 EXPECT_NEAR (pfhs->points[i].histogram[8], 0.190346, 1e-4);
00609 EXPECT_NEAR (pfhs->points[i].histogram[9], 1.78031, 1e-4);
00610 EXPECT_NEAR (pfhs->points[i].histogram[10], 4.37654, 1e-4);
00611 EXPECT_NEAR (pfhs->points[i].histogram[11], 0.707457, 1e-4);
00612 EXPECT_NEAR (pfhs->points[i].histogram[12], 2.16224, 1e-4);
00613 EXPECT_NEAR (pfhs->points[i].histogram[13], 18.23467, 1e-4);
00614 EXPECT_NEAR (pfhs->points[i].histogram[14], 0.737912, 1e-4);
00615 EXPECT_NEAR (pfhs->points[i].histogram[15], 3.29406, 1e-4);
00616 EXPECT_NEAR (pfhs->points[i].histogram[16], 8.59094, 1e-4);
00617 EXPECT_NEAR (pfhs->points[i].histogram[17], 0.831817, 1e-4);
00618 EXPECT_NEAR (pfhs->points[i].histogram[18], 5.92704, 1e-4);
00619 EXPECT_NEAR (pfhs->points[i].histogram[19], 3.8936, 1e-4);
00620 EXPECT_NEAR (pfhs->points[i].histogram[20], 1.00313, 1e-4);
00621 EXPECT_NEAR (pfhs->points[i].histogram[21], 11.1144, 1e-4);
00622 EXPECT_NEAR (pfhs->points[i].histogram[22], 11.2659, 1e-4);
00623 EXPECT_NEAR (pfhs->points[i].histogram[23], 1.32352, 1e-4);
00624 EXPECT_NEAR (pfhs->points[i].histogram[24], 6.23105, 1e-4);
00625 EXPECT_NEAR (pfhs->points[i].histogram[25], 6.21518, 1e-4);
00626 EXPECT_NEAR (pfhs->points[i].histogram[26], 1.83741, 1e-4);
00627 }
00628 }
00629
00631 TEST (PCL, FPFHEstimation)
00632 {
00633
00634 NormalEstimation<PointXYZ, Normal> n;
00635 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00636
00637 n.setInputCloud (cloud.makeShared ());
00638 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00639 n.setIndices (indicesptr);
00640 n.setSearchMethod (tree);
00641 n.setKSearch (10);
00642
00643 n.compute (*normals);
00644
00645 FPFHEstimation<PointXYZ, Normal, FPFHSignature33> fpfh;
00646 fpfh.setInputNormals (normals);
00647 EXPECT_EQ (fpfh.getInputNormals (), normals);
00648
00649
00650 int nr_subdiv = 11;
00651 Eigen::MatrixXf hist_f1 (indices.size (), nr_subdiv), hist_f2 (indices.size (), nr_subdiv), hist_f3 (indices.size (), nr_subdiv);
00652 hist_f1.setZero (); hist_f2.setZero (); hist_f3.setZero ();
00653 for (size_t i = 0; i < indices.size (); ++i)
00654 fpfh.computePointSPFHSignature (cloud, *normals, i, indices, hist_f1, hist_f2, hist_f3);
00655
00656 EXPECT_NEAR (hist_f1 (0, 0), 2.77778, 1e-4);
00657 EXPECT_NEAR (hist_f1 (0, 1), 1.010101, 1e-4);
00658 EXPECT_NEAR (hist_f1 (0, 2), 4.0404, 1e-4);
00659 EXPECT_NEAR (hist_f1 (0, 3), 19.1919, 1e-4);
00660 EXPECT_NEAR (hist_f1 (0, 4), 40.1515, 1e-4);
00661 EXPECT_NEAR (hist_f1 (0, 5), 20.4545, 1e-4);
00662 EXPECT_NEAR (hist_f1 (0, 6), 8.58586, 1e-4);
00663 EXPECT_NEAR (hist_f1 (0, 7), 1.0101, 1e-4);
00664 EXPECT_NEAR (hist_f1 (0, 8), 1.26263, 1e-4);
00665 EXPECT_NEAR (hist_f1 (0, 9), 0, 1e-4);
00666 EXPECT_NEAR (hist_f1 (0, 10), 1.51515, 1e-4);
00667
00668 EXPECT_NEAR (hist_f2 (0, 0), 0, 1e-4);
00669 EXPECT_NEAR (hist_f2 (0, 1), 0.50505, 1e-4);
00670 EXPECT_NEAR (hist_f2 (0, 2), 2.27273, 1e-4);
00671 EXPECT_NEAR (hist_f2 (0, 3), 10.6061, 1e-4);
00672 EXPECT_NEAR (hist_f2 (0, 4), 24.495, 1e-4);
00673 EXPECT_NEAR (hist_f2 (0, 5), 20.7071, 1e-4);
00674 EXPECT_NEAR (hist_f2 (0, 6), 17.1717, 1e-4);
00675 EXPECT_NEAR (hist_f2 (0, 7), 11.8687, 1e-4);
00676 EXPECT_NEAR (hist_f2 (0, 8), 8.08081, 1e-4);
00677 EXPECT_NEAR (hist_f2 (0, 9), 1.76768, 1e-4);
00678 EXPECT_NEAR (hist_f2 (0, 10), 2.52525, 1e-4);
00679
00680 EXPECT_NEAR (hist_f3 (0, 0), 0, 1e-4);
00681 EXPECT_NEAR (hist_f3 (0, 1), 0, 1e-4);
00682 EXPECT_NEAR (hist_f3 (0, 2), 0, 1e-4);
00683 EXPECT_NEAR (hist_f3 (0, 3), 0, 1e-4);
00684 EXPECT_NEAR (hist_f3 (0, 4), 0.252525, 1e-4);
00685 EXPECT_NEAR (hist_f3 (0, 5), 14.1414, 1e-4);
00686 EXPECT_NEAR (hist_f3 (0, 6), 26.0101, 1e-4);
00687 EXPECT_NEAR (hist_f3 (0, 7), 42.6768, 1e-4);
00688 EXPECT_NEAR (hist_f3 (0, 8), 13.8889, 1e-4);
00689 EXPECT_NEAR (hist_f3 (0, 9), 3.0303, 1e-4);
00690 EXPECT_NEAR (hist_f3 (0, 10), 0, 1e-4);
00691
00692
00693 Eigen::VectorXf fpfh_histogram (nr_subdiv + nr_subdiv + nr_subdiv);
00694 fpfh_histogram.setZero ();
00695 vector<float> dists (indices.size ());
00696 for (size_t i = 0; i < dists.size (); ++i) dists[i] = i;
00697 fpfh.weightPointSPFHSignature (hist_f1, hist_f2, hist_f3, indices, dists, fpfh_histogram);
00698
00699 EXPECT_NEAR (fpfh_histogram[0], 2.25806, 1e-4);
00700 EXPECT_NEAR (fpfh_histogram[1], 4.20886, 1e-4);
00701 EXPECT_NEAR (fpfh_histogram[2], 8.72928, 1e-4);
00702 EXPECT_NEAR (fpfh_histogram[3], 23.2465, 1e-4);
00703 EXPECT_NEAR (fpfh_histogram[4], 29.5395, 1e-4);
00704 EXPECT_NEAR (fpfh_histogram[5], 17.46889, 1e-4);
00705 EXPECT_NEAR (fpfh_histogram[6], 8.41421, 1e-4);
00706 EXPECT_NEAR (fpfh_histogram[7], 2.30139, 1e-4);
00707 EXPECT_NEAR (fpfh_histogram[8], 1.41585, 1e-4);
00708 EXPECT_NEAR (fpfh_histogram[9], 1.00892, 1e-4);
00709 EXPECT_NEAR (fpfh_histogram[10], 1.40861, 1e-4);
00710 EXPECT_NEAR (fpfh_histogram[11], 1.21368, 1e-4);
00711 EXPECT_NEAR (fpfh_histogram[12], 3.28168, 1e-4);
00712 EXPECT_NEAR (fpfh_histogram[13], 7.06985, 1e-4);
00713 EXPECT_NEAR (fpfh_histogram[14], 11.0509, 1e-4);
00714 EXPECT_NEAR (fpfh_histogram[15], 18.9273, 1e-4);
00715 EXPECT_NEAR (fpfh_histogram[16], 17.6086, 1e-4);
00716 EXPECT_NEAR (fpfh_histogram[17], 13.3466, 1e-4);
00717 EXPECT_NEAR (fpfh_histogram[18], 10.4234, 1e-4);
00718 EXPECT_NEAR (fpfh_histogram[19], 7.71453, 1e-4);
00719 EXPECT_NEAR (fpfh_histogram[20], 4.90723, 1e-4);
00720 EXPECT_NEAR (fpfh_histogram[21], 4.45617, 1e-4);
00721 EXPECT_NEAR (fpfh_histogram[22], 0.364497, 1e-4);
00722 EXPECT_NEAR (fpfh_histogram[23], 0.653451, 1e-4);
00723 EXPECT_NEAR (fpfh_histogram[24], 1.7847, 1e-4);
00724 EXPECT_NEAR (fpfh_histogram[25], 3.74132, 1e-4);
00725 EXPECT_NEAR (fpfh_histogram[26], 5.708313, 1e-4);
00726 EXPECT_NEAR (fpfh_histogram[27], 9.507835, 1e-4);
00727 EXPECT_NEAR (fpfh_histogram[28], 17.638830, 1e-4);
00728 EXPECT_NEAR (fpfh_histogram[29], 22.766557, 1e-4);
00729 EXPECT_NEAR (fpfh_histogram[30], 19.5883, 1e-4);
00730 EXPECT_NEAR (fpfh_histogram[31], 13.063, 1e-4);
00731 EXPECT_NEAR (fpfh_histogram[32], 5.18325, 1e-4);
00732
00733
00734 PointCloud<FPFHSignature33>::Ptr fpfhs (new PointCloud<FPFHSignature33> ());
00735
00736
00737 fpfh.setInputCloud (cloud.makeShared ());
00738 fpfh.setNrSubdivisions (11, 11, 11);
00739 fpfh.setIndices (indicesptr);
00740 fpfh.setSearchMethod (tree);
00741 fpfh.setKSearch (indices.size ());
00742
00743
00744 fpfh.compute (*fpfhs);
00745 EXPECT_EQ (fpfhs->points.size (), indices.size ());
00746
00747 EXPECT_NEAR (fpfhs->points[0].histogram[0], 2.11328, 1e-4);
00748 EXPECT_NEAR (fpfhs->points[0].histogram[1], 3.13866, 1e-4);
00749 EXPECT_NEAR (fpfhs->points[0].histogram[2], 7.07176, 1e-4);
00750 EXPECT_NEAR (fpfhs->points[0].histogram[3], 23.0986, 1e-4);
00751 EXPECT_NEAR (fpfhs->points[0].histogram[4], 32.988, 1e-4);
00752 EXPECT_NEAR (fpfhs->points[0].histogram[5], 18.74372, 1e-4);
00753 EXPECT_NEAR (fpfhs->points[0].histogram[6], 8.118416, 1e-4);
00754 EXPECT_NEAR (fpfhs->points[0].histogram[7], 1.9162, 1e-4);
00755 EXPECT_NEAR (fpfhs->points[0].histogram[8], 1.19554, 1e-4);
00756 EXPECT_NEAR (fpfhs->points[0].histogram[9], 0.577558, 1e-4);
00757 EXPECT_NEAR (fpfhs->points[0].histogram[10], 1.03827, 1e-4);
00758 EXPECT_NEAR (fpfhs->points[0].histogram[11], 0.631236, 1e-4);
00759 EXPECT_NEAR (fpfhs->points[0].histogram[12], 2.13356, 1e-4);
00760 EXPECT_NEAR (fpfhs->points[0].histogram[13], 5.67842, 1e-4);
00761 EXPECT_NEAR (fpfhs->points[0].histogram[14], 10.8759, 1e-4);
00762 EXPECT_NEAR (fpfhs->points[0].histogram[15], 20.2439, 1e-4);
00763 EXPECT_NEAR (fpfhs->points[0].histogram[16], 19.674, 1e-4);
00764 EXPECT_NEAR (fpfhs->points[0].histogram[17], 15.3302, 1e-4);
00765 EXPECT_NEAR (fpfhs->points[0].histogram[18], 10.773, 1e-4);
00766 EXPECT_NEAR (fpfhs->points[0].histogram[19], 6.80136, 1e-4);
00767 EXPECT_NEAR (fpfhs->points[0].histogram[20], 4.03065, 1e-4);
00768 EXPECT_NEAR (fpfhs->points[0].histogram[21], 3.82776, 1e-4);
00769 EXPECT_NEAR (fpfhs->points[0].histogram[22], 0.208905, 1e-4);
00770 EXPECT_NEAR (fpfhs->points[0].histogram[23], 0.392544, 1e-4);
00771 EXPECT_NEAR (fpfhs->points[0].histogram[24], 1.27637, 1e-4);
00772 EXPECT_NEAR (fpfhs->points[0].histogram[25], 2.61976, 1e-4);
00773 EXPECT_NEAR (fpfhs->points[0].histogram[26], 5.12960, 1e-4);
00774 EXPECT_NEAR (fpfhs->points[0].histogram[27], 12.35568, 1e-4);
00775 EXPECT_NEAR (fpfhs->points[0].histogram[28], 21.89877, 1e-4);
00776 EXPECT_NEAR (fpfhs->points[0].histogram[29], 25.55738, 1e-4);
00777 EXPECT_NEAR (fpfhs->points[0].histogram[30], 19.1552, 1e-4);
00778 EXPECT_NEAR (fpfhs->points[0].histogram[31], 9.22763, 1e-4);
00779 EXPECT_NEAR (fpfhs->points[0].histogram[32], 2.17815, 1e-4);
00780 }
00781
00783 TEST (PCL, FPFHEstimationOpenMP)
00784 {
00785
00786 NormalEstimation<PointXYZ, Normal> n;
00787 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00788
00789 n.setInputCloud (cloud.makeShared ());
00790 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00791 n.setIndices (indicesptr);
00792 n.setSearchMethod (tree);
00793 n.setKSearch (10);
00794
00795 n.compute (*normals);
00796 FPFHEstimationOMP<PointXYZ, Normal, FPFHSignature33> fpfh (4);
00797 fpfh.setInputNormals (normals);
00798
00799
00800 PointCloud<FPFHSignature33>::Ptr fpfhs (new PointCloud<FPFHSignature33> ());
00801
00802
00803 fpfh.setInputCloud (cloud.makeShared ());
00804 fpfh.setNrSubdivisions (11, 11, 11);
00805 fpfh.setIndices (indicesptr);
00806 fpfh.setSearchMethod (tree);
00807 fpfh.setKSearch (indices.size ());
00808
00809
00810 fpfh.compute (*fpfhs);
00811 EXPECT_EQ (fpfhs->points.size (), indices.size ());
00812
00813 EXPECT_NEAR (fpfhs->points[0].histogram[0], 2.11328, 1e-4);
00814 EXPECT_NEAR (fpfhs->points[0].histogram[1], 3.13866, 1e-4);
00815 EXPECT_NEAR (fpfhs->points[0].histogram[2], 7.07176, 1e-4);
00816 EXPECT_NEAR (fpfhs->points[0].histogram[3], 23.0986, 1e-4);
00817 EXPECT_NEAR (fpfhs->points[0].histogram[4], 32.988, 1e-4);
00818 EXPECT_NEAR (fpfhs->points[0].histogram[5], 18.74372, 1e-4);
00819 EXPECT_NEAR (fpfhs->points[0].histogram[6], 8.118416, 1e-4);
00820 EXPECT_NEAR (fpfhs->points[0].histogram[7], 1.9162, 1e-4);
00821 EXPECT_NEAR (fpfhs->points[0].histogram[8], 1.19554, 1e-4);
00822 EXPECT_NEAR (fpfhs->points[0].histogram[9], 0.577558, 1e-4);
00823 EXPECT_NEAR (fpfhs->points[0].histogram[10], 1.03827, 1e-4);
00824 EXPECT_NEAR (fpfhs->points[0].histogram[11], 0.631236, 1e-4);
00825 EXPECT_NEAR (fpfhs->points[0].histogram[12], 2.13356, 1e-4);
00826 EXPECT_NEAR (fpfhs->points[0].histogram[13], 5.67842, 1e-4);
00827 EXPECT_NEAR (fpfhs->points[0].histogram[14], 10.8759, 1e-4);
00828 EXPECT_NEAR (fpfhs->points[0].histogram[15], 20.2439, 1e-4);
00829 EXPECT_NEAR (fpfhs->points[0].histogram[16], 19.674, 1e-4);
00830 EXPECT_NEAR (fpfhs->points[0].histogram[17], 15.3302, 1e-4);
00831 EXPECT_NEAR (fpfhs->points[0].histogram[18], 10.773, 1e-4);
00832 EXPECT_NEAR (fpfhs->points[0].histogram[19], 6.80136, 1e-4);
00833 EXPECT_NEAR (fpfhs->points[0].histogram[20], 4.03065, 1e-4);
00834 EXPECT_NEAR (fpfhs->points[0].histogram[21], 3.82776, 1e-4);
00835 EXPECT_NEAR (fpfhs->points[0].histogram[22], 0.208905, 1e-4);
00836 EXPECT_NEAR (fpfhs->points[0].histogram[23], 0.392544, 1e-4);
00837 EXPECT_NEAR (fpfhs->points[0].histogram[24], 1.27637, 1e-4);
00838 EXPECT_NEAR (fpfhs->points[0].histogram[25], 2.61976, 1e-4);
00839 EXPECT_NEAR (fpfhs->points[0].histogram[26], 5.12960, 1e-4);
00840 EXPECT_NEAR (fpfhs->points[0].histogram[27], 12.35568, 1e-4);
00841 EXPECT_NEAR (fpfhs->points[0].histogram[28], 21.89877, 1e-4);
00842 EXPECT_NEAR (fpfhs->points[0].histogram[29], 25.55738, 1e-4);
00843 EXPECT_NEAR (fpfhs->points[0].histogram[30], 19.1552, 1e-4);
00844 EXPECT_NEAR (fpfhs->points[0].histogram[31], 9.22763, 1e-4);
00845 EXPECT_NEAR (fpfhs->points[0].histogram[32], 2.17815, 1e-4);
00846 }
00847
00849 TEST (PCL, VFHEstimation)
00850 {
00851
00852 NormalEstimation<PointXYZ, Normal> n;
00853 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00854
00855 n.setInputCloud (cloud.makeShared ());
00856 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00857 n.setIndices (indicesptr);
00858 n.setSearchMethod (tree);
00859 n.setKSearch (10);
00860
00861 n.compute (*normals);
00862 VFHEstimation<PointXYZ, Normal, VFHSignature308> vfh;
00863 vfh.setInputNormals (normals);
00864
00865
00866
00867
00868
00869
00870 PointCloud<VFHSignature308>::Ptr vfhs (new PointCloud<VFHSignature308> ());
00871
00872
00873 vfh.setInputCloud (cloud.makeShared ());
00874 vfh.setNrSubdivisions (45, 45, 45, 45);
00875 vfh.setNrViewpointSubdivisions (128);
00876 vfh.setIndices (indicesptr);
00877 vfh.setSearchMethod (tree);
00878
00879
00880 vfh.compute (*vfhs);
00881 EXPECT_EQ ((int)vfhs->points.size (), 1);
00882
00883
00884
00885 }
00886
00888 TEST (PCL, RSDEstimation)
00889 {
00890
00891 NormalEstimation<PointXYZ, Normal> n;
00892 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00893
00894 n.setInputCloud (cloud.makeShared ());
00895 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00896 n.setIndices (indicesptr);
00897 n.setSearchMethod (tree);
00898 n.setKSearch (10);
00899
00900 n.compute (*normals);
00901 RSDEstimation<PointXYZ, Normal, PrincipalRadiiRSD> rsd;
00902 rsd.setInputNormals (normals);
00903
00904
00905 PointCloud<PrincipalRadiiRSD>::Ptr rsds (new PointCloud<PrincipalRadiiRSD> ());
00906
00907
00908 rsd.setInputCloud (cloud.makeShared ());
00909 rsd.setIndices (indicesptr);
00910 rsd.setSearchMethod (tree);
00911 rsd.setRadiusSearch (0.01);
00912
00913
00914 rsd.compute (*rsds);
00915 EXPECT_NEAR (rsds->points[0].r_min, 0.0843, 0.005);
00916 EXPECT_NEAR (rsds->points[0].r_max, 0.1389, 0.005);
00917 }
00918
00920 TEST (PCL, IntensityGradientEstimation)
00921 {
00922
00923 PointCloud<PointXYZI> cloud_xyzi;
00924 cloud_xyzi.height = 1;
00925 cloud_xyzi.is_dense = true;
00926 for (float x = -5.0; x <= 5.0; x += 0.1)
00927 {
00928 for (float y = -5.0; y <= 5.0; y += 0.1)
00929 {
00930 PointXYZI p;
00931 p.x = x;
00932 p.y = y;
00933 p.z = 0.1*pow (x,2) + 0.5*y + 1.0;
00934 p.intensity = 0.1*pow (x,3) + 0.2*pow (y,2) + 1.0*p.z + 2.0;
00935
00936 cloud_xyzi.points.push_back (p);
00937 }
00938 }
00939 cloud_xyzi.width = cloud_xyzi.points.size ();
00940 PointCloud<PointXYZI>::ConstPtr cloud_ptr = cloud_xyzi.makeShared ();
00941
00942
00943 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00944 NormalEstimation<PointXYZI, Normal> norm_est;
00945 norm_est.setInputCloud (cloud_ptr);
00946 norm_est.setSearchMethod (boost::make_shared<KdTreeFLANN<PointXYZI> > (false));
00947 norm_est.setRadiusSearch (0.25);
00948 norm_est.compute (*normals);
00949
00950
00951 PointCloud<IntensityGradient> gradient;
00952 IntensityGradientEstimation<PointXYZI, Normal, IntensityGradient> grad_est;
00953 grad_est.setInputCloud (cloud_ptr);
00954 grad_est.setInputNormals (normals);
00955 grad_est.setSearchMethod (boost::make_shared<KdTreeFLANN<PointXYZI> > (false));
00956 grad_est.setRadiusSearch (0.25);
00957 grad_est.compute (gradient);
00958
00959
00960 for (size_t i = 0; i < cloud_ptr->points.size (); ++i)
00961 {
00962 const PointXYZI &p = cloud_ptr->points[i];
00963
00964
00965 const float * g_est = gradient.points[i].gradient;
00966
00967
00968 float nx = -0.2*p.x;
00969 float ny = -0.5;
00970 float nz = 1.0;
00971 float magnitude = sqrt(nx*nx + ny*ny + nz*nz);
00972 nx /= magnitude;
00973 ny /= magnitude;
00974 nz /= magnitude;
00975
00976
00977 float tmpx = (0.3 * pow (p.x,2));
00978 float tmpy = (0.4 * p.y);
00979 float tmpz = (1.0);
00980
00981 float gx = (1-nx*nx)*tmpx + (-nx*ny)*tmpy + (-nx*nz)*tmpz;
00982 float gy = (-ny*nx)*tmpx + (1-ny*ny)*tmpy + (-ny*nz)*tmpz;
00983 float gz = (-nz*nx)*tmpx + (-nz*ny)*tmpy + (1-nz*nz)*tmpz;
00984
00985
00986 const float tolerance = 0.1;
00987 EXPECT_NEAR (g_est[0], gx, tolerance);
00988 EXPECT_NEAR (g_est[1], gy, tolerance);
00989 EXPECT_NEAR (g_est[2], gz, tolerance);
00990 }
00991 }
00992
00994 TEST (PCL, IntensitySpinEstimation)
00995 {
00996
00997 PointCloud<PointXYZI> cloud_xyzi;
00998 cloud_xyzi.height = 1;
00999 cloud_xyzi.is_dense = true;
01000
01001 for (float x = -10.0; x <= 10.0; x += 1.0)
01002 {
01003 for (float y = -10.0; y <= 10.0; y += 1.0)
01004 {
01005 PointXYZI p;
01006 p.x = x;
01007 p.y = y;
01008 p.z = sqrt(400 - x*x - y*y);
01009 p.intensity =
01010 exp (-(pow (x-3, 2) + pow (y+2, 2)) / (2*25.0)) +
01011 exp (-(pow (x+5, 2) + pow (y-5, 2)) / (2*4.0));
01012
01013 cloud_xyzi.points.push_back (p);
01014 }
01015 }
01016 cloud_xyzi.width = cloud_xyzi.points.size ();
01017
01018
01019 typedef Histogram<20> IntensitySpin;
01020 IntensitySpinEstimation<PointXYZI, IntensitySpin> ispin_est;
01021 ispin_est.setSearchMethod (boost::make_shared<KdTreeFLANN<PointXYZI> > (false));
01022 ispin_est.setRadiusSearch (10.0);
01023 ispin_est.setNrDistanceBins (4);
01024 ispin_est.setNrIntensityBins (5);
01025
01026 ispin_est.setInputCloud (cloud_xyzi.makeShared ());
01027 PointCloud<IntensitySpin> ispin_output;
01028 ispin_est.compute (ispin_output);
01029
01030
01031 const IntensitySpin &ispin = ispin_output.points[220];
01032 const float correct_ispin_feature_values[20] =
01033 {
01034 2.4387, 9.4737, 21.3232, 28.3025, 22.5639,
01035 13.2426, 35.7026, 60.0755, 66.9240, 50.4225,
01036 42.7086, 83.5818, 105.4513, 97.8454, 67.3801,
01037 75.7127, 119.4726, 120.9649, 93.4829, 55.4045
01038 };
01039 for (int i = 0; i < 20; ++i)
01040 {
01041 EXPECT_NEAR (ispin.histogram[i], correct_ispin_feature_values[i], 1e-4);
01042 }
01043 }
01044
01046 TEST (PCL, RIFTEstimation)
01047 {
01048
01049 PointCloud<PointXYZI> cloud_xyzi;
01050 cloud_xyzi.height = 1;
01051 cloud_xyzi.is_dense = true;
01052 for (float x = -10.0; x <= 10.0; x += 1.0)
01053 {
01054 for (float y = -10.0; y <= 10.0; y += 1.0)
01055 {
01056 PointXYZI p;
01057 p.x = x;
01058 p.y = y;
01059 p.z = sqrt(400 - x*x - y*y);
01060 p.intensity =
01061 exp ((-pow (x-3, 2) + pow (y+2, 2)) / (2*25.0)) +
01062 exp ((-pow (x+5, 2) + pow (y-5, 2)) / (2*4.0));
01063
01064 cloud_xyzi.points.push_back (p);
01065 }
01066 }
01067 cloud_xyzi.width = cloud_xyzi.points.size ();
01068
01069
01070 PointCloud<IntensityGradient> gradient;
01071 gradient.height = 1;
01072 gradient.width = cloud_xyzi.points.size ();
01073 gradient.is_dense = true;
01074 gradient.points.resize (gradient.width);
01075 for (size_t i = 0; i < cloud_xyzi.points.size (); ++i)
01076 {
01077 const PointXYZI &p = cloud_xyzi.points[i];
01078
01079
01080 float nx = p.x;
01081 float ny = p.y;
01082 float nz = p.z;
01083 float magnitude = sqrt(nx*nx + ny*ny + nz*nz);
01084 nx /= magnitude;
01085 ny /= magnitude;
01086 nz /= magnitude;
01087
01088
01089 float tmpx = -(p.x + 5)/4.0 / exp ((pow (p.x + 5, 2) + pow (p.y - 5, 2))/8.0) -
01090 (p.x - 3)/25.0 / exp ((pow (p.x - 3, 2) + pow (p.y + 2, 2))/50.0);
01091 float tmpy = -(p.y - 5)/4.0 / exp ((pow (p.x + 5, 2) + pow (p.y - 5, 2))/8.0) -
01092 (p.y + 2)/25.0 / exp ((pow (p.x - 3, 2) + pow (p.y + 2, 2))/50.0);
01093 float tmpz = 0;
01094
01095 float gx = (1-nx*nx)*tmpx + (-nx*ny)*tmpy + (-nx*nz)*tmpz;
01096 float gy = (-ny*nx)*tmpx + (1-ny*ny)*tmpy + (-ny*nz)*tmpz;
01097 float gz = (-nz*nx)*tmpx + (-nz*ny)*tmpy + (1-nz*nz)*tmpz;
01098
01099 gradient.points[i].gradient[0] = gx;
01100 gradient.points[i].gradient[1] = gy;
01101 gradient.points[i].gradient[2] = gz;
01102 }
01103
01104
01105 typedef Histogram<32> RIFTDescriptor;
01106 RIFTEstimation<PointXYZI, IntensityGradient, RIFTDescriptor> rift_est;
01107 rift_est.setSearchMethod (boost::make_shared<KdTreeFLANN<PointXYZI> > (false));
01108 rift_est.setRadiusSearch (10.0);
01109 rift_est.setNrDistanceBins (4);
01110 rift_est.setNrGradientBins (8);
01111
01112 rift_est.setInputCloud (cloud_xyzi.makeShared ());
01113 rift_est.setInputGradient (gradient.makeShared ());
01114 PointCloud<RIFTDescriptor> rift_output;
01115 rift_est.compute (rift_output);
01116
01117
01118 const RIFTDescriptor &rift = rift_output.points[220];
01119 const float correct_rift_feature_values[32] =
01120 {
01121 0.0187, 0.0349, 0.0647, 0.0881,
01122 0.0042, 0.0131, 0.0346, 0.0030,
01123 0.0076, 0.0218, 0.0463, 0.0030,
01124 0.0087, 0.0288, 0.0920, 0.0472,
01125 0.0076, 0.0420, 0.0726, 0.0669,
01126 0.0090, 0.0901, 0.1274, 0.2185,
01127 0.0147, 0.1222, 0.3568, 0.4348,
01128 0.0149, 0.0806, 0.2787, 0.6864
01129 };
01130 for (int i = 0; i < 32; ++i)
01131 {
01132 EXPECT_NEAR (rift.histogram[i], correct_rift_feature_values[i], 1e-4);
01133 }
01134 }
01135
01136
01137 int
01138 main (int argc, char** argv)
01139 {
01140 sensor_msgs::PointCloud2 cloud_blob;
01141 loadPCDFile ("./test/bun0.pcd", cloud_blob);
01142 fromROSMsg (cloud_blob, cloud);
01143
01144 indices.resize (cloud.points.size ());
01145 for (size_t i = 0; i < indices.size (); ++i) { indices[i] = i; }
01146
01147 tree.reset (new KdTreeFLANN<PointXYZ> (false));
01148 tree->setInputCloud (cloud.makeShared ());
01149
01150 testing::InitGoogleTest (&argc, argv);
01151 return (RUN_ALL_TESTS ());
01152 }
01153