00001 #include <fstream>
00002 #include <ros/ros.h>
00003 #include <pcl/io/pcd_io.h>
00004 #include <pcl/point_types.h>
00005
00006 #include <pcl/registration/correspondence_estimation.h>
00007
00008 #include <pcl/registration/correspondence_rejection_distance.h>
00009 #include <pcl/registration/correspondence_rejection_trimmed.h>
00010 #include <pcl/registration/correspondence_rejection_one_to_one.h>
00011 #include <pcl/registration/correspondence_rejection_reciprocal.h>
00012 #include <pcl/registration/correspondence_rejection_sample_consensuns.h>
00013
00014 #include <pcl/registration/transformation_estimation_svd.h>
00015
00016 typedef pcl::PointXYZ Point;
00017 typedef pcl::PointCloud<Point> PointCloud;
00018 typedef pcl::registration::Correspondence Correspondence;
00019
00020
00021 int main(int argc, char** argv)
00022 {
00023 if (argc != 3)
00024 {
00025 ROS_ERROR ("Syntax is: %s <source.pcd> <target.pcd>", argv[0]);
00026 ROS_INFO ("Example: %s `rospack find pcl`/test/bun0.pcd `rospack find pcl`/test/bun4.pcd", argv[0]);
00027 return (-1);
00028 }
00029
00030 ros::init (argc, argv, "pcd_inc_reg");
00031 ros::Time::init();
00032
00033 PointCloud cloud_input, cloud_target;
00034 pcl::io::loadPCDFile(argv[1], cloud_input);
00035 pcl::io::loadPCDFile(argv[2], cloud_target);
00036
00037 PointCloud::ConstPtr input_cloud_ptr = cloud_input.makeShared();
00038 PointCloud::ConstPtr target_cloud_ptr = cloud_target.makeShared();
00039
00040
00042
00043 float registration_distance_threshold = 0.01;
00044 std::vector<Correspondence> correspondences;
00045 pcl::registration::CorrespondenceEstimation<Point, Point> corr_est;
00046 corr_est.setInputTarget(target_cloud_ptr);
00047 corr_est.setMaxCorrespondenceDistance(registration_distance_threshold);
00048 corr_est.setInputCloud(input_cloud_ptr);
00049 corr_est.determineCorrespondences(correspondences);
00050 printf("%d\t original correspondences\n", (int)correspondences.size());
00051
00052 pcl::registration::CorrespondencesConstPtr correspondences_ptr = boost::make_shared< const std::vector<pcl::registration::Correspondence> >(correspondences);
00053
00054 std::vector<Correspondence> correspondeces_reciprocal;
00055 corr_est.determineReciprocalCorrespondences(correspondeces_reciprocal);
00056 printf("%d\t reciprocal correspondences\n", (int)correspondeces_reciprocal.size());
00057
00058
00060
00061
00062 float max_cor_dist = 0.0001;
00063 std::vector<Correspondence> correspondeces_dist;
00064 pcl::registration::CorrespondenceRejectorDistance cor_rej_dist;
00065 cor_rej_dist.setMaximumDistance(0.0001);
00066 cor_rej_dist.setInputCorrespondences(correspondences_ptr);
00067 cor_rej_dist.getCorrespondeces(correspondeces_dist);
00068 printf("%d\t filtered correspondences (max_cost_dist=%0.4f)\n", (int)correspondeces_dist.size(), max_cor_dist);
00069
00070 float ratio = 0.5;
00071 std::vector<Correspondence> correspondeces_trimmed;
00072 pcl::registration::CorrespondenceRejectorTrimmed cor_rej_trimmed;
00073 cor_rej_trimmed.setOverlapRadio(ratio);
00074 cor_rej_trimmed.setInputCorrespondences(correspondences_ptr);
00075 cor_rej_trimmed.getCorrespondeces(correspondeces_trimmed);
00076 printf("%d\t trimmed correspondences (ratio=%0.4f)\n", (int)correspondeces_trimmed.size(), ratio);
00077
00078 std::vector<Correspondence> correspondeces_one_to_one;
00079 pcl::registration::CorrespondenceRejectorOneToOne cor_rej_one_to_one;
00080 cor_rej_one_to_one.setInputCorrespondences(correspondences_ptr);
00081 cor_rej_one_to_one.getCorrespondeces(correspondeces_one_to_one);
00082 printf("%d\t ono-to-one correspondences\n", (int)correspondeces_one_to_one.size());
00083
00084
00085 double sac_threshold = 0.005;
00086 int sac_max_iterations = 100;
00087 std::vector<pcl::registration::Correspondence> correspondeces_sac;
00088 pcl::registration::CorrespondenceRejectorSampleConsensus<Point> cor_rej_sac;
00089 cor_rej_sac.setInputCloud(input_cloud_ptr);
00090 cor_rej_sac.setTargetCloud(target_cloud_ptr);
00091 cor_rej_sac.setInlierThreshold(sac_threshold);
00092 cor_rej_sac.setMaxIterations(sac_max_iterations);
00093 cor_rej_sac.setInputCorrespondences(correspondences_ptr);
00094 cor_rej_sac.getCorrespondeces(correspondeces_sac);
00095
00096 printf("%d\t correspondences after SAC rejection\n", (int)correspondeces_sac.size());
00097
00098 Eigen::Matrix4f transform_sac = cor_rej_sac.getBestTransformation();
00099
00100 std::vector<int> indices_not_corresponding;
00101 cor_rej_sac.getRejectedQueryIndices(correspondeces_sac, indices_not_corresponding);
00102 printf("%d\t correspondences rejected by SAC\n", (int)indices_not_corresponding.size());
00103
00104
00105 pcl::registration::TransformationEstimationSVD<Point, Point> trans_est;
00106 Eigen::Matrix4f transform_svd;
00107 trans_est.estimateRigidTransformation(cloud_input, cloud_target, correspondeces_sac, transform_svd);
00108
00109 std::cout << "Transform from SAC:" << std::endl;
00110 std::cout << transform_sac << std::endl;
00111 std::cout << "Transform from SVD:" << std::endl;
00112 std::cout << transform_svd << std::endl;
00113
00114
00115
00116
00118
00119 std::ofstream file_output;
00120
00121 file_output.open("correspondences_original.dat");
00122 for (unsigned int i = 0; i < correspondences.size(); ++i)
00123 file_output << correspondences[i] << std::endl;
00124 file_output.close();
00125
00126 file_output.open("correspondences_dist.dat");
00127 for (unsigned int i = 0; i < correspondeces_dist.size(); ++i)
00128 file_output << correspondeces_dist[i] << std::endl;
00129 file_output.close();
00130
00131 file_output.open("correspondences_trimmed.dat");
00132 for (unsigned int i = 0; i < correspondeces_trimmed.size(); ++i)
00133 file_output << correspondeces_trimmed[i] << std::endl;
00134 file_output.close();
00135
00136 file_output.open("correspondences_one_to_one.dat");
00137 for (unsigned int i = 0; i < correspondeces_one_to_one.size(); ++i)
00138 file_output << correspondeces_one_to_one[i] << std::endl;
00139 file_output.close();
00140
00141 file_output.open("correspondences_reciprocal.dat");
00142 for (unsigned int i = 0; i < correspondeces_reciprocal.size(); ++i)
00143 file_output << correspondeces_reciprocal[i] << std::endl;
00144 file_output.close();
00145
00146 return 0;
00147 }