https://github.com/MNewBie/PCL-Notes/blob/master/chapter12.md

    该代码中完成了提取关键点、特征描述、计算匹配对与旋转平移矩阵、显示等操作。

    1. #include <pcl/io/pcd_io.h>
    2. #include <pcl/point_types.h>
    3. // 包含相关头文件
    4. #include <pcl/keypoints/harris_3d.h>
    5. #include <pcl/features/normal_3d.h>
    6. #include <pcl/features/shot.h>
    7. #include <pcl/registration/correspondence_estimation.h>
    8. #include <pcl/visualization/pcl_visualizer.h>
    9. /*
    10. #include <pcl/common/transforms.h>
    11. #include <pcl/registration/transformation_estimation_svd.h>
    12. */
    13. #include "resolution.h" // 用于计算模型分辨率
    14. #include "getTransformation.h" //计算旋转平移矩阵
    15. typedef pcl::PointXYZ PointT;
    16. typedef pcl::Normal PointNT;
    17. typedef pcl::SHOT352 FeatureT;
    18. // 获取Harris关键点
    19. void getHarrisKeyPoints(const pcl::PointCloud<PointT>::Ptr &cloud, double resolution,
    20. pcl::PointCloud<PointT>::Ptr &keys)
    21. {
    22. pcl::HarrisKeypoint3D<PointT, pcl::PointXYZI> detector;
    23. pcl::PointCloud<pcl::PointXYZI>::Ptr keypoints_temp(new pcl::PointCloud<pcl::PointXYZI>);
    24. detector.setNonMaxSupression(true);
    25. detector.setRadiusSearch(10 * resolution);
    26. detector.setThreshold(1E-6);
    27. detector.setInputCloud(cloud);
    28. detector.compute(*keypoints_temp);
    29. pcl::console::print_highlight("Detected %d points !\n", keypoints_temp->size());
    30. pcl::copyPointCloud(*keypoints_temp, *keys);
    31. }
    32. void getFeatures(const pcl::PointCloud<PointT>::Ptr &cloud, const pcl::PointCloud<PointT>::Ptr &keys,
    33. double resolution, pcl::PointCloud<FeatureT>::Ptr features)
    34. {
    35. // 法向量
    36. pcl::NormalEstimation<PointT, PointNT> nest;
    37. nest.setKSearch(10);
    38. pcl::PointCloud<PointNT>::Ptr cloud_normal(new pcl::PointCloud<PointNT>);
    39. nest.setInputCloud(cloud);
    40. nest.setSearchSurface(cloud);
    41. nest.compute(*cloud_normal);
    42. std::cout << "compute normal\n";
    43. pcl::SHOTEstimation<PointT, PointNT, FeatureT> shot;
    44. shot.setRadiusSearch(18 * resolution);
    45. shot.setInputCloud(keys);
    46. shot.setSearchSurface(cloud);
    47. shot.setInputNormals(cloud_normal);
    48. shot.compute(*features);
    49. std::cout << "compute feature\n";
    50. }
    51. int main(int argc, char** argv)
    52. {
    53. // 读取点云
    54. pcl::PointCloud<PointT>::Ptr cloud_src(new pcl::PointCloud<PointT>);
    55. pcl::io::loadPCDFile(argv[1], *cloud_src);
    56. pcl::PointCloud<PointT>::Ptr cloud_tgt(new pcl::PointCloud<PointT>);
    57. pcl::io::loadPCDFile(argv[2], *cloud_tgt);
    58. // 计算模型分辨率
    59. double resolution = computeCloudResolution(cloud_src);
    60. // 提取关键点
    61. pcl::PointCloud<PointT>::Ptr keys_src(new pcl::PointCloud<pcl::PointXYZ>);
    62. getHarrisKeyPoints(cloud_src, resolution, keys_src);
    63. pcl::PointCloud<PointT>::Ptr keys_tgt(new pcl::PointCloud<pcl::PointXYZ>);
    64. getHarrisKeyPoints(cloud_tgt, resolution, keys_tgt);
    65. // 特征描述
    66. pcl::PointCloud<FeatureT>::Ptr features_src(new pcl::PointCloud<FeatureT>);
    67. getFeatures(cloud_src, keys_src, resolution, features_src);
    68. pcl::PointCloud<FeatureT>::Ptr features_tgt(new pcl::PointCloud<FeatureT>);
    69. getFeatures(cloud_tgt, keys_tgt, resolution, features_tgt);
    70. // 计算对应匹配关系
    71. pcl::registration::CorrespondenceEstimation<FeatureT, FeatureT> cor_est;
    72. cor_est.setInputCloud(features_src);
    73. cor_est.setInputTarget(features_tgt);
    74. boost::shared_ptr<pcl::Correspondences> cor(new pcl::Correspondences);
    75. cor_est.determineReciprocalCorrespondences(*cor);
    76. std::cout << "compute Correspondences " << cor->size() << std::endl;
    77. // 计算旋转平移矩阵
    78. Eigen::Matrix4f transformation(Eigen::Matrix4f::Identity());
    79. getTransformation(keys_src,keys_tgt, resolution, *cor, transformation);
    80. /*
    81. // 也可以不用关键点对应关系直接获取旋转平移矩阵
    82. Eigen::Matrix4f transformation(Eigen::Matrix4f::Identity());
    83. pcl::registration::TransformationEstimationSVD<pcl::PointXYZ, pcl::PointXYZ> svd;
    84. svd.estimateRigidTransformation(*cloud_src, *cloud_tgt, transformation);
    85. */
    86. // 显示
    87. pcl::visualization::PCLVisualizer viewer;
    88. viewer.addPointCloud(cloud_src, "cloud_src"); // 显示点云
    89. viewer.addPointCloud(cloud_tgt, "cloud_tgt");
    90. pcl::visualization::PointCloudColorHandlerCustom<PointT> red_src(keys_src, 255, 0, 0);
    91. pcl::visualization::PointCloudColorHandlerCustom<PointT> red_tgt(keys_tgt, 255, 0, 0);
    92. viewer.addPointCloud(keys_src, red_src, "keys_src"); //显示关键点,红色,加粗
    93. viewer.addPointCloud(keys_tgt, red_tgt, "keys_tgt");
    94. viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "keys_src");
    95. viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "keys_tgt");
    96. for (size_t i = 0; i < cor->size(); ++i) // 显示关键点匹配关系
    97. {
    98. PointT temp1 = keys_src->points[cor->at(i).index_query];
    99. PointT temp2 = keys_tgt->points[cor->at(i).index_match];
    100. std::stringstream ss;
    101. ss << "line_" << i;
    102. viewer.addLine(temp1, temp2, ss.str());
    103. }
    104. pcl::PointCloud<PointT>::Ptr cloud_trans(new pcl::PointCloud<pcl::PointXYZ>);
    105. pcl::transformPointCloud(*cloud_src, *cloud_trans, transformation); // 将原点云旋转
    106. pcl::visualization::PointCloudColorHandlerCustom<PointT> green_trans(cloud_trans, 0, 255, 0);
    107. viewer.addPointCloud(cloud_trans, green_trans, "cloud_trans");
    108. viewer.spin();
    109. system("pause");
    110. return 0;
    111. }