00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <gtest/gtest.h>
00041
00042 #include <pcl/point_types.h>
00043 #include <pcl/io/pcd_io.h>
00044 #include <pcl/registration/correspondence_estimation.h>
00045 #include <pcl/registration/correspondence_rejection_distance.h>
00046 #include <pcl/registration/correspondence_rejection_median_distance.h>
00047 #include <pcl/registration/correspondence_rejection_surface_normal.h>
00048 #include <pcl/registration/correspondence_rejection.h>
00049 #include <pcl/registration/correspondence_rejection_one_to_one.h>
00050 #include <pcl/registration/correspondence_rejection_sample_consensus.h>
00051 #include <pcl/registration/correspondence_rejection_trimmed.h>
00052 #include <pcl/registration/correspondence_rejection_var_trimmed.h>
00053 #include <pcl/registration/transformation_estimation_lm.h>
00054 #include <pcl/registration/transformation_estimation_svd.h>
00055 #include <pcl/features/normal_3d.h>
00056
00057 #include "test_registration_api_data.h"
00058
00059 pcl::PointCloud<pcl::PointXYZ> cloud_source, cloud_target, cloud_reg;
00060
00062 TEST (PCL, CorrespondenceEstimation)
00063 {
00064 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00065 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00066
00067 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00068 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00069 corr_est.setInputCloud (source);
00070 corr_est.setInputTarget (target);
00071 corr_est.determineCorrespondences (*correspondences);
00072
00073
00074 EXPECT_EQ (int (correspondences->size ()), nr_original_correspondences);
00075 if (int (correspondences->size ()) == nr_original_correspondences)
00076 {
00077 for (int i = 0; i < nr_original_correspondences; ++i)
00078 EXPECT_EQ ((*correspondences)[i].index_query, i);
00079
00080
00081 for (int i = 0; i < nr_original_correspondences; ++i)
00082 EXPECT_EQ ((*correspondences)[i].index_match, correspondences_original[i][1]);
00083 }
00084 }
00085
00087 TEST (PCL, CorrespondenceEstimationReciprocal)
00088 {
00089 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00090 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00091
00092 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00093 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00094 corr_est.setInputCloud (source);
00095 corr_est.setInputTarget (target);
00096 corr_est.determineReciprocalCorrespondences (*correspondences);
00097
00098
00099 EXPECT_EQ (int (correspondences->size ()), nr_reciprocal_correspondences);
00100 if (int (correspondences->size ()) == nr_reciprocal_correspondences)
00101 for (int i = 0; i < nr_reciprocal_correspondences; ++i)
00102 EXPECT_EQ ((*correspondences)[i].index_match, correspondences_reciprocal[i][1]);
00103 }
00104
00106 TEST (PCL, CorrespondenceRejectorDistance)
00107 {
00108 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00109 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00110
00111
00112 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00113 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00114 corr_est.setInputCloud (source);
00115 corr_est.setInputTarget (target);
00116 corr_est.determineCorrespondences (*correspondences);
00117
00118 boost::shared_ptr<pcl::Correspondences> correspondences_result_rej_dist (new pcl::Correspondences);
00119 pcl::registration::CorrespondenceRejectorDistance corr_rej_dist;
00120 corr_rej_dist.setInputCorrespondences(correspondences);
00121 corr_rej_dist.setMaximumDistance(rej_dist_max_dist);
00122 corr_rej_dist.getCorrespondences(*correspondences_result_rej_dist);
00123
00124
00125 EXPECT_EQ (int (correspondences_result_rej_dist->size ()), nr_correspondences_result_rej_dist);
00126 if (int (correspondences_result_rej_dist->size ()) == nr_correspondences_result_rej_dist)
00127 for (int i = 0; i < nr_correspondences_result_rej_dist; ++i)
00128 EXPECT_EQ ((*correspondences_result_rej_dist)[i].index_match, correspondences_dist[i][1]);
00129 }
00130
00132 TEST (PCL, CorrespondenceRejectorOneToOne)
00133 {
00134 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00135 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00136
00137
00138 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00139 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00140 corr_est.setInputCloud (source);
00141 corr_est.setInputTarget (target);
00142 corr_est.determineCorrespondences (*correspondences);
00143
00144 boost::shared_ptr<pcl::Correspondences> correspondences_result_rej_one_to_one (new pcl::Correspondences);
00145 pcl::registration::CorrespondenceRejectorOneToOne corr_rej_one_to_one;
00146 corr_rej_one_to_one.setInputCorrespondences(correspondences);
00147 corr_rej_one_to_one.getCorrespondences(*correspondences_result_rej_one_to_one);
00148
00149
00150 EXPECT_EQ (int (correspondences_result_rej_one_to_one->size ()), nr_correspondences_result_rej_one_to_one);
00151 if (int (correspondences_result_rej_one_to_one->size ()) == nr_correspondences_result_rej_one_to_one)
00152 for (int i = 0; i < nr_correspondences_result_rej_one_to_one; ++i)
00153 EXPECT_EQ ((*correspondences_result_rej_one_to_one)[i].index_match, correspondences_one_to_one[i][1]);
00154 }
00155
00157 TEST (PCL, CorrespondenceRejectorSampleConsensus)
00158 {
00159 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00160 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00161
00162
00163 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00164 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00165 corr_est.setInputCloud (source);
00166 corr_est.setInputTarget (target);
00167 corr_est.determineCorrespondences (*correspondences);
00168 EXPECT_EQ (int (correspondences->size ()), nr_original_correspondences);
00169
00170 boost::shared_ptr<pcl::Correspondences> correspondences_result_rej_sac (new pcl::Correspondences);
00171 pcl::registration::CorrespondenceRejectorSampleConsensus<pcl::PointXYZ> corr_rej_sac;
00172 corr_rej_sac.setInputCloud (source);
00173 corr_rej_sac.setTargetCloud (target);
00174 corr_rej_sac.setInlierThreshold (rej_sac_max_dist);
00175 corr_rej_sac.setMaxIterations (rej_sac_max_iter);
00176 corr_rej_sac.setInputCorrespondences (correspondences);
00177 corr_rej_sac.getCorrespondences (*correspondences_result_rej_sac);
00178 Eigen::Matrix4f transform_res_from_SAC = corr_rej_sac.getBestTransformation ();
00179
00180
00181 EXPECT_EQ (int (correspondences_result_rej_sac->size ()), nr_correspondences_result_rej_sac);
00182 if (int (correspondences_result_rej_sac->size ()) == nr_correspondences_result_rej_sac)
00183 for (int i = 0; i < nr_correspondences_result_rej_sac; ++i)
00184 EXPECT_EQ ((*correspondences_result_rej_sac)[i].index_match, correspondences_sac[i][1]);
00185
00186
00187 for (int i = 0; i < 4; ++i)
00188 for (int j = 0; j < 4; ++j)
00189 EXPECT_NEAR (transform_res_from_SAC (i, j), transform_from_SAC[i][j], 1e-4);
00190 }
00191
00193 TEST (PCL, CorrespondenceRejectorSurfaceNormal)
00194 {
00195 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00196 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00197
00198
00199 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00200 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00201 corr_est.setInputCloud (source);
00202 corr_est.setInputTarget (target);
00203 corr_est.determineCorrespondences (*correspondences);
00204
00205
00206 pcl::PointCloud<pcl::PointNormal>::Ptr source_normals(new pcl::PointCloud<pcl::PointNormal>);
00207 pcl::copyPointCloud(*source, *source_normals);
00208 pcl::PointCloud<pcl::PointNormal>::Ptr target_normals(new pcl::PointCloud<pcl::PointNormal>);
00209 pcl::copyPointCloud(*target, *target_normals);
00210
00211 pcl::NormalEstimation<pcl::PointNormal, pcl::PointNormal> norm_est_src;
00212 norm_est_src.setSearchMethod (pcl::search::KdTree<pcl::PointNormal>::Ptr (new pcl::search::KdTree<pcl::PointNormal>));
00213 norm_est_src.setKSearch (10);
00214 norm_est_src.setInputCloud (source_normals);
00215 norm_est_src.compute (*source_normals);
00216
00217 pcl::NormalEstimation<pcl::PointNormal, pcl::PointNormal> norm_est_tgt;
00218 norm_est_tgt.setSearchMethod (pcl::search::KdTree<pcl::PointNormal>::Ptr (new pcl::search::KdTree<pcl::PointNormal>));
00219 norm_est_tgt.setKSearch (10);
00220 norm_est_tgt.setInputCloud (target_normals);
00221 norm_est_tgt.compute (*target_normals);
00222
00223 pcl::registration::CorrespondenceRejectorSurfaceNormal corr_rej_surf_norm;
00224 corr_rej_surf_norm.initializeDataContainer <pcl::PointXYZ, pcl::PointNormal> ();
00225 corr_rej_surf_norm.setInputCloud <pcl::PointXYZ> (source);
00226 corr_rej_surf_norm.setInputTarget <pcl::PointXYZ> (target);
00227 corr_rej_surf_norm.setInputNormals <pcl::PointXYZ, pcl::PointNormal> (source_normals);
00228 corr_rej_surf_norm.setTargetNormals <pcl::PointXYZ, pcl::PointNormal> (target_normals);
00229
00230 boost::shared_ptr<pcl::Correspondences> correspondences_result_rej_surf_norm (new pcl::Correspondences);
00231 corr_rej_surf_norm.setInputCorrespondences (correspondences);
00232 corr_rej_surf_norm.setThreshold (0.5);
00233
00234 corr_rej_surf_norm.getCorrespondences (*correspondences_result_rej_surf_norm);
00235
00236
00237 if (int (correspondences_result_rej_surf_norm->size ()) == nr_correspondences_result_rej_dist)
00238 for (int i = 0; i < nr_correspondences_result_rej_dist; ++i)
00239 EXPECT_EQ ((*correspondences_result_rej_surf_norm)[i].index_match, correspondences_dist[i][1]);
00240 }
00242 TEST (PCL, CorrespondenceRejectorTrimmed)
00243 {
00244 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00245 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00246
00247
00248 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00249 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00250 corr_est.setInputCloud (source);
00251 corr_est.setInputTarget (target);
00252 corr_est.determineCorrespondences (*correspondences);
00253
00254 boost::shared_ptr<pcl::Correspondences> correspondences_result_rej_trimmed (new pcl::Correspondences);
00255 pcl::registration::CorrespondenceRejectorTrimmed corr_rej_trimmed;
00256 corr_rej_trimmed.setOverlapRadio(rej_trimmed_overlap);
00257 corr_rej_trimmed.setInputCorrespondences(correspondences);
00258 corr_rej_trimmed.getCorrespondences(*correspondences_result_rej_trimmed);
00259
00260
00261 EXPECT_EQ (int (correspondences_result_rej_trimmed->size ()), nr_correspondences_result_rej_trimmed);
00262 if (int (correspondences_result_rej_trimmed->size ()) == nr_correspondences_result_rej_trimmed)
00263 {
00264 for (int i = 0; i < nr_correspondences_result_rej_trimmed; ++i)
00265 EXPECT_EQ ((*correspondences_result_rej_trimmed)[i].index_query, correspondences_trimmed[i][0]);
00266 for (int i = 0; i < nr_correspondences_result_rej_trimmed; ++i)
00267 EXPECT_EQ ((*correspondences_result_rej_trimmed)[i].index_match, correspondences_trimmed[i][1]);
00268 }
00269 }
00270
00272 TEST (PCL, CorrespondenceRejectorVarTrimmed)
00273 {
00274 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00275 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00276
00277
00278 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00279 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00280 corr_est.setInputCloud (source);
00281 corr_est.setInputTarget (target);
00282 corr_est.determineCorrespondences (*correspondences);
00283
00284 boost::shared_ptr<pcl::Correspondences> correspondences_result_rej_var_trimmed_dist (new pcl::Correspondences);
00285 pcl::registration::CorrespondenceRejectorVarTrimmed corr_rej_var_trimmed_dist;
00286 corr_rej_var_trimmed_dist.setInputCloud<pcl::PointXYZ> (source);
00287 corr_rej_var_trimmed_dist.setInputTarget<pcl::PointXYZ> (target);
00288 corr_rej_var_trimmed_dist.setInputCorrespondences(correspondences);
00289
00290 corr_rej_var_trimmed_dist.getCorrespondences(*correspondences_result_rej_var_trimmed_dist);
00291
00292
00293 if (int (correspondences_result_rej_var_trimmed_dist->size ()) == nr_correspondences_result_rej_dist)
00294 for (int i = 0; i < nr_correspondences_result_rej_dist; ++i)
00295 EXPECT_EQ ((*correspondences_result_rej_var_trimmed_dist)[i].index_match, correspondences_dist[i][1]);
00296 }
00297
00299 TEST (PCL, TransformationEstimationSVD)
00300 {
00301 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00302 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00303
00304
00305 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00306 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00307 corr_est.setInputCloud (source);
00308 corr_est.setInputTarget (target);
00309 corr_est.determineReciprocalCorrespondences (*correspondences);
00310
00311 Eigen::Matrix4f transform_res_from_SVD;
00312 pcl::registration::TransformationEstimationSVD<pcl::PointXYZ, pcl::PointXYZ> trans_est_svd;
00313 trans_est_svd.estimateRigidTransformation(*source, *target,
00314 *correspondences,
00315 transform_res_from_SVD);
00316
00317
00318 for (int i = 0; i < 4; ++i)
00319 for (int j = 0; j < 4; ++j)
00320 EXPECT_NEAR (transform_res_from_SVD(i, j), transform_from_SVD[i][j], 1e-4);
00321 }
00322
00324 TEST (PCL, TransformationEstimationLM)
00325 {
00326 pcl::PointCloud<pcl::PointXYZ>::Ptr source (new pcl::PointCloud<pcl::PointXYZ>(cloud_source));
00327 pcl::PointCloud<pcl::PointXYZ>::Ptr target (new pcl::PointCloud<pcl::PointXYZ>(cloud_target));
00328
00329
00330 boost::shared_ptr<pcl::Correspondences> correspondences (new pcl::Correspondences);
00331 pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;
00332 corr_est.setInputCloud (source);
00333 corr_est.setInputTarget (target);
00334 corr_est.determineReciprocalCorrespondences (*correspondences);
00335
00336 Eigen::Matrix4f transform_res_from_LM;
00337 pcl::registration::TransformationEstimationLM<pcl::PointXYZ, pcl::PointXYZ> trans_est_lm;
00338 trans_est_lm.estimateRigidTransformation (*source, *target,
00339 *correspondences,
00340 transform_res_from_LM);
00341
00342
00343 EXPECT_EQ (int (correspondences->size ()), nr_reciprocal_correspondences);
00344 for (int i = 0; i < nr_reciprocal_correspondences; ++i)
00345 {
00346 EXPECT_EQ ((*correspondences)[i].index_query, correspondences_reciprocal[i][0]);
00347 EXPECT_EQ ((*correspondences)[i].index_match, correspondences_reciprocal[i][1]);
00348 }
00349
00350
00351
00352
00353
00354 }
00355
00356
00357 int
00358 main (int argc, char** argv)
00359 {
00360 if (argc < 3)
00361 {
00362 std::cerr << "No test files given. Please download `bun0.pcd` and `bun4.pcd` and pass their path to the test." << std::endl;
00363 return (-1);
00364 }
00365
00366
00367 if (pcl::io::loadPCDFile (argv[1], cloud_source) < 0)
00368 {
00369 std::cerr << "Failed to read test file. Please download `bun0.pcd` and pass its path to the test." << std::endl;
00370 return (-1);
00371 }
00372 if (pcl::io::loadPCDFile (argv[2], cloud_target) < 0)
00373 {
00374 std::cerr << "Failed to read test file. Please download `bun4.pcd` and pass its path to the test." << std::endl;
00375 return (-1);
00376 }
00377
00378 testing::InitGoogleTest (&argc, argv);
00379 return (RUN_ALL_TESTS ());
00380
00381
00382
00383
00384
00385
00386 }
00387