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 #include <gtest/gtest.h>
00040 #include <pcl/io/pcd_io.h>
00041 #include <pcl/sample_consensus/sac.h>
00042 #include <pcl/sample_consensus/lmeds.h>
00043 #include <pcl/sample_consensus/ransac.h>
00044 #include <pcl/sample_consensus/rransac.h>
00045 #include <pcl/sample_consensus/msac.h>
00046 #include <pcl/sample_consensus/rmsac.h>
00047 #include <pcl/sample_consensus/mlesac.h>
00048 #include <pcl/sample_consensus/sac_model.h>
00049 #include <pcl/sample_consensus/sac_model_plane.h>
00050 #include <pcl/sample_consensus/sac_model_sphere.h>
00051 #include <pcl/sample_consensus/sac_model_cone.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_normal_sphere.h>
00057 #include <pcl/sample_consensus/sac_model_parallel_plane.h>
00058 #include <pcl/sample_consensus/sac_model_normal_parallel_plane.h>
00059 #include <pcl/features/normal_3d.h>
00060 #include <boost/thread.hpp>
00061
00062 using namespace pcl;
00063 using namespace pcl::io;
00064 using namespace std;
00065
00066 typedef SampleConsensusModel<PointXYZ>::Ptr SampleConsensusModelPtr;
00067 typedef SampleConsensusModelPlane<PointXYZ>::Ptr SampleConsensusModelPlanePtr;
00068 typedef SampleConsensusModelSphere<PointXYZ>::Ptr SampleConsensusModelSpherePtr;
00069 typedef SampleConsensusModelCylinder<PointXYZ, Normal>::Ptr SampleConsensusModelCylinderPtr;
00070 typedef SampleConsensusModelCone<PointXYZ, Normal>::Ptr SampleConsensusModelConePtr;
00071 typedef SampleConsensusModelCircle2D<PointXYZ>::Ptr SampleConsensusModelCircle2DPtr;
00072 typedef SampleConsensusModelLine<PointXYZ>::Ptr SampleConsensusModelLinePtr;
00073 typedef SampleConsensusModelNormalPlane<PointXYZ, Normal>::Ptr SampleConsensusModelNormalPlanePtr;
00074 typedef SampleConsensusModelNormalSphere<PointXYZ, Normal>::Ptr SampleConsensusModelNormalSpherePtr;
00075 typedef SampleConsensusModelParallelPlane<PointXYZ>::Ptr SampleConsensusModelParallelPlanePtr;
00076 typedef SampleConsensusModelNormalParallelPlane<PointXYZ, Normal>::Ptr SampleConsensusModelNormalParallelPlanePtr;
00077
00078 PointCloud<PointXYZ>::Ptr cloud_ (new PointCloud<PointXYZ> ());
00079 PointCloud<Normal>::Ptr normals_ (new PointCloud<Normal> ());
00080 vector<int> indices_;
00081 float plane_coeffs_[] = {-0.8964f, -0.5868f, -1.208f};
00082
00084
00085 template<typename ModelType, typename SacType>
00086 void verifyPlaneSac (ModelType & model, SacType & sac, unsigned int inlier_number = 2000, float tol = 1e-1f,
00087 float refined_tol = 1e-1f, float proj_tol = 1e-3f)
00088 {
00089
00090 bool result = sac.computeModel ();
00091 ASSERT_EQ (result, true);
00092
00093 std::vector<int> sample;
00094 sac.getModel (sample);
00095 EXPECT_EQ (int (sample.size ()), 3);
00096
00097 std::vector<int> inliers;
00098 sac.getInliers (inliers);
00099 EXPECT_GE (int (inliers.size ()), inlier_number);
00100
00101 Eigen::VectorXf coeff;
00102 sac.getModelCoefficients (coeff);
00103 EXPECT_EQ (int (coeff.size ()), 4);
00104 EXPECT_NEAR (coeff[0]/coeff[3], plane_coeffs_[0], tol);
00105 EXPECT_NEAR (coeff[1]/coeff[3], plane_coeffs_[1], tol);
00106 EXPECT_NEAR (coeff[2]/coeff[3], plane_coeffs_[2], tol);
00107
00108
00109 Eigen::VectorXf coeff_refined;
00110 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00111 EXPECT_EQ (int (coeff_refined.size ()), 4);
00112 EXPECT_NEAR (coeff_refined[0]/coeff_refined[3], plane_coeffs_[0], refined_tol);
00113 EXPECT_NEAR (coeff_refined[1]/coeff_refined[3], plane_coeffs_[1], refined_tol);
00114
00115
00116
00117
00118
00119 PointCloud<PointXYZ> proj_points;
00120 model->projectPoints (inliers, coeff_refined, proj_points);
00121 EXPECT_NEAR (proj_points.points[20].x, 1.1266, proj_tol);
00122 EXPECT_NEAR (proj_points.points[20].y, 0.0152, proj_tol);
00123 EXPECT_NEAR (proj_points.points[20].z, -0.0156, proj_tol);
00124
00125 EXPECT_NEAR (proj_points.points[30].x, 1.1843, proj_tol);
00126 EXPECT_NEAR (proj_points.points[30].y, -0.0635, proj_tol);
00127 EXPECT_NEAR (proj_points.points[30].z, -0.0201, proj_tol);
00128
00129 EXPECT_NEAR (proj_points.points[50].x, 1.0749, proj_tol);
00130 EXPECT_NEAR (proj_points.points[50].y, -0.0586, proj_tol);
00131 EXPECT_NEAR (proj_points.points[50].z, 0.0587, refined_tol);
00132 }
00133
00135 TEST (SampleConsensusModelPlane, Base)
00136 {
00137
00138 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00139
00140
00141 PointCloud<PointXYZ>::ConstPtr cloud = model->getInputCloud ();
00142 ASSERT_EQ (cloud->points.size (), cloud_->points.size ());
00143
00144 model->setInputCloud (cloud);
00145 cloud = model->getInputCloud ();
00146 ASSERT_EQ (cloud->points.size (), cloud_->points.size ());
00147
00148 boost::shared_ptr<vector<int> > indices = model->getIndices ();
00149 ASSERT_EQ (indices->size (), indices_.size ());
00150 model->setIndices (indices_);
00151 indices = model->getIndices ();
00152 ASSERT_EQ (indices->size (), indices_.size ());
00153 model->setIndices (indices);
00154 indices = model->getIndices ();
00155 ASSERT_EQ (indices->size (), indices_.size ());
00156 }
00157
00159 TEST (RANSAC, Base)
00160 {
00161
00162 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00163
00164
00165 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00166
00167
00168 ASSERT_EQ (sac.getDistanceThreshold (), 0.03);
00169 sac.setDistanceThreshold (0.03);
00170 ASSERT_EQ (sac.getDistanceThreshold (), 0.03);
00171
00172 sac.setProbability (0.99);
00173 ASSERT_EQ (sac.getProbability (), 0.99);
00174
00175 sac.setMaxIterations (10000);
00176 ASSERT_EQ (sac.getMaxIterations (), 10000);
00177 }
00178
00180 TEST (RANSAC, SampleConsensusModelPlane)
00181 {
00182 srand (0);
00183
00184 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00185
00186
00187 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00188
00189 verifyPlaneSac(model, sac);
00190 }
00191
00193 TEST (LMedS, SampleConsensusModelPlane)
00194 {
00195 srand (0);
00196
00197 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00198
00199
00200 LeastMedianSquares<PointXYZ> sac (model, 0.03);
00201
00202 verifyPlaneSac(model, sac);
00203 }
00204
00206 TEST (MSAC, SampleConsensusModelPlane)
00207 {
00208 srand (0);
00209
00210 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00211
00212
00213 MEstimatorSampleConsensus<PointXYZ> sac (model, 0.03);
00214
00215 verifyPlaneSac (model, sac);
00216 }
00217
00219 TEST (RRANSAC, SampleConsensusModelPlane)
00220 {
00221 srand (0);
00222
00223 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00224
00225
00226 RandomizedRandomSampleConsensus<PointXYZ> sac (model, 0.03);
00227
00228 sac.setFractionNrPretest (10.0);
00229 ASSERT_EQ (sac.getFractionNrPretest (), 10.0);
00230
00231 verifyPlaneSac(model, sac, 600, 1.0f, 1.0f, 0.01f);
00232 }
00233
00235 TEST (RMSAC, SampleConsensusModelPlane)
00236 {
00237 srand (0);
00238
00239 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00240
00241
00242 RandomizedMEstimatorSampleConsensus<PointXYZ> sac (model, 0.03);
00243
00244 sac.setFractionNrPretest (10.0);
00245 ASSERT_EQ (sac.getFractionNrPretest (), 10.0);
00246
00247 verifyPlaneSac(model, sac, 600, 1.0f, 1.0f, 0.01f);
00248 }
00249
00251 TEST (RANSAC, SampleConsensusModelNormalParallelPlane)
00252 {
00253 srand (0);
00254
00255 PointCloud<PointXYZ> cloud;
00256 PointCloud<Normal> normals;
00257 cloud.points.resize (10);
00258 normals.resize (10);
00259
00260 for (unsigned idx = 0; idx < cloud.size (); ++idx)
00261 {
00262 cloud.points[idx].x = static_cast<float> ((rand () % 200) - 100);
00263 cloud.points[idx].y = static_cast<float> ((rand () % 200) - 100);
00264 cloud.points[idx].z = 0.0f;
00265
00266 normals.points[idx].normal_x = 0.0f;
00267 normals.points[idx].normal_y = 0.0f;
00268 normals.points[idx].normal_z = 1.0f;
00269 }
00270
00271
00272 SampleConsensusModelNormalParallelPlanePtr model (new SampleConsensusModelNormalParallelPlane<PointXYZ, Normal> (cloud.makeShared ()));
00273 model->setInputNormals (normals.makeShared ());
00274
00275 const float max_angle_rad = 0.01f;
00276 const float angle_eps = 0.001f;
00277 model->setEpsAngle (max_angle_rad);
00278
00279
00280 {
00281 model->setAxis (Eigen::Vector3f (0, 0, 1));
00282
00283 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00284 sac.computeModel();
00285
00286 std::vector<int> inliers;
00287 sac.getInliers (inliers);
00288 ASSERT_EQ (inliers.size (), cloud.size ());
00289 }
00290
00291
00292 {
00293 model->setAxis (Eigen::Vector3f(0, sin(max_angle_rad * (1 - angle_eps)), cos(max_angle_rad * (1 - angle_eps))));
00294 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00295 sac.computeModel();
00296
00297 std::vector<int> inliers;
00298 sac.getInliers (inliers);
00299 ASSERT_EQ (inliers.size (), cloud.size ());
00300 }
00301
00302
00303 {
00304 model->setAxis (Eigen::Vector3f(0, sin(max_angle_rad * (1 + angle_eps)), cos(max_angle_rad * (1 + angle_eps))));
00305 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00306 sac.computeModel();
00307
00308 std::vector<int> inliers;
00309 sac.getInliers (inliers);
00310 ASSERT_EQ (inliers.size (), 0);
00311 }
00312 }
00313
00314
00316 TEST (MLESAC, SampleConsensusModelPlane)
00317 {
00318 srand (0);
00319
00320 SampleConsensusModelPlanePtr model (new SampleConsensusModelPlane<PointXYZ> (cloud_));
00321
00322
00323 MaximumLikelihoodSampleConsensus<PointXYZ> sac (model, 0.03);
00324
00325 verifyPlaneSac(model, sac, 1000, 0.3f, 0.2f, 0.01f);
00326 }
00327
00329 TEST (RANSAC, SampleConsensusModelSphere)
00330 {
00331 srand (0);
00332
00333
00334 PointCloud<PointXYZ> cloud;
00335 cloud.points.resize (10);
00336 cloud.points[0].x = 1.7068f; cloud.points[0].y = 1.0684f; cloud.points[0].z = 2.2147f;
00337 cloud.points[1].x = 2.4708f; cloud.points[1].y = 2.3081f; cloud.points[1].z = 1.1736f;
00338 cloud.points[2].x = 2.7609f; cloud.points[2].y = 1.9095f; cloud.points[2].z = 1.3574f;
00339 cloud.points[3].x = 2.8016f; cloud.points[3].y = 1.6704f; cloud.points[3].z = 1.5009f;
00340 cloud.points[4].x = 1.8517f; cloud.points[4].y = 2.0276f; cloud.points[4].z = 1.0112f;
00341 cloud.points[5].x = 1.8726f; cloud.points[5].y = 1.3539f; cloud.points[5].z = 2.7523f;
00342 cloud.points[6].x = 2.5179f; cloud.points[6].y = 2.3218f; cloud.points[6].z = 1.2074f;
00343 cloud.points[7].x = 2.4026f; cloud.points[7].y = 2.5114f; cloud.points[7].z = 2.7588f;
00344 cloud.points[8].x = 2.6999f; cloud.points[8].y = 2.5606f; cloud.points[8].z = 1.5571f;
00345 cloud.points[9].x = 0.0f; cloud.points[9].y = 0.0f; cloud.points[9].z = 0.0f;
00346
00347
00348 SampleConsensusModelSpherePtr model (new SampleConsensusModelSphere<PointXYZ> (cloud.makeShared ()));
00349
00350
00351 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00352
00353
00354 bool result = sac.computeModel ();
00355 ASSERT_EQ (result, true);
00356
00357 std::vector<int> sample;
00358 sac.getModel (sample);
00359 EXPECT_EQ (int (sample.size ()), 4);
00360
00361 std::vector<int> inliers;
00362 sac.getInliers (inliers);
00363 EXPECT_EQ (int (inliers.size ()), 9);
00364
00365 Eigen::VectorXf coeff;
00366 sac.getModelCoefficients (coeff);
00367 EXPECT_EQ (int (coeff.size ()), 4);
00368 EXPECT_NEAR (coeff[0]/coeff[3], 2, 1e-2);
00369 EXPECT_NEAR (coeff[1]/coeff[3], 2, 1e-2);
00370 EXPECT_NEAR (coeff[2]/coeff[3], 2, 1e-2);
00371
00372 Eigen::VectorXf coeff_refined;
00373 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00374 EXPECT_EQ (int (coeff_refined.size ()), 4);
00375 EXPECT_NEAR (coeff_refined[0]/coeff_refined[3], 2, 1e-2);
00376 EXPECT_NEAR (coeff_refined[1]/coeff_refined[3], 2, 1e-2);
00377 EXPECT_NEAR (coeff_refined[2]/coeff_refined[3], 2, 1e-2);
00378 }
00379
00381 TEST (RANSAC, SampleConsensusModelNormalSphere)
00382 {
00383 srand (0);
00384
00385
00386 PointCloud<PointXYZ> cloud;
00387 PointCloud<Normal> normals;
00388 cloud.points.resize (27); normals.points.resize (27);
00389 cloud.points[0].x = -0.014695f; cloud.points[0].y = 0.009549f; cloud.points[0].z = 0.954775f;
00390 cloud.points[1].x = 0.014695f; cloud.points[1].y = 0.009549f; cloud.points[1].z = 0.954775f;
00391 cloud.points[2].x = -0.014695f; cloud.points[2].y = 0.040451f; cloud.points[2].z = 0.954775f;
00392 cloud.points[3].x = 0.014695f; cloud.points[3].y = 0.040451f; cloud.points[3].z = 0.954775f;
00393 cloud.points[4].x = -0.009082f; cloud.points[4].y = -0.015451f; cloud.points[4].z = 0.972049f;
00394 cloud.points[5].x = 0.009082f; cloud.points[5].y = -0.015451f; cloud.points[5].z = 0.972049f;
00395 cloud.points[6].x = -0.038471f; cloud.points[6].y = 0.009549f; cloud.points[6].z = 0.972049f;
00396 cloud.points[7].x = 0.038471f; cloud.points[7].y = 0.009549f; cloud.points[7].z = 0.972049f;
00397 cloud.points[8].x = -0.038471f; cloud.points[8].y = 0.040451f; cloud.points[8].z = 0.972049f;
00398 cloud.points[9].x = 0.038471f; cloud.points[9].y = 0.040451f; cloud.points[9].z = 0.972049f;
00399 cloud.points[10].x = -0.009082f; cloud.points[10].y = 0.065451f; cloud.points[10].z = 0.972049f;
00400 cloud.points[11].x = 0.009082f; cloud.points[11].y = 0.065451f; cloud.points[11].z = 0.972049f;
00401 cloud.points[12].x = -0.023776f; cloud.points[12].y = -0.015451f; cloud.points[12].z = 0.982725f;
00402 cloud.points[13].x = 0.023776f; cloud.points[13].y = -0.015451f; cloud.points[13].z = 0.982725f;
00403 cloud.points[14].x = -0.023776f; cloud.points[14].y = 0.065451f; cloud.points[14].z = 0.982725f;
00404 cloud.points[15].x = 0.023776f; cloud.points[15].y = 0.065451f; cloud.points[15].z = 0.982725f;
00405 cloud.points[16].x = -0.000000f; cloud.points[16].y = -0.025000f; cloud.points[16].z = 1.000000f;
00406 cloud.points[17].x = 0.000000f; cloud.points[17].y = -0.025000f; cloud.points[17].z = 1.000000f;
00407 cloud.points[18].x = -0.029389f; cloud.points[18].y = -0.015451f; cloud.points[18].z = 1.000000f;
00408 cloud.points[19].x = 0.029389f; cloud.points[19].y = -0.015451f; cloud.points[19].z = 1.000000f;
00409 cloud.points[20].x = -0.047553f; cloud.points[20].y = 0.009549f; cloud.points[20].z = 1.000000f;
00410 cloud.points[21].x = 0.047553f; cloud.points[21].y = 0.009549f; cloud.points[21].z = 1.000000f;
00411 cloud.points[22].x = -0.047553f; cloud.points[22].y = 0.040451f; cloud.points[22].z = 1.000000f;
00412 cloud.points[23].x = 0.047553f; cloud.points[23].y = 0.040451f; cloud.points[23].z = 1.000000f;
00413 cloud.points[24].x = -0.029389f; cloud.points[24].y = 0.065451f; cloud.points[24].z = 1.000000f;
00414 cloud.points[25].x = 0.029389f; cloud.points[25].y = 0.065451f; cloud.points[25].z = 1.000000f;
00415 cloud.points[26].x = 0.000000f; cloud.points[26].y = 0.075000f; cloud.points[26].z = 1.000000f;
00416
00417 normals.points[0].normal[0] = -0.293893f; normals.points[0].normal[1] = -0.309017f; normals.points[0].normal[2] = -0.904509f;
00418 normals.points[1].normal[0] = 0.293893f; normals.points[1].normal[1] = -0.309017f; normals.points[1].normal[2] = -0.904508f;
00419 normals.points[2].normal[0] = -0.293893f; normals.points[2].normal[1] = 0.309017f; normals.points[2].normal[2] = -0.904509f;
00420 normals.points[3].normal[0] = 0.293893f; normals.points[3].normal[1] = 0.309017f; normals.points[3].normal[2] = -0.904508f;
00421 normals.points[4].normal[0] = -0.181636f; normals.points[4].normal[1] = -0.809017f; normals.points[4].normal[2] = -0.559017f;
00422 normals.points[5].normal[0] = 0.181636f; normals.points[5].normal[1] = -0.809017f; normals.points[5].normal[2] = -0.559017f;
00423 normals.points[6].normal[0] = -0.769421f; normals.points[6].normal[1] = -0.309017f; normals.points[6].normal[2] = -0.559017f;
00424 normals.points[7].normal[0] = 0.769421f; normals.points[7].normal[1] = -0.309017f; normals.points[7].normal[2] = -0.559017f;
00425 normals.points[8].normal[0] = -0.769421f; normals.points[8].normal[1] = 0.309017f; normals.points[8].normal[2] = -0.559017f;
00426 normals.points[9].normal[0] = 0.769421f; normals.points[9].normal[1] = 0.309017f; normals.points[9].normal[2] = -0.559017f;
00427 normals.points[10].normal[0] = -0.181636f; normals.points[10].normal[1] = 0.809017f; normals.points[10].normal[2] = -0.559017f;
00428 normals.points[11].normal[0] = 0.181636f; normals.points[11].normal[1] = 0.809017f; normals.points[11].normal[2] = -0.559017f;
00429 normals.points[12].normal[0] = -0.475528f; normals.points[12].normal[1] = -0.809017f; normals.points[12].normal[2] = -0.345491f;
00430 normals.points[13].normal[0] = 0.475528f; normals.points[13].normal[1] = -0.809017f; normals.points[13].normal[2] = -0.345491f;
00431 normals.points[14].normal[0] = -0.475528f; normals.points[14].normal[1] = 0.809017f; normals.points[14].normal[2] = -0.345491f;
00432 normals.points[15].normal[0] = 0.475528f; normals.points[15].normal[1] = 0.809017f; normals.points[15].normal[2] = -0.345491f;
00433 normals.points[16].normal[0] = -0.000000f; normals.points[16].normal[1] = -1.000000f; normals.points[16].normal[2] = 0.000000f;
00434 normals.points[17].normal[0] = 0.000000f; normals.points[17].normal[1] = -1.000000f; normals.points[17].normal[2] = 0.000000f;
00435 normals.points[18].normal[0] = -0.587785f; normals.points[18].normal[1] = -0.809017f; normals.points[18].normal[2] = 0.000000f;
00436 normals.points[19].normal[0] = 0.587785f; normals.points[19].normal[1] = -0.809017f; normals.points[19].normal[2] = 0.000000f;
00437 normals.points[20].normal[0] = -0.951057f; normals.points[20].normal[1] = -0.309017f; normals.points[20].normal[2] = 0.000000f;
00438 normals.points[21].normal[0] = 0.951057f; normals.points[21].normal[1] = -0.309017f; normals.points[21].normal[2] = 0.000000f;
00439 normals.points[22].normal[0] = -0.951057f; normals.points[22].normal[1] = 0.309017f; normals.points[22].normal[2] = 0.000000f;
00440 normals.points[23].normal[0] = 0.951057f; normals.points[23].normal[1] = 0.309017f; normals.points[23].normal[2] = 0.000000f;
00441 normals.points[24].normal[0] = -0.587785f; normals.points[24].normal[1] = 0.809017f; normals.points[24].normal[2] = 0.000000f;
00442 normals.points[25].normal[0] = 0.587785f; normals.points[25].normal[1] = 0.809017f; normals.points[25].normal[2] = 0.000000f;
00443 normals.points[26].normal[0] = 0.000000f; normals.points[26].normal[1] = 1.000000f; normals.points[26].normal[2] = 0.000000f;
00444
00445
00446 SampleConsensusModelNormalSpherePtr model (new SampleConsensusModelNormalSphere<PointXYZ, Normal> (cloud.makeShared ()));
00447 model->setInputNormals(normals.makeShared ());
00448
00449
00450 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00451
00452
00453 bool result = sac.computeModel ();
00454 ASSERT_EQ (result, true);
00455
00456 std::vector<int> sample;
00457 sac.getModel (sample);
00458 EXPECT_EQ (int (sample.size ()), 4);
00459
00460 std::vector<int> inliers;
00461 sac.getInliers (inliers);
00462 EXPECT_EQ (int (inliers.size ()), 27);
00463
00464 Eigen::VectorXf coeff;
00465 sac.getModelCoefficients (coeff);
00466 EXPECT_EQ (int (coeff.size ()), 4);
00467 EXPECT_NEAR (coeff[0], 0.0, 1e-2);
00468 EXPECT_NEAR (coeff[1], 0.025, 1e-2);
00469 EXPECT_NEAR (coeff[2], 1.0, 1e-2);
00470 EXPECT_NEAR (coeff[3], 0.05, 1e-2);
00471 Eigen::VectorXf coeff_refined;
00472 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00473 EXPECT_EQ (int (coeff_refined.size ()), 4);
00474 EXPECT_NEAR (coeff_refined[0], 0.0, 1e-2);
00475 EXPECT_NEAR (coeff_refined[1], 0.025, 1e-2);
00476 EXPECT_NEAR (coeff_refined[2], 1.0, 1e-2);
00477 EXPECT_NEAR (coeff_refined[3], 0.05, 1e-2);
00478 }
00480 TEST (RANSAC, SampleConsensusModelCone)
00481 {
00482 srand (0);
00483
00484
00485 PointCloud<PointXYZ> cloud;
00486 PointCloud<Normal> normals;
00487 cloud.points.resize (31); normals.points.resize (31);
00488
00489 cloud.points[0].x = -0.011247f; cloud.points[0].y = 0.200000f; cloud.points[0].z = 0.965384f;
00490 cloud.points[1].x = 0.000000f; cloud.points[1].y = 0.200000f; cloud.points[1].z = 0.963603f;
00491 cloud.points[2].x = 0.011247f; cloud.points[2].y = 0.200000f; cloud.points[2].z = 0.965384f;
00492 cloud.points[3].x = -0.016045f; cloud.points[3].y = 0.175000f; cloud.points[3].z = 0.977916f;
00493 cloud.points[4].x = -0.008435f; cloud.points[4].y = 0.175000f; cloud.points[4].z = 0.974038f;
00494 cloud.points[5].x = 0.004218f; cloud.points[5].y = 0.175000f; cloud.points[5].z = 0.973370f;
00495 cloud.points[6].x = 0.016045f; cloud.points[6].y = 0.175000f; cloud.points[6].z = 0.977916f;
00496 cloud.points[7].x = -0.025420f; cloud.points[7].y = 0.200000f; cloud.points[7].z = 0.974580f;
00497 cloud.points[8].x = 0.025420f; cloud.points[8].y = 0.200000f; cloud.points[8].z = 0.974580f;
00498 cloud.points[9].x = -0.012710f; cloud.points[9].y = 0.150000f; cloud.points[9].z = 0.987290f;
00499 cloud.points[10].x = -0.005624f; cloud.points[10].y = 0.150000f; cloud.points[10].z = 0.982692f;
00500 cloud.points[11].x = 0.002812f; cloud.points[11].y = 0.150000f; cloud.points[11].z = 0.982247f;
00501 cloud.points[12].x = 0.012710f; cloud.points[12].y = 0.150000f; cloud.points[12].z = 0.987290f;
00502 cloud.points[13].x = -0.022084f; cloud.points[13].y = 0.175000f; cloud.points[13].z = 0.983955f;
00503 cloud.points[14].x = 0.022084f; cloud.points[14].y = 0.175000f; cloud.points[14].z = 0.983955f;
00504 cloud.points[15].x = -0.034616f; cloud.points[15].y = 0.200000f; cloud.points[15].z = 0.988753f;
00505 cloud.points[16].x = 0.034616f; cloud.points[16].y = 0.200000f; cloud.points[16].z = 0.988753f;
00506 cloud.points[17].x = -0.006044f; cloud.points[17].y = 0.125000f; cloud.points[17].z = 0.993956f;
00507 cloud.points[18].x = 0.004835f; cloud.points[18].y = 0.125000f; cloud.points[18].z = 0.993345f;
00508 cloud.points[19].x = -0.017308f; cloud.points[19].y = 0.150000f; cloud.points[19].z = 0.994376f;
00509 cloud.points[20].x = 0.017308f; cloud.points[20].y = 0.150000f; cloud.points[20].z = 0.994376f;
00510 cloud.points[21].x = -0.025962f; cloud.points[21].y = 0.175000f; cloud.points[21].z = 0.991565f;
00511 cloud.points[22].x = 0.025962f; cloud.points[22].y = 0.175000f; cloud.points[22].z = 0.991565f;
00512 cloud.points[23].x = -0.009099f; cloud.points[23].y = 0.125000f; cloud.points[23].z = 1.000000f;
00513 cloud.points[24].x = 0.009099f; cloud.points[24].y = 0.125000f; cloud.points[24].z = 1.000000f;
00514 cloud.points[25].x = -0.018199f; cloud.points[25].y = 0.150000f; cloud.points[25].z = 1.000000f;
00515 cloud.points[26].x = 0.018199f; cloud.points[26].y = 0.150000f; cloud.points[26].z = 1.000000f;
00516 cloud.points[27].x = -0.027298f; cloud.points[27].y = 0.175000f; cloud.points[27].z = 1.000000f;
00517 cloud.points[28].x = 0.027298f; cloud.points[28].y = 0.175000f; cloud.points[28].z = 1.000000f;
00518 cloud.points[29].x = -0.036397f; cloud.points[29].y = 0.200000f; cloud.points[29].z = 1.000000f;
00519 cloud.points[30].x = 0.036397f; cloud.points[30].y = 0.200000f; cloud.points[30].z = 1.000000f;
00520
00521 normals.points[0].normal[0] = -0.290381f; normals.points[0].normal[1] = -0.342020f; normals.points[0].normal[2] = -0.893701f;
00522 normals.points[1].normal[0] = 0.000000f; normals.points[1].normal[1] = -0.342020f; normals.points[1].normal[2] = -0.939693f;
00523 normals.points[2].normal[0] = 0.290381f; normals.points[2].normal[1] = -0.342020f; normals.points[2].normal[2] = -0.893701f;
00524 normals.points[3].normal[0] = -0.552338f; normals.points[3].normal[1] = -0.342020f; normals.points[3].normal[2] = -0.760227f;
00525 normals.points[4].normal[0] = -0.290381f; normals.points[4].normal[1] = -0.342020f; normals.points[4].normal[2] = -0.893701f;
00526 normals.points[5].normal[0] = 0.145191f; normals.points[5].normal[1] = -0.342020f; normals.points[5].normal[2] = -0.916697f;
00527 normals.points[6].normal[0] = 0.552337f; normals.points[6].normal[1] = -0.342020f; normals.points[6].normal[2] = -0.760227f;
00528 normals.points[7].normal[0] = -0.656282f; normals.points[7].normal[1] = -0.342020f; normals.points[7].normal[2] = -0.656283f;
00529 normals.points[8].normal[0] = 0.656282f; normals.points[8].normal[1] = -0.342020f; normals.points[8].normal[2] = -0.656283f;
00530 normals.points[9].normal[0] = -0.656283f; normals.points[9].normal[1] = -0.342020f; normals.points[9].normal[2] = -0.656282f;
00531 normals.points[10].normal[0] = -0.290381f; normals.points[10].normal[1] = -0.342020f; normals.points[10].normal[2] = -0.893701f;
00532 normals.points[11].normal[0] = 0.145191f; normals.points[11].normal[1] = -0.342020f; normals.points[11].normal[2] = -0.916697f;
00533 normals.points[12].normal[0] = 0.656282f; normals.points[12].normal[1] = -0.342020f; normals.points[12].normal[2] = -0.656282f;
00534 normals.points[13].normal[0] = -0.760228f; normals.points[13].normal[1] = -0.342020f; normals.points[13].normal[2] = -0.552337f;
00535 normals.points[14].normal[0] = 0.760228f; normals.points[14].normal[1] = -0.342020f; normals.points[14].normal[2] = -0.552337f;
00536 normals.points[15].normal[0] = -0.893701f; normals.points[15].normal[1] = -0.342020f; normals.points[15].normal[2] = -0.290380f;
00537 normals.points[16].normal[0] = 0.893701f; normals.points[16].normal[1] = -0.342020f; normals.points[16].normal[2] = -0.290380f;
00538 normals.points[17].normal[0] = -0.624162f; normals.points[17].normal[1] = -0.342020f; normals.points[17].normal[2] = -0.624162f;
00539 normals.points[18].normal[0] = 0.499329f; normals.points[18].normal[1] = -0.342020f; normals.points[18].normal[2] = -0.687268f;
00540 normals.points[19].normal[0] = -0.893701f; normals.points[19].normal[1] = -0.342020f; normals.points[19].normal[2] = -0.290380f;
00541 normals.points[20].normal[0] = 0.893701f; normals.points[20].normal[1] = -0.342020f; normals.points[20].normal[2] = -0.290380f;
00542 normals.points[21].normal[0] = -0.893701f; normals.points[21].normal[1] = -0.342020f; normals.points[21].normal[2] = -0.290381f;
00543 normals.points[22].normal[0] = 0.893701f; normals.points[22].normal[1] = -0.342020f; normals.points[22].normal[2] = -0.290381f;
00544 normals.points[23].normal[0] = -0.939693f; normals.points[23].normal[1] = -0.342020f; normals.points[23].normal[2] = 0.000000f;
00545 normals.points[24].normal[0] = 0.939693f; normals.points[24].normal[1] = -0.342020f; normals.points[24].normal[2] = 0.000000f;
00546 normals.points[25].normal[0] = -0.939693f; normals.points[25].normal[1] = -0.342020f; normals.points[25].normal[2] = 0.000000f;
00547 normals.points[26].normal[0] = 0.939693f; normals.points[26].normal[1] = -0.342020f; normals.points[26].normal[2] = 0.000000f;
00548 normals.points[27].normal[0] = -0.939693f; normals.points[27].normal[1] = -0.342020f; normals.points[27].normal[2] = 0.000000f;
00549 normals.points[28].normal[0] = 0.939693f; normals.points[28].normal[1] = -0.342020f; normals.points[28].normal[2] = 0.000000f;
00550 normals.points[29].normal[0] = -0.939693f; normals.points[29].normal[1] = -0.342020f; normals.points[29].normal[2] = 0.000000f;
00551 normals.points[30].normal[0] = 0.939693f; normals.points[30].normal[1] = -0.342020f; normals.points[30].normal[2] = 0.000000f;
00552
00553
00554
00555 SampleConsensusModelConePtr model (new SampleConsensusModelCone<PointXYZ, Normal> (cloud.makeShared ()));
00556 model->setInputNormals (normals.makeShared ());
00557
00558
00559 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00560
00561
00562 bool result = sac.computeModel ();
00563 ASSERT_EQ (result, true);
00564
00565 std::vector<int> sample;
00566 sac.getModel (sample);
00567 EXPECT_EQ (int (sample.size ()), 3);
00568
00569 std::vector<int> inliers;
00570 sac.getInliers (inliers);
00571 EXPECT_EQ (int (inliers.size ()), 31);
00572
00573 Eigen::VectorXf coeff;
00574 sac.getModelCoefficients (coeff);
00575 EXPECT_EQ (int (coeff.size ()), 7);
00576 EXPECT_NEAR (coeff[0], 0, 1e-2);
00577 EXPECT_NEAR (coeff[1], 0.1, 1e-2);
00578 EXPECT_NEAR (coeff[6], 0.349066, 1e-2);
00579
00580 Eigen::VectorXf coeff_refined;
00581 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00582 EXPECT_EQ (int (coeff_refined.size ()), 7);
00583 EXPECT_NEAR (coeff_refined[6], 0.349066 , 1e-2);
00584 }
00585
00587 TEST (RANSAC, SampleConsensusModelCylinder)
00588 {
00589 srand (0);
00590
00591
00592 PointCloud<PointXYZ> cloud;
00593 PointCloud<Normal> normals;
00594 cloud.points.resize (20); normals.points.resize (20);
00595
00596 cloud.points[0].x = -0.499902f; cloud.points[0].y = 2.199701f; cloud.points[0].z = 0.000008f;
00597 cloud.points[1].x = -0.875397f; cloud.points[1].y = 2.030177f; cloud.points[1].z = 0.050104f;
00598 cloud.points[2].x = -0.995875f; cloud.points[2].y = 1.635973f; cloud.points[2].z = 0.099846f;
00599 cloud.points[3].x = -0.779523f; cloud.points[3].y = 1.285527f; cloud.points[3].z = 0.149961f;
00600 cloud.points[4].x = -0.373285f; cloud.points[4].y = 1.216488f; cloud.points[4].z = 0.199959f;
00601 cloud.points[5].x = -0.052893f; cloud.points[5].y = 1.475973f; cloud.points[5].z = 0.250101f;
00602 cloud.points[6].x = -0.036558f; cloud.points[6].y = 1.887591f; cloud.points[6].z = 0.299839f;
00603 cloud.points[7].x = -0.335048f; cloud.points[7].y = 2.171994f; cloud.points[7].z = 0.350001f;
00604 cloud.points[8].x = -0.745456f; cloud.points[8].y = 2.135528f; cloud.points[8].z = 0.400072f;
00605 cloud.points[9].x = -0.989282f; cloud.points[9].y = 1.803311f; cloud.points[9].z = 0.449983f;
00606 cloud.points[10].x = -0.900651f; cloud.points[10].y = 1.400701f; cloud.points[10].z = 0.500126f;
00607 cloud.points[11].x = -0.539658f; cloud.points[11].y = 1.201468f; cloud.points[11].z = 0.550079f;
00608 cloud.points[12].x = -0.151875f; cloud.points[12].y = 1.340951f; cloud.points[12].z = 0.599983f;
00609 cloud.points[13].x = -0.000724f; cloud.points[13].y = 1.724373f; cloud.points[13].z = 0.649882f;
00610 cloud.points[14].x = -0.188573f; cloud.points[14].y = 2.090983f; cloud.points[14].z = 0.699854f;
00611 cloud.points[15].x = -0.587925f; cloud.points[15].y = 2.192257f; cloud.points[15].z = 0.749956f;
00612 cloud.points[16].x = -0.927724f; cloud.points[16].y = 1.958846f; cloud.points[16].z = 0.800008f;
00613 cloud.points[17].x = -0.976888f; cloud.points[17].y = 1.549655f; cloud.points[17].z = 0.849970f;
00614 cloud.points[18].x = -0.702003f; cloud.points[18].y = 1.242707f; cloud.points[18].z = 0.899954f;
00615 cloud.points[19].x = -0.289916f; cloud.points[19].y = 1.246296f; cloud.points[19].z = 0.950075f;
00616
00617 normals.points[0].normal[0] = 0.000098f; normals.points[0].normal[1] = 1.000098f; normals.points[0].normal[2] = 0.000008f;
00618 normals.points[1].normal[0] = -0.750891f; normals.points[1].normal[1] = 0.660413f; normals.points[1].normal[2] = 0.000104f;
00619 normals.points[2].normal[0] = -0.991765f; normals.points[2].normal[1] = -0.127949f; normals.points[2].normal[2] = -0.000154f;
00620 normals.points[3].normal[0] = -0.558918f; normals.points[3].normal[1] = -0.829439f; normals.points[3].normal[2] = -0.000039f;
00621 normals.points[4].normal[0] = 0.253627f; normals.points[4].normal[1] = -0.967447f; normals.points[4].normal[2] = -0.000041f;
00622 normals.points[5].normal[0] = 0.894105f; normals.points[5].normal[1] = -0.447965f; normals.points[5].normal[2] = 0.000101f;
00623 normals.points[6].normal[0] = 0.926852f; normals.points[6].normal[1] = 0.375543f; normals.points[6].normal[2] = -0.000161f;
00624 normals.points[7].normal[0] = 0.329948f; normals.points[7].normal[1] = 0.943941f; normals.points[7].normal[2] = 0.000001f;
00625 normals.points[8].normal[0] = -0.490966f; normals.points[8].normal[1] = 0.871203f; normals.points[8].normal[2] = 0.000072f;
00626 normals.points[9].normal[0] = -0.978507f; normals.points[9].normal[1] = 0.206425f; normals.points[9].normal[2] = -0.000017f;
00627 normals.points[10].normal[0] = -0.801227f; normals.points[10].normal[1] = -0.598534f; normals.points[10].normal[2] = 0.000126f;
00628 normals.points[11].normal[0] = -0.079447f; normals.points[11].normal[1] = -0.996697f; normals.points[11].normal[2] = 0.000079f;
00629 normals.points[12].normal[0] = 0.696154f; normals.points[12].normal[1] = -0.717889f; normals.points[12].normal[2] = -0.000017f;
00630 normals.points[13].normal[0] = 0.998685f; normals.points[13].normal[1] = 0.048502f; normals.points[13].normal[2] = -0.000118f;
00631 normals.points[14].normal[0] = 0.622933f; normals.points[14].normal[1] = 0.782133f; normals.points[14].normal[2] = -0.000146f;
00632 normals.points[15].normal[0] = -0.175948f; normals.points[15].normal[1] = 0.984480f; normals.points[15].normal[2] = -0.000044f;
00633 normals.points[16].normal[0] = -0.855476f; normals.points[16].normal[1] = 0.517824f; normals.points[16].normal[2] = 0.000008f;
00634 normals.points[17].normal[0] = -0.953769f; normals.points[17].normal[1] = -0.300571f; normals.points[17].normal[2] = -0.000030f;
00635 normals.points[18].normal[0] = -0.404035f; normals.points[18].normal[1] = -0.914700f; normals.points[18].normal[2] = -0.000046f;
00636 normals.points[19].normal[0] = 0.420154f; normals.points[19].normal[1] = -0.907445f; normals.points[19].normal[2] = 0.000075f;
00637
00638
00639 SampleConsensusModelCylinderPtr model (new SampleConsensusModelCylinder<PointXYZ, Normal> (cloud.makeShared ()));
00640 model->setInputNormals (normals.makeShared ());
00641
00642
00643 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00644
00645
00646 bool result = sac.computeModel ();
00647 ASSERT_EQ (result, true);
00648
00649 std::vector<int> sample;
00650 sac.getModel (sample);
00651 EXPECT_EQ (int (sample.size ()), 2);
00652
00653 std::vector<int> inliers;
00654 sac.getInliers (inliers);
00655 EXPECT_EQ (int (inliers.size ()), 20);
00656
00657 Eigen::VectorXf coeff;
00658 sac.getModelCoefficients (coeff);
00659 EXPECT_EQ (int (coeff.size ()), 7);
00660 EXPECT_NEAR (coeff[0], -0.5, 1e-3);
00661 EXPECT_NEAR (coeff[1], 1.7, 1e-3);
00662 EXPECT_NEAR (coeff[6], 0.5, 1e-3);
00663
00664 Eigen::VectorXf coeff_refined;
00665 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00666 EXPECT_EQ (int (coeff_refined.size ()), 7);
00667 EXPECT_NEAR (coeff_refined[6], 0.5, 1e-3);
00668 }
00669
00671 TEST (RANSAC, SampleConsensusModelCircle2D)
00672 {
00673 srand (0);
00674
00675
00676 PointCloud<PointXYZ> cloud;
00677 cloud.points.resize (18);
00678
00679 cloud.points[0].x = 3.587751f; cloud.points[0].y = -4.190982f; cloud.points[0].z = 0.0f;
00680 cloud.points[1].x = 3.808883f; cloud.points[1].y = -4.412265f; cloud.points[1].z = 0.0f;
00681 cloud.points[2].x = 3.587525f; cloud.points[2].y = -5.809143f; cloud.points[2].z = 0.0f;
00682 cloud.points[3].x = 2.999913f; cloud.points[3].y = -5.999980f; cloud.points[3].z = 0.0f;
00683 cloud.points[4].x = 2.412224f; cloud.points[4].y = -5.809090f; cloud.points[4].z = 0.0f;
00684 cloud.points[5].x = 2.191080f; cloud.points[5].y = -5.587682f; cloud.points[5].z = 0.0f;
00685 cloud.points[6].x = 2.048941f; cloud.points[6].y = -5.309003f; cloud.points[6].z = 0.0f;
00686 cloud.points[7].x = 2.000397f; cloud.points[7].y = -4.999944f; cloud.points[7].z = 0.0f;
00687 cloud.points[8].x = 2.999953f; cloud.points[8].y = -6.000056f; cloud.points[8].z = 0.0f;
00688 cloud.points[9].x = 2.691127f; cloud.points[9].y = -5.951136f; cloud.points[9].z = 0.0f;
00689 cloud.points[10].x = 2.190892f; cloud.points[10].y = -5.587838f; cloud.points[10].z = 0.0f;
00690 cloud.points[11].x = 2.048874f; cloud.points[11].y = -5.309052f; cloud.points[11].z = 0.0f;
00691 cloud.points[12].x = 1.999990f; cloud.points[12].y = -5.000147f; cloud.points[12].z = 0.0f;
00692 cloud.points[13].x = 2.049026f; cloud.points[13].y = -4.690918f; cloud.points[13].z = 0.0f;
00693 cloud.points[14].x = 2.190956f; cloud.points[14].y = -4.412162f; cloud.points[14].z = 0.0f;
00694 cloud.points[15].x = 2.412231f; cloud.points[15].y = -4.190918f; cloud.points[15].z = 0.0f;
00695 cloud.points[16].x = 2.691027f; cloud.points[16].y = -4.049060f; cloud.points[16].z = 0.0f;
00696 cloud.points[17].x = 2.0f; cloud.points[17].y = -3.0f; cloud.points[17].z = 0.0f;
00697
00698
00699 SampleConsensusModelCircle2DPtr model (new SampleConsensusModelCircle2D<PointXYZ> (cloud.makeShared ()));
00700
00701
00702 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00703
00704
00705 bool result = sac.computeModel ();
00706 ASSERT_EQ (result, true);
00707
00708 std::vector<int> sample;
00709 sac.getModel (sample);
00710 EXPECT_EQ (int (sample.size ()), 3);
00711
00712 std::vector<int> inliers;
00713 sac.getInliers (inliers);
00714 EXPECT_EQ (int (inliers.size ()), 17);
00715
00716 Eigen::VectorXf coeff;
00717 sac.getModelCoefficients (coeff);
00718 EXPECT_EQ (int (coeff.size ()), 3);
00719 EXPECT_NEAR (coeff[0], 3, 1e-3);
00720 EXPECT_NEAR (coeff[1], -5, 1e-3);
00721 EXPECT_NEAR (coeff[2], 1, 1e-3);
00722
00723 Eigen::VectorXf coeff_refined;
00724 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00725 EXPECT_EQ (int (coeff_refined.size ()), 3);
00726 EXPECT_NEAR (coeff_refined[0], 3, 1e-3);
00727 EXPECT_NEAR (coeff_refined[1], -5, 1e-3);
00728 EXPECT_NEAR (coeff_refined[2], 1, 1e-3);
00729 }
00730
00732 TEST (RANSAC, SampleConsensusModelLine)
00733 {
00734 srand (0);
00735
00736
00737 PointCloud<PointXYZ> cloud;
00738 cloud.points.resize (10);
00739
00740 cloud.points[0].x = 1.0f; cloud.points[0].y = 2.0f; cloud.points[0].z = 3.0f;
00741 cloud.points[1].x = 4.0f; cloud.points[1].y = 5.0f; cloud.points[1].z = 6.0f;
00742 cloud.points[2].x = 7.0f; cloud.points[2].y = 8.0f; cloud.points[2].z = 9.0f;
00743 cloud.points[3].x = 10.0f; cloud.points[3].y = 11.0f; cloud.points[3].z = 12.0f;
00744 cloud.points[4].x = 13.0f; cloud.points[4].y = 14.0f; cloud.points[4].z = 15.0f;
00745 cloud.points[5].x = 16.0f; cloud.points[5].y = 17.0f; cloud.points[5].z = 18.0f;
00746 cloud.points[6].x = 19.0f; cloud.points[6].y = 20.0f; cloud.points[6].z = 21.0f;
00747 cloud.points[7].x = 22.0f; cloud.points[7].y = 23.0f; cloud.points[7].z = 24.0f;
00748 cloud.points[8].x = -5.0f; cloud.points[8].y = 1.57f; cloud.points[8].z = 0.75f;
00749 cloud.points[9].x = 4.0f; cloud.points[9].y = 2.0f; cloud.points[9].z = 3.0f;
00750
00751
00752 SampleConsensusModelLinePtr model (new SampleConsensusModelLine<PointXYZ> (cloud.makeShared ()));
00753
00754
00755 RandomSampleConsensus<PointXYZ> sac (model, 0.001);
00756
00757
00758 bool result = sac.computeModel ();
00759 ASSERT_EQ (result, true);
00760
00761 std::vector<int> sample;
00762 sac.getModel (sample);
00763 EXPECT_EQ (int (sample.size ()), 2);
00764
00765 std::vector<int> inliers;
00766 sac.getInliers (inliers);
00767 EXPECT_EQ (int (inliers.size ()), 8);
00768
00769 Eigen::VectorXf coeff;
00770 sac.getModelCoefficients (coeff);
00771 EXPECT_EQ (int (coeff.size ()), 6);
00772 EXPECT_NEAR (coeff[4]/coeff[3], 1, 1e-4);
00773 EXPECT_NEAR (coeff[5]/coeff[3], 1, 1e-4);
00774
00775 Eigen::VectorXf coeff_refined;
00776 model->optimizeModelCoefficients (inliers, coeff, coeff_refined);
00777 EXPECT_EQ (int (coeff_refined.size ()), 6);
00778 EXPECT_NEAR (coeff[4]/coeff[3], 1, 1e-4);
00779 EXPECT_NEAR (coeff[5]/coeff[3], 1, 1e-4);
00780
00781
00782 PointCloud<PointXYZ> proj_points;
00783 model->projectPoints (inliers, coeff_refined, proj_points);
00784
00785 EXPECT_NEAR (proj_points.points[2].x, 7.0, 1e-4);
00786 EXPECT_NEAR (proj_points.points[2].y, 8.0, 1e-4);
00787 EXPECT_NEAR (proj_points.points[2].z, 9.0, 1e-4);
00788
00789 EXPECT_NEAR (proj_points.points[3].x, 10.0, 1e-4);
00790 EXPECT_NEAR (proj_points.points[3].y, 11.0, 1e-4);
00791 EXPECT_NEAR (proj_points.points[3].z, 12.0, 1e-4);
00792
00793 EXPECT_NEAR (proj_points.points[5].x, 16.0, 1e-4);
00794 EXPECT_NEAR (proj_points.points[5].y, 17.0, 1e-4);
00795 EXPECT_NEAR (proj_points.points[5].z, 18.0, 1e-4);
00796 }
00797
00799 TEST (RANSAC, SampleConsensusModelNormalPlane)
00800 {
00801 srand (0);
00802
00803 SampleConsensusModelNormalPlanePtr model (new SampleConsensusModelNormalPlane<PointXYZ, Normal> (cloud_));
00804 model->setInputNormals (normals_);
00805 model->setNormalDistanceWeight (0.01);
00806
00807 RandomSampleConsensus<PointXYZ> sac (model, 0.03);
00808
00809 verifyPlaneSac (model, sac);
00810 }
00811
00813
00814 TEST (SAC, InfiniteLoop)
00815 {
00816 const unsigned point_count = 100;
00817 PointCloud<PointXYZ> cloud;
00818 cloud.points.resize (point_count);
00819 for (unsigned pIdx = 0; pIdx < point_count; ++pIdx)
00820 {
00821 cloud.points[pIdx].x = static_cast<float> (pIdx);
00822 cloud.points[pIdx].y = 0.0;
00823 cloud.points[pIdx].z = 0.0;
00824 }
00825
00826 boost::posix_time::time_duration delay(0,0,1,0);
00827 boost::function<bool ()> sac_function;
00828 SampleConsensusModelSpherePtr model (new SampleConsensusModelSphere<PointXYZ> (cloud.makeShared ()));
00829
00830
00831 RandomSampleConsensus<PointXYZ> ransac (model, 0.03);
00832 sac_function = boost::bind (&RandomSampleConsensus<PointXYZ>::computeModel, &ransac, 0);
00833 boost::thread thread1 (sac_function);
00834 ASSERT_TRUE(thread1.timed_join(delay));
00835
00836
00837 LeastMedianSquares<PointXYZ> lmsac (model, 0.03);
00838 sac_function = boost::bind (&LeastMedianSquares<PointXYZ>::computeModel, &lmsac, 0);
00839 boost::thread thread2 (sac_function);
00840 ASSERT_TRUE(thread2.timed_join(delay));
00841
00842
00843 MEstimatorSampleConsensus<PointXYZ> mesac (model, 0.03);
00844 sac_function = boost::bind (&MEstimatorSampleConsensus<PointXYZ>::computeModel, &mesac, 0);
00845 boost::thread thread3 (sac_function);
00846 ASSERT_TRUE(thread3.timed_join(delay));
00847
00848
00849 RandomizedRandomSampleConsensus<PointXYZ> rrsac (model, 0.03);
00850 sac_function = boost::bind (&RandomizedRandomSampleConsensus<PointXYZ>::computeModel, &rrsac, 0);
00851 boost::thread thread4 (sac_function);
00852 ASSERT_TRUE(thread4.timed_join(delay));
00853
00854
00855 RandomizedMEstimatorSampleConsensus<PointXYZ> rmsac (model, 0.03);
00856 sac_function = boost::bind (&RandomizedMEstimatorSampleConsensus<PointXYZ>::computeModel, &rmsac, 0);
00857 boost::thread thread5 (sac_function);
00858 ASSERT_TRUE(thread5.timed_join(delay));
00859
00860
00861 MaximumLikelihoodSampleConsensus<PointXYZ> mlesac (model, 0.03);
00862 sac_function = boost::bind (&MaximumLikelihoodSampleConsensus<PointXYZ>::computeModel, &mlesac, 0);
00863 boost::thread thread6 (sac_function);
00864 ASSERT_TRUE(thread6.timed_join(delay));
00865 }
00866
00867
00868 int
00869 main (int argc, char** argv)
00870 {
00871 if (argc < 2)
00872 {
00873 std::cerr << "No test file given. Please download `sac_plane_test.pcd` and pass its path to the test." << std::endl;
00874 return (-1);
00875 }
00876
00877
00878 sensor_msgs::PointCloud2 cloud_blob;
00879 if (loadPCDFile (argv[1], cloud_blob) < 0)
00880 {
00881 std::cerr << "Failed to read test file. Please download `sac_plane_test.pcd` and pass its path to the test." << std::endl;
00882 return (-1);
00883 }
00884 fromROSMsg (cloud_blob, *cloud_);
00885
00886 indices_.resize (cloud_->points.size ());
00887 for (size_t i = 0; i < indices_.size (); ++i) { indices_[i] = int (i); }
00888
00889
00890 NormalEstimation<PointXYZ, Normal> n;
00891 search::Search<PointXYZ>::Ptr tree (new search::KdTree<PointXYZ>);
00892 tree->setInputCloud (cloud_);
00893 n.setInputCloud (cloud_);
00894 boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices_));
00895 n.setIndices (indicesptr);
00896 n.setSearchMethod (tree);
00897 n.setRadiusSearch (0.02);
00898 n.compute (*normals_);
00899
00900 testing::InitGoogleTest (&argc, argv);
00901 return (RUN_ALL_TESTS ());
00902 }
00903