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 #include <pcl/io/pcd_io.h>
00041 #include <pcl/kdtree/kdtree_flann.h>
00042 #include <pcl/sample_consensus/sac.h>
00043 #include <pcl/sample_consensus/lmeds.h>
00044 #include <pcl/sample_consensus/ransac.h>
00045 #include <pcl/sample_consensus/rransac.h>
00046 #include <pcl/sample_consensus/msac.h>
00047 #include <pcl/sample_consensus/rmsac.h>
00048 #include <pcl/sample_consensus/mlesac.h>
00049 #include <pcl/sample_consensus/sac_model.h>
00050 #include <pcl/sample_consensus/sac_model_plane.h>
00051 #include <pcl/sample_consensus/sac_model_sphere.h>
00052 #include <pcl/sample_consensus/sac_model_cylinder.h>
00053 #include <pcl/sample_consensus/sac_model_circle.h>
00054 #include <pcl/sample_consensus/sac_model_line.h>
00055 #include <pcl/sample_consensus/sac_model_normal_plane.h>
00056 #include <pcl/sample_consensus/sac_model_parallel_plane.h>
00057
00058 using namespace pcl;
00059 using namespace pcl::io;
00060 using namespace std;
00061
00062 typedef SampleConsensusModel<PointXYZ>::Ptr SampleConsensusModelPtr;
00063 typedef SampleConsensusModelPlane<PointXYZ>::Ptr SampleConsensusModelPlanePtr;
00064 typedef SampleConsensusModelSphere<PointXYZ>::Ptr SampleConsensusModelSpherePtr;
00065 typedef SampleConsensusModelCylinder<PointXYZ, Normal>::Ptr SampleConsensusModelCylinderPtr;
00066 typedef SampleConsensusModelCircle2D<PointXYZ>::Ptr SampleConsensusModelCircle2DPtr;
00067 typedef SampleConsensusModelLine<PointXYZ>::Ptr SampleConsensusModelLinePtr;
00068 typedef SampleConsensusModelNormalPlane<PointXYZ, Normal>::Ptr SampleConsensusModelNormalPlanePtr;
00069 typedef SampleConsensusModelParallelPlane<PointXYZ>::Ptr SampleConsensusModelParallelPlanePtr;
00070
00071 PointCloud<PointXYZ>::Ptr cloud_ (new PointCloud<PointXYZ> ());
00072 PointCloud<Normal>::Ptr normals_ (new PointCloud<Normal> ());
00073 vector<int> indices_;
00074
00076 TEST (SampleConsensusModelPlane, Base)
00077 {
00078
00079 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00080
00081
00082 PointCloud<PointXYZ>::ConstPtr cloud = model->getInputCloud ();
00083 ASSERT_EQ (cloud->points.size (), cloud_->points.size ());
00084
00085 model->setInputCloud (cloud);
00086 cloud = model->getInputCloud ();
00087 ASSERT_EQ (cloud->points.size (), cloud_->points.size ());
00088
00089 boost::shared_ptr<vector<int> > indices = model->getIndices ();
00090 ASSERT_EQ (indices->size (), indices_.size ());
00091 model->setIndices (indices_);
00092 indices = model->getIndices ();
00093 ASSERT_EQ (indices->size (), indices_.size ());
00094 model->setIndices (indices);
00095 indices = model->getIndices ();
00096 ASSERT_EQ (indices->size (), indices_.size ());
00097 }
00098
00100 TEST (RANSAC, Base)
00101 {
00102
00103 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00104
00105
00106 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00107
00108
00109 ASSERT_EQ (sac.getDistanceThreshold (), 0.03);
00110 sac.setDistanceThreshold (0.03);
00111 ASSERT_EQ (sac.getDistanceThreshold (), 0.03);
00112
00113 sac.setProbability (0.99);
00114 ASSERT_EQ (sac.getProbability (), 0.99);
00115
00116 sac.setMaxIterations (10000);
00117 ASSERT_EQ (sac.getMaxIterations (), 10000);
00118 }
00119
00121 TEST (RANSAC, SampleConsensusModelPlane)
00122 {
00123 srand (0);
00124
00125 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00126
00127
00128 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00129
00130
00131 bool result = sac.computeModel ();
00132 ASSERT_EQ (result, true);
00133
00134 std::vector<int> sample;
00135 sac.getModel (sample);
00136 EXPECT_EQ ((int)sample.size (), 3);
00137 EXPECT_EQ (sample[0], 1818);
00138 EXPECT_EQ (sample[1], 1567);
00139 EXPECT_EQ (sample[2], 2064);
00140
00141 std::vector<int> inliers;
00142 sac.getInliers (inliers);
00143 EXPECT_EQ ((int)inliers.size (), 2525);
00144
00145 Eigen::VectorXf coeff;
00146 sac.getModelCoefficients (coeff);
00147 EXPECT_EQ ((int)coeff.size (), 4);
00148 EXPECT_NEAR (coeff[0], 0.5590537786, 1e-4);
00149 EXPECT_NEAR (coeff[1], 0.3575230539, 1e-4);
00150 EXPECT_NEAR (coeff[2], 0.7480883598, 1e-4);
00151 EXPECT_NEAR (coeff[3], -0.622878551, 1e-4);
00152
00153 Eigen::VectorXf coeff_refined;
00154 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00155 EXPECT_EQ ((int)coeff_refined.size (), 4);
00156 EXPECT_NEAR (coeff_refined[0], 0.5554245114, 1e-4);
00157 EXPECT_NEAR (coeff_refined[1], 0.3644647598, 1e-4);
00158 EXPECT_NEAR (coeff_refined[2], 0.747441709, 1e-4);
00159 EXPECT_NEAR (coeff_refined[3], -0.619598031, 1e-4);
00160
00161
00162 PointCloud<PointXYZ> proj_points;
00163 model->projectPoints (inliers, coeff_refined, proj_points);
00164 EXPECT_NEAR (proj_points.points[20].x, 1.12661, 1e-4);
00165 EXPECT_NEAR (proj_points.points[20].y, 0.0152829, 1e-4);
00166 EXPECT_NEAR (proj_points.points[20].z, -0.0156815, 1e-4);
00167
00168 EXPECT_NEAR (proj_points.points[30].x, 1.18438, 1e-4);
00169 EXPECT_NEAR (proj_points.points[30].y, -0.0635465, 1e-4);
00170 EXPECT_NEAR (proj_points.points[30].z, -0.0201715, 1e-4);
00171
00172 EXPECT_NEAR (proj_points.points[50].x, 1.07499, 1e-4);
00173 EXPECT_NEAR (proj_points.points[50].y, -0.0586441, 1e-4);
00174 EXPECT_NEAR (proj_points.points[50].z, 0.0587273, 1e-4);
00175 }
00176
00178 TEST (LMedS, SampleConsensusModelPlane)
00179 {
00180 srand (0);
00181
00182 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00183
00184
00185 LeastMedianSquares<PointXYZ> sac (model, 0.03);
00186
00187
00188 bool result = sac.computeModel ();
00189 ASSERT_EQ (result, true);
00190
00191 std::vector<int> sample;
00192 sac.getModel (sample);
00193 EXPECT_EQ ((int)sample.size (), 3);
00194 EXPECT_EQ (sample[0], 338);
00195 EXPECT_EQ (sample[1], 413);
00196 EXPECT_EQ (sample[2], 1626);
00197
00198 std::vector<int> inliers;
00199 sac.getInliers (inliers);
00200 EXPECT_EQ ((int)inliers.size (), 2490);
00201
00202 Eigen::VectorXf coeff;
00203 sac.getModelCoefficients (coeff);
00204 EXPECT_EQ ((int)coeff.size (), 4);
00205 EXPECT_NEAR (coeff[0], -0.5413796306, 1e-4);
00206 EXPECT_NEAR (coeff[1], -0.3658693433, 1e-4);
00207 EXPECT_NEAR (coeff[2], -0.756999135, 1e-4);
00208 EXPECT_NEAR (coeff[3], 0.606127798, 1e-4);
00209
00210 Eigen::VectorXf coeff_refined;
00211 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00212 EXPECT_EQ ((int)coeff_refined.size (), 4);
00213 EXPECT_NEAR (coeff_refined[0], 0.5517195463, 1e-4);
00214 EXPECT_NEAR (coeff_refined[1], 0.3651787937, 1e-4);
00215 EXPECT_NEAR (coeff_refined[2], 0.74983340, 1e-4);
00216 EXPECT_NEAR (coeff_refined[3], -0.6159575582, 1e-4);
00217
00218
00219 PointCloud<PointXYZ> proj_points;
00220 model->projectPoints (inliers, coeff_refined, proj_points);
00221
00222 EXPECT_NEAR (proj_points.points[20].x, 1.12694, 1e-4);
00223 EXPECT_NEAR (proj_points.points[20].y, 0.0154845, 1e-4);
00224 EXPECT_NEAR (proj_points.points[20].z, -0.0152713, 1e-4);
00225
00226 EXPECT_NEAR (proj_points.points[30].x, 1.18486, 1e-4);
00227 EXPECT_NEAR (proj_points.points[30].y, -0.0632408, 1e-4);
00228 EXPECT_NEAR (proj_points.points[30].z, -0.0195459, 1e-4);
00229
00230 EXPECT_NEAR (proj_points.points[50].x, 1.07512, 1e-4);
00231 EXPECT_NEAR (proj_points.points[50].y, -0.0585533, 1e-4);
00232 EXPECT_NEAR (proj_points.points[50].z, 0.058916, 1e-4);
00233 }
00234
00236 TEST (MSAC, SampleConsensusModelPlane)
00237 {
00238 srand (0);
00239
00240 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00241
00242
00243 MEstimatorSampleConsensus<PointXYZ> sac (model, 0.03);
00244
00245
00246 bool result = sac.computeModel ();
00247 ASSERT_EQ (result, true);
00248
00249 std::vector<int> sample;
00250 sac.getModel (sample);
00251 EXPECT_EQ ((int)sample.size (), 3);
00252 EXPECT_EQ (sample[0], 464);
00253 EXPECT_EQ (sample[1], 1992);
00254 EXPECT_EQ (sample[2], 53);
00255
00256 std::vector<int> inliers;
00257 sac.getInliers (inliers);
00258 EXPECT_EQ ((int)inliers.size (), 2505);
00259
00260 Eigen::VectorXf coeff;
00261 sac.getModelCoefficients (coeff);
00262 EXPECT_EQ ((int)coeff.size (), 4);
00263
00264 EXPECT_NEAR (coeff[0], -0.5485954285, 1e-4);
00265 EXPECT_NEAR (coeff[1], -0.3597415686, 1e-4);
00266 EXPECT_NEAR (coeff[2], -0.7547376752, 1e-4);
00267 EXPECT_NEAR (coeff[3], 0.6130523086, 1e-4);
00268
00269 Eigen::VectorXf coeff_refined;
00270 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00271 EXPECT_EQ ((int)coeff_refined.size (), 4);
00272 EXPECT_NEAR (coeff_refined[0], 0.5532695055, 1e-4);
00273 EXPECT_NEAR (coeff_refined[1], 0.3648152649, 1e-4);
00274 EXPECT_NEAR (coeff_refined[2], 0.7488676906, 1e-4);
00275 EXPECT_NEAR (coeff_refined[3], -0.617486834, 1e-4);
00276
00277
00278 PointCloud<PointXYZ> proj_points;
00279 model->projectPoints (inliers, coeff_refined, proj_points);
00280
00281 EXPECT_NEAR (proj_points.points[20].x, 1.12681, 1e-4);
00282 EXPECT_NEAR (proj_points.points[20].y, 0.0154031, 1e-4);
00283 EXPECT_NEAR (proj_points.points[20].z, -0.0154375, 1e-4);
00284
00285 EXPECT_NEAR (proj_points.points[30].x, 1.18466, 1e-4);
00286 EXPECT_NEAR (proj_points.points[30].y, -0.0633676, 1e-4);
00287 EXPECT_NEAR (proj_points.points[30].z, -0.0198059, 1e-4);
00288
00289 EXPECT_NEAR (proj_points.points[50].x, 1.07506, 1e-4);
00290 EXPECT_NEAR (proj_points.points[50].y, -0.0585913, 1e-4);
00291 EXPECT_NEAR (proj_points.points[50].z, 0.0588374, 1e-4);
00292 }
00293
00295 TEST (RRANSAC, SampleConsensusModelPlane)
00296 {
00297 srand (0);
00298
00299 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00300
00301
00302 RandomizedRandomSampleConsensus<PointXYZ> sac (model, 0.03);
00303
00304 sac.setFractionNrPretest (10.0);
00305 ASSERT_EQ (sac.getFractionNrPretest (), 10.0);
00306
00307
00308 bool result = sac.computeModel ();
00309 ASSERT_EQ (result, true);
00310
00311 std::vector<int> sample;
00312 sac.getModel (sample);
00313 EXPECT_EQ ((int)sample.size (), 3);
00314 EXPECT_EQ (sample[0], 2758);
00315 EXPECT_EQ (sample[1], 1294);
00316 EXPECT_EQ (sample[2], 2570);
00317
00318 std::vector<int> inliers;
00319 sac.getInliers (inliers);
00320 EXPECT_EQ ((int)inliers.size (), 2482);
00321
00322 Eigen::VectorXf coeff;
00323 sac.getModelCoefficients (coeff);
00324 EXPECT_EQ ((int)coeff.size (), 4);
00325 EXPECT_NEAR (coeff[0], -0.5901594758, 1e-4);
00326 EXPECT_NEAR (coeff[1], -0.3539851904, 1e-4);
00327 EXPECT_NEAR (coeff[2], -0.725538671, 1e-4);
00328 EXPECT_NEAR (coeff[3], 0.6641977429, 1e-4);
00329
00330 Eigen::VectorXf coeff_refined;
00331 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00332 EXPECT_EQ ((int)coeff_refined.size (), 4);
00333 EXPECT_NEAR (fabs (coeff_refined[0]), 0.5598492622, 1e-4);
00334 EXPECT_NEAR (fabs (coeff_refined[1]), 0.3632659912, 1e-4);
00335 EXPECT_NEAR (fabs (coeff_refined[2]), 0.7447191477, 1e-4);
00336 EXPECT_NEAR (fabs (coeff_refined[3]), 0.6246083975, 1e-4);
00337
00338
00339 PointCloud<PointXYZ> proj_points;
00340 model->projectPoints (inliers, coeff_refined, proj_points);
00341
00342 EXPECT_NEAR (proj_points.points[20].x, 1.1266, 1e-4);
00343 EXPECT_NEAR (proj_points.points[20].y, 0.0152881, 1e-4);
00344 EXPECT_NEAR (proj_points.points[20].z, -0.0156696, 1e-4);
00345
00346 EXPECT_NEAR (proj_points.points[30].x, 1.18417, 1e-4);
00347 EXPECT_NEAR (proj_points.points[30].y, -0.0636751, 1e-4);
00348 EXPECT_NEAR (proj_points.points[30].z, -0.0204345, 1e-4);
00349
00350 EXPECT_NEAR (proj_points.points[50].x, 1.07519, 1e-4);
00351 EXPECT_NEAR (proj_points.points[50].y, -0.0585223, 1e-4);
00352 EXPECT_NEAR (proj_points.points[50].z, 0.0589761, 1e-4);
00353 }
00354
00356 TEST (RMSAC, SampleConsensusModelPlane)
00357 {
00358 srand (0);
00359
00360 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00361
00362
00363 RandomizedMEstimatorSampleConsensus<PointXYZ> sac (model, 0.03);
00364
00365 sac.setFractionNrPretest (10.0);
00366 ASSERT_EQ (sac.getFractionNrPretest (), 10.0);
00367
00368
00369 bool result = sac.computeModel ();
00370 ASSERT_EQ (result, true);
00371
00372 std::vector<int> sample;
00373 sac.getModel (sample);
00374 EXPECT_EQ ((int)sample.size (), 3);
00375 EXPECT_EQ (sample[0], 2758);
00376 EXPECT_EQ (sample[1], 1294);
00377 EXPECT_EQ (sample[2], 2570);
00378
00379 std::vector<int> inliers;
00380 sac.getInliers (inliers);
00381 EXPECT_EQ ((int)inliers.size (), 2482);
00382
00383 Eigen::VectorXf coeff;
00384 sac.getModelCoefficients (coeff);
00385 EXPECT_EQ ((int)coeff.size (), 4);
00386 EXPECT_NEAR (coeff[0], -0.5901594758, 1e-4);
00387 EXPECT_NEAR (coeff[1], -0.3539851904, 1e-4);
00388 EXPECT_NEAR (coeff[2], -0.725538671, 1e-4);
00389 EXPECT_NEAR (coeff[3], 0.6641977429, 1e-4);
00390
00391 Eigen::VectorXf coeff_refined;
00392 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00393 EXPECT_EQ ((int)coeff_refined.size (), 4);
00394 EXPECT_NEAR (fabs (coeff_refined[0]), 0.5598492622, 1e-4);
00395 EXPECT_NEAR (fabs (coeff_refined[1]), 0.3632659912, 1e-4);
00396 EXPECT_NEAR (fabs (coeff_refined[2]), 0.7447191477, 1e-4);
00397 EXPECT_NEAR (fabs (coeff_refined[3]), 0.6246083975, 1e-4);
00398
00399
00400 PointCloud<PointXYZ> proj_points;
00401 model->projectPoints (inliers, coeff_refined, proj_points);
00402
00403 EXPECT_NEAR (proj_points.points[20].x, 1.1266, 1e-4);
00404 EXPECT_NEAR (proj_points.points[20].y, 0.0152881, 1e-4);
00405 EXPECT_NEAR (proj_points.points[20].z, -0.0156696, 1e-4);
00406
00407 EXPECT_NEAR (proj_points.points[30].x, 1.18417, 1e-4);
00408 EXPECT_NEAR (proj_points.points[30].y, -0.0636751, 1e-4);
00409 EXPECT_NEAR (proj_points.points[30].z, -0.0204345, 1e-4);
00410
00411 EXPECT_NEAR (proj_points.points[50].x, 1.07519, 1e-4);
00412 EXPECT_NEAR (proj_points.points[50].y, -0.0585223, 1e-4);
00413 EXPECT_NEAR (proj_points.points[50].z, 0.0589761, 1e-4);
00414 }
00415
00417 TEST (MLESAC, SampleConsensusModelPlane)
00418 {
00419 srand (0);
00420
00421 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00422
00423
00424 MaximumLikelihoodSampleConsensus<PointXYZ> sac (model, 0.03);
00425
00426
00427 bool result = sac.computeModel ();
00428 ASSERT_EQ (result, true);
00429
00430 std::vector<int> sample;
00431 sac.getModel (sample);
00432 EXPECT_EQ ((int)sample.size (), 3);
00433 EXPECT_EQ (sample[0], 2758);
00434 EXPECT_EQ (sample[1], 1294);
00435 EXPECT_EQ (sample[2], 2570);
00436
00437 std::vector<int> inliers;
00438 sac.getInliers (inliers);
00439 EXPECT_EQ ((int)inliers.size (), 2214);
00440
00441 Eigen::VectorXf coeff;
00442 sac.getModelCoefficients (coeff);
00443 EXPECT_EQ ((int)coeff.size (), 4);
00444
00445 EXPECT_NEAR (coeff[0], -0.5901594758, 1e-4);
00446 EXPECT_NEAR (coeff[1], -0.3539851904, 1e-4);
00447 EXPECT_NEAR (coeff[2], -0.725538671, 1e-4);
00448 EXPECT_NEAR (coeff[3], 0.664197742, 1e-4);
00449
00450 Eigen::VectorXf coeff_refined;
00451 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00452 EXPECT_EQ ((int)coeff_refined.size (), 4);
00453 EXPECT_NEAR (fabs (coeff_refined[0]), 0.5599190593, 1e-4);
00454 EXPECT_NEAR (fabs (coeff_refined[1]), 0.3627234101, 1e-4);
00455 EXPECT_NEAR (fabs (coeff_refined[2]), 0.7449311614, 1e-4);
00456 EXPECT_NEAR (fabs (coeff_refined[3]), 0.625774502, 1e-4);
00457
00458
00459 PointCloud<PointXYZ> proj_points;
00460 model->projectPoints (inliers, coeff_refined, proj_points);
00461
00462 EXPECT_NEAR (proj_points.points[20].x, 1.12721, 1e-4);
00463 EXPECT_NEAR (proj_points.points[20].y, 0.01568, 1e-4);
00464 EXPECT_NEAR (proj_points.points[20].z, -0.014851, 1e-4);
00465
00466 EXPECT_NEAR (proj_points.points[30].x, 1.18476, 1e-4);
00467 EXPECT_NEAR (proj_points.points[30].y, -0.063291, 1e-4);
00468 EXPECT_NEAR (proj_points.points[30].z, -0.019650, 1e-4);
00469
00470 EXPECT_NEAR (proj_points.points[50].x, 1.07578, 1e-4);
00471 EXPECT_NEAR (proj_points.points[50].y, -0.058144, 1e-4);
00472 EXPECT_NEAR (proj_points.points[50].z, 0.059756, 1e-4);
00473 }
00474
00476 TEST (RANSAC, SampleConsensusModelSphere)
00477 {
00478 srand (0);
00479
00480
00481 PointCloud<PointXYZ> cloud;
00482 cloud.points.resize (10);
00483 cloud.points[0].x = 1.7068; cloud.points[0].y = 1.0684; cloud.points[0].z = 2.2147;
00484 cloud.points[1].x = 2.4708; cloud.points[1].y = 2.3081; cloud.points[1].z = 1.1736;
00485 cloud.points[2].x = 2.7609; cloud.points[2].y = 1.9095; cloud.points[2].z = 1.3574;
00486 cloud.points[3].x = 2.8016; cloud.points[3].y = 1.6704; cloud.points[3].z = 1.5009;
00487 cloud.points[4].x = 1.8517; cloud.points[4].y = 2.0276; cloud.points[4].z = 1.0112;
00488 cloud.points[5].x = 1.8726; cloud.points[5].y = 1.3539; cloud.points[5].z = 2.7523;
00489 cloud.points[6].x = 2.5179; cloud.points[6].y = 2.3218; cloud.points[6].z = 1.2074;
00490 cloud.points[7].x = 2.4026; cloud.points[7].y = 2.5114; cloud.points[7].z = 2.7588;
00491 cloud.points[8].x = 2.6999; cloud.points[8].y = 2.5606; cloud.points[8].z = 1.5571;
00492 cloud.points[9].x = 0; cloud.points[9].y = 0; cloud.points[9].z = 0;
00493
00494
00495 SampleConsensusModelSpherePtr model (new SampleConsensusModelSphere<PointXYZ> (cloud.makeShared ()));
00496
00497
00498 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00499
00500
00501 bool result = sac.computeModel ();
00502 ASSERT_EQ (result, true);
00503
00504 std::vector<int> sample;
00505 sac.getModel (sample);
00506 EXPECT_EQ ((int)sample.size (), 4);
00507 EXPECT_EQ (sample[0], 1);
00508 EXPECT_EQ (sample[1], 3);
00509 EXPECT_EQ (sample[2], 7);
00510 EXPECT_EQ (sample[3], 2);
00511
00512 std::vector<int> inliers;
00513 sac.getInliers (inliers);
00514 EXPECT_EQ ((int)inliers.size (), 9);
00515
00516 Eigen::VectorXf coeff;
00517 sac.getModelCoefficients (coeff);
00518 EXPECT_EQ ((int)coeff.size (), 4);
00519 EXPECT_NEAR (coeff[0], 2.00052, 1e-4);
00520 EXPECT_NEAR (coeff[1], 1.9997, 1e-4);
00521 EXPECT_NEAR (coeff[2], 2.00003, 1e-4);
00522 EXPECT_NEAR (coeff[3], 0.999565, 1e-4);
00523
00524 Eigen::VectorXf coeff_refined;
00525 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00526 EXPECT_EQ ((int)coeff_refined.size (), 4);
00527 EXPECT_NEAR (coeff_refined[0], 2.00023, 1e-3);
00528 EXPECT_NEAR (coeff_refined[1], 1.99979, 1e-3);
00529 EXPECT_NEAR (coeff_refined[2], 1.99979, 1e-3);
00530 EXPECT_NEAR (coeff_refined[3], 0.999888, 1e-3);
00531 }
00532
00534 TEST (RANSAC, SampleConsensusModelCylinder)
00535 {
00536 srand (0);
00537
00538
00539 PointCloud<PointXYZ> cloud;
00540 PointCloud<Normal> normals;
00541 cloud.points.resize (20); normals.points.resize (20);
00542
00543 cloud.points[0].x = -0.499902; cloud.points[0].y = 2.199701; cloud.points[0].z = 0.000008;
00544 cloud.points[1].x = -0.875397; cloud.points[1].y = 2.030177; cloud.points[1].z = 0.050104;
00545 cloud.points[2].x = -0.995875; cloud.points[2].y = 1.635973; cloud.points[2].z = 0.099846;
00546 cloud.points[3].x = -0.779523; cloud.points[3].y = 1.285527; cloud.points[3].z = 0.149961;
00547 cloud.points[4].x = -0.373285; cloud.points[4].y = 1.216488; cloud.points[4].z = 0.199959;
00548 cloud.points[5].x = -0.052893; cloud.points[5].y = 1.475973; cloud.points[5].z = 0.250101;
00549 cloud.points[6].x = -0.036558; cloud.points[6].y = 1.887591; cloud.points[6].z = 0.299839;
00550 cloud.points[7].x = -0.335048; cloud.points[7].y = 2.171994; cloud.points[7].z = 0.350001;
00551 cloud.points[8].x = -0.745456; cloud.points[8].y = 2.135528; cloud.points[8].z = 0.400072;
00552 cloud.points[9].x = -0.989282; cloud.points[9].y = 1.803311; cloud.points[9].z = 0.449983;
00553 cloud.points[10].x = -0.900651; cloud.points[10].y = 1.400701; cloud.points[10].z = 0.500126;
00554 cloud.points[11].x = -0.539658; cloud.points[11].y = 1.201468; cloud.points[11].z = 0.550079;
00555 cloud.points[12].x = -0.151875; cloud.points[12].y = 1.340951; cloud.points[12].z = 0.599983;
00556 cloud.points[13].x = -0.000724; cloud.points[13].y = 1.724373; cloud.points[13].z = 0.649882;
00557 cloud.points[14].x = -0.188573; cloud.points[14].y = 2.090983; cloud.points[14].z = 0.699854;
00558 cloud.points[15].x = -0.587925; cloud.points[15].y = 2.192257; cloud.points[15].z = 0.749956;
00559 cloud.points[16].x = -0.927724; cloud.points[16].y = 1.958846; cloud.points[16].z = 0.800008;
00560 cloud.points[17].x = -0.976888; cloud.points[17].y = 1.549655; cloud.points[17].z = 0.849970;
00561 cloud.points[18].x = -0.702003; cloud.points[18].y = 1.242707; cloud.points[18].z = 0.899954;
00562 cloud.points[19].x = -0.289916; cloud.points[19].y = 1.246296; cloud.points[19].z = 0.950075;
00563
00564 normals.points[0].normal[0] = 0.000098; normals.points[0].normal[1] = 1.000098; normals.points[0].normal[2] = 0.000008;
00565 normals.points[1].normal[0] = -0.750891; normals.points[1].normal[1] = 0.660413; normals.points[1].normal[2] = 0.000104;
00566 normals.points[2].normal[0] = -0.991765; normals.points[2].normal[1] = -0.127949; normals.points[2].normal[2] = -0.000154;
00567 normals.points[3].normal[0] = -0.558918; normals.points[3].normal[1] = -0.829439; normals.points[3].normal[2] = -0.000039;
00568 normals.points[4].normal[0] = 0.253627; normals.points[4].normal[1] = -0.967447; normals.points[4].normal[2] = -0.000041;
00569 normals.points[5].normal[0] = 0.894105; normals.points[5].normal[1] = -0.447965; normals.points[5].normal[2] = 0.000101;
00570 normals.points[6].normal[0] = 0.926852; normals.points[6].normal[1] = 0.375543; normals.points[6].normal[2] = -0.000161;
00571 normals.points[7].normal[0] = 0.329948; normals.points[7].normal[1] = 0.943941; normals.points[7].normal[2] = 0.000001;
00572 normals.points[8].normal[0] = -0.490966; normals.points[8].normal[1] = 0.871203; normals.points[8].normal[2] = 0.000072;
00573 normals.points[9].normal[0] = -0.978507; normals.points[9].normal[1] = 0.206425; normals.points[9].normal[2] = -0.000017;
00574 normals.points[10].normal[0] = -0.801227; normals.points[10].normal[1] = -0.598534; normals.points[10].normal[2] = 0.000126;
00575 normals.points[11].normal[0] = -0.079447; normals.points[11].normal[1] = -0.996697; normals.points[11].normal[2] = 0.000079;
00576 normals.points[12].normal[0] = 0.696154; normals.points[12].normal[1] = -0.717889; normals.points[12].normal[2] = -0.000017;
00577 normals.points[13].normal[0] = 0.998685; normals.points[13].normal[1] = 0.048502; normals.points[13].normal[2] = -0.000118;
00578 normals.points[14].normal[0] = 0.622933; normals.points[14].normal[1] = 0.782133; normals.points[14].normal[2] = -0.000146;
00579 normals.points[15].normal[0] = -0.175948; normals.points[15].normal[1] = 0.984480; normals.points[15].normal[2] = -0.000044;
00580 normals.points[16].normal[0] = -0.855476; normals.points[16].normal[1] = 0.517824; normals.points[16].normal[2] = 0.000008;
00581 normals.points[17].normal[0] = -0.953769; normals.points[17].normal[1] = -0.300571; normals.points[17].normal[2] = -0.000030;
00582 normals.points[18].normal[0] = -0.404035; normals.points[18].normal[1] = -0.914700; normals.points[18].normal[2] = -0.000046;
00583 normals.points[19].normal[0] = 0.420154; normals.points[19].normal[1] = -0.907445; normals.points[19].normal[2] = 0.000075;
00584
00585
00586 SampleConsensusModelCylinderPtr model (new SampleConsensusModelCylinder<PointXYZ, Normal> (cloud.makeShared ()));
00587 model->setInputNormals (normals.makeShared ());
00588
00589
00590 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00591
00592
00593 bool result = sac.computeModel ();
00594 ASSERT_EQ (result, true);
00595
00596 std::vector<int> sample;
00597 sac.getModel (sample);
00598 EXPECT_EQ ((int)sample.size (), 2);
00599 EXPECT_EQ (sample[0], 16);
00600 EXPECT_EQ (sample[1], 7);
00601
00602 std::vector<int> inliers;
00603 sac.getInliers (inliers);
00604 EXPECT_EQ ((int)inliers.size (), 20);
00605
00606 Eigen::VectorXf coeff;
00607 sac.getModelCoefficients (coeff);
00608 EXPECT_EQ ((int)coeff.size (), 7);
00609 EXPECT_NEAR (coeff[0], -0.500038, 1e-4);
00610 EXPECT_NEAR (coeff[1], 1.69997, 1e-4);
00611 EXPECT_NEAR (coeff[6], 0.499934, 1e-4);
00612
00613 Eigen::VectorXf coeff_refined;
00614 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00615 EXPECT_EQ ((int)coeff_refined.size (), 7);
00616 EXPECT_NEAR (coeff_refined[6], 0.499966, 1e-4);
00617 }
00618
00620 TEST (RANSAC, SampleConsensusModelCircle2D)
00621 {
00622 srand (0);
00623
00624
00625 PointCloud<PointXYZ> cloud;
00626 cloud.points.resize (18);
00627
00628 cloud.points[0].x = 3.587751; cloud.points[0].y = -4.190982; cloud.points[0].z = 0;
00629 cloud.points[1].x = 3.808883; cloud.points[1].y = -4.412265; cloud.points[1].z = 0;
00630 cloud.points[2].x = 3.587525; cloud.points[2].y = -5.809143; cloud.points[2].z = 0;
00631 cloud.points[3].x = 2.999913; cloud.points[3].y = -5.999980; cloud.points[3].z = 0;
00632 cloud.points[4].x = 2.412224; cloud.points[4].y = -5.809090; cloud.points[4].z = 0;
00633 cloud.points[5].x = 2.191080; cloud.points[5].y = -5.587682; cloud.points[5].z = 0;
00634 cloud.points[6].x = 2.048941; cloud.points[6].y = -5.309003; cloud.points[6].z = 0;
00635 cloud.points[7].x = 2.000397; cloud.points[7].y = -4.999944; cloud.points[7].z = 0;
00636 cloud.points[8].x = 2.999953; cloud.points[8].y = -6.000056; cloud.points[8].z = 0;
00637 cloud.points[9].x = 2.691127; cloud.points[9].y = -5.951136; cloud.points[9].z = 0;
00638 cloud.points[10].x = 2.190892; cloud.points[10].y = -5.587838; cloud.points[10].z = 0;
00639 cloud.points[11].x = 2.048874; cloud.points[11].y = -5.309052; cloud.points[11].z = 0;
00640 cloud.points[12].x = 1.999990; cloud.points[12].y = -5.000147; cloud.points[12].z = 0;
00641 cloud.points[13].x = 2.049026; cloud.points[13].y = -4.690918; cloud.points[13].z = 0;
00642 cloud.points[14].x = 2.190956; cloud.points[14].y = -4.412162; cloud.points[14].z = 0;
00643 cloud.points[15].x = 2.412231; cloud.points[15].y = -4.190918; cloud.points[15].z = 0;
00644 cloud.points[16].x = 2.691027; cloud.points[16].y = -4.049060; cloud.points[16].z = 0;
00645 cloud.points[17].x = 2; cloud.points[17].y = -3; cloud.points[17].z = 0;
00646
00647
00648 SampleConsensusModelCircle2DPtr model (new SampleConsensusModelCircle2D<PointXYZ> (cloud.makeShared ()));
00649
00650
00651 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00652
00653
00654 bool result = sac.computeModel ();
00655 ASSERT_EQ (result, true);
00656
00657 std::vector<int> sample;
00658 sac.getModel (sample);
00659 EXPECT_EQ ((int)sample.size (), 3);
00660 EXPECT_EQ (sample[0], 15);
00661 EXPECT_EQ (sample[1], 7);
00662 EXPECT_EQ (sample[2], 14);
00663
00664 std::vector<int> inliers;
00665 sac.getInliers (inliers);
00666 EXPECT_EQ ((int)inliers.size (), 17);
00667
00668 Eigen::VectorXf coeff;
00669 sac.getModelCoefficients (coeff);
00670 EXPECT_EQ ((int)coeff.size (), 3);
00671 EXPECT_NEAR (coeff[0], 2.9988, 1e-4);
00672 EXPECT_NEAR (coeff[1], -4.99885, 1e-4);
00673 EXPECT_NEAR (coeff[2], 0.998406, 1e-4);
00674
00675 Eigen::VectorXf coeff_refined;
00676 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00677 EXPECT_EQ ((int)coeff_refined.size (), 3);
00678 EXPECT_NEAR (coeff_refined[0], 2.99999, 1e-4);
00679 EXPECT_NEAR (coeff_refined[1], -5.00004, 1e-4);
00680 EXPECT_NEAR (coeff_refined[2], 0.999962, 1e-4);
00681 }
00682
00684 TEST (RANSAC, SampleConsensusModelLine)
00685 {
00686 srand (0);
00687
00688
00689 PointCloud<PointXYZ> cloud;
00690 cloud.points.resize (10);
00691
00692 cloud.points[0].x = 1; cloud.points[0].y = 2; cloud.points[0].z = 3;
00693 cloud.points[1].x = 4; cloud.points[1].y = 5; cloud.points[1].z = 6;
00694 cloud.points[2].x = 7; cloud.points[2].y = 8; cloud.points[2].z = 9;
00695 cloud.points[3].x = 10; cloud.points[3].y = 11; cloud.points[3].z = 12;
00696 cloud.points[4].x = 13; cloud.points[4].y = 14; cloud.points[4].z = 15;
00697 cloud.points[5].x = 16; cloud.points[5].y = 17; cloud.points[5].z = 18;
00698 cloud.points[6].x = 19; cloud.points[6].y = 20; cloud.points[6].z = 21;
00699 cloud.points[7].x = 22; cloud.points[7].y = 23; cloud.points[7].z = 24;
00700 cloud.points[8].x = -5; cloud.points[8].y = 1.57; cloud.points[8].z = 0.75;
00701 cloud.points[9].x = 4; cloud.points[9].y = 2; cloud.points[9].z = 3;
00702
00703
00704 SampleConsensusModelLinePtr model (new SampleConsensusModelLine<PointXYZ> (cloud.makeShared ()));
00705
00706
00707 RandomSampleConsensus<PointXYZ> sac (model, 0.001);
00708
00709
00710 bool result = sac.computeModel ();
00711 ASSERT_EQ (result, true);
00712
00713 std::vector<int> sample;
00714 sac.getModel (sample);
00715 EXPECT_EQ ((int)sample.size (), 2);
00716 EXPECT_EQ (sample[0], 1);
00717 EXPECT_EQ (sample[1], 3);
00718
00719 std::vector<int> inliers;
00720 sac.getInliers (inliers);
00721 EXPECT_EQ ((int)inliers.size (), 8);
00722
00723 Eigen::VectorXf coeff;
00724 sac.getModelCoefficients (coeff);
00725 EXPECT_EQ ((int)coeff.size (), 6);
00726 EXPECT_NEAR (coeff[3], 0.57735, 1e-4);
00727 EXPECT_NEAR (coeff[4], 0.57735, 1e-4);
00728 EXPECT_NEAR (coeff[5], 0.57735, 1e-4);
00729
00730 Eigen::VectorXf coeff_refined;
00731 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00732 EXPECT_EQ ((int)coeff_refined.size (), 6);
00733 EXPECT_NEAR (coeff_refined[3], 0.57735, 1e-4);
00734 EXPECT_NEAR (coeff_refined[4], 0.57735, 1e-4);
00735 EXPECT_NEAR (coeff_refined[5], 0.57735, 1e-4);
00736
00737
00738 PointCloud<PointXYZ> proj_points;
00739 model->projectPoints (inliers, coeff_refined, proj_points);
00740
00741 EXPECT_NEAR (proj_points.points[2].x, 7.0, 1e-4);
00742 EXPECT_NEAR (proj_points.points[2].y, 8.0, 1e-4);
00743 EXPECT_NEAR (proj_points.points[2].z, 9.0, 1e-4);
00744
00745 EXPECT_NEAR (proj_points.points[3].x, 10.0, 1e-4);
00746 EXPECT_NEAR (proj_points.points[3].y, 11.0, 1e-4);
00747 EXPECT_NEAR (proj_points.points[3].z, 12.0, 1e-4);
00748
00749 EXPECT_NEAR (proj_points.points[5].x, 16.0, 1e-4);
00750 EXPECT_NEAR (proj_points.points[5].y, 17.0, 1e-4);
00751 EXPECT_NEAR (proj_points.points[5].z, 18.0, 1e-4);
00752 }
00753
00755 TEST (RANSAC, SampleConsensusModelNormalPlane)
00756 {
00757 srand (0);
00758
00759 SampleConsensusModelNormalPlanePtr model (new SampleConsensusModelNormalPlane<PointXYZ, Normal> (cloud_));
00760 model->setInputNormals (normals_);
00761 model->setNormalDistanceWeight (0.01);
00762
00763 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00764
00765
00766 bool result = sac.computeModel ();
00767 ASSERT_EQ (result, true);
00768
00769 std::vector<int> sample;
00770 sac.getModel (sample);
00771 EXPECT_EQ ((int)sample.size (), 3);
00772 EXPECT_EQ (sample[0], 1818);
00773 EXPECT_EQ (sample[1], 1567);
00774 EXPECT_EQ (sample[2], 2064);
00775
00776 std::vector<int> inliers;
00777 sac.getInliers (inliers);
00778 EXPECT_EQ ((int)inliers.size (), 2440);
00779
00780 Eigen::VectorXf coeff;
00781 sac.getModelCoefficients (coeff);
00782 EXPECT_EQ ((int)coeff.size (), 4);
00783 EXPECT_NEAR (coeff[0], 0.5590537786, 1e-4);
00784 EXPECT_NEAR (coeff[1], 0.3575230538, 1e-4);
00785 EXPECT_NEAR (coeff[2], 0.7480884194, 1e-4);
00786 EXPECT_NEAR (coeff[3], -0.6228785514, 1e-4);
00787
00788 Eigen::VectorXf coeff_refined;
00789 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00790 EXPECT_EQ ((int)coeff_refined.size (), 4);
00791 EXPECT_NEAR (fabs (coeff_refined[0]), 0.552499, 1e-4);
00792 EXPECT_NEAR (fabs (coeff_refined[1]), 0.364361, 1e-4);
00793 EXPECT_NEAR (fabs (coeff_refined[2]), 0.749656, 1e-4);
00794 EXPECT_NEAR (fabs (coeff_refined[3]), 0.617206, 1e-4);
00795
00796
00797 PointCloud<PointXYZ> proj_points;
00798 model->projectPoints (inliers, coeff_refined, proj_points);
00799
00800 EXPECT_NEAR (proj_points.points[20].x, 1.12707, 1e-4);
00801 EXPECT_NEAR (proj_points.points[20].y, 0.0155766, 1e-4);
00802 EXPECT_NEAR (proj_points.points[20].z, -0.0149861, 1e-4);
00803
00804 EXPECT_NEAR (proj_points.points[30].x, 1.185, 1e-4);
00805 EXPECT_NEAR (proj_points.points[30].y, -0.063224, 1e-4);
00806 EXPECT_NEAR (proj_points.points[30].z, -0.019343, 1e-4);
00807
00808 EXPECT_NEAR (proj_points.points[50].x, 1.07528, 1e-4);
00809 EXPECT_NEAR (proj_points.points[50].y, -0.0584513, 1e-4);
00810 EXPECT_NEAR (proj_points.points[50].z, 0.0591309, 1e-4);
00811 }
00812
00813
00814 int
00815 main (int argc, char** argv)
00816 {
00817
00818 sensor_msgs::PointCloud2 cloud_blob;
00819 loadPCDFile ("./test/sac_plane_test.pcd", cloud_blob);
00820 fromROSMsg (cloud_blob, *cloud_);
00821
00822 indices_.resize (cloud_->points.size ());
00823 for (size_t i = 0; i < indices_.size (); ++i) { indices_[i] = i; }
00824
00825
00826 NormalEstimation<PointXYZ, Normal> n;
00827 KdTree<PointXYZ>::Ptr tree = boost::make_shared<KdTreeFLANN<PointXYZ> > ();
00828 tree->setInputCloud (cloud_);
00829 n.setInputCloud (cloud_);
00830 n.setIndices (boost::make_shared <vector<int> > (indices_));
00831 n.setSearchMethod (tree);
00832 n.setRadiusSearch (0.02);
00833 n.compute (*normals_);
00834
00835 testing::InitGoogleTest (&argc, argv);
00836 return (RUN_ALL_TESTS ());
00837 }
00838