一个完整的实例

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

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
// 包含相关头文件
#include <pcl/keypoints/harris_3d.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/shot.h>
#include <pcl/registration/correspondence_estimation.h>
#include <pcl/visualization/pcl_visualizer.h>
/*
#include <pcl/common/transforms.h>
#include <pcl/registration/transformation_estimation_svd.h>
*/
#include "resolution.h" // 用于计算模型分辨率
#include "getTransformation.h" //计算旋转平移矩阵

typedef pcl::PointXYZ PointT;
typedef pcl::Normal PointNT;
typedef pcl::SHOT352 FeatureT;

// 获取Harris关键点
void getHarrisKeyPoints(const pcl::PointCloud<PointT>::Ptr &cloud, double resolution, 
    pcl::PointCloud<PointT>::Ptr &keys)
{
    pcl::HarrisKeypoint3D<PointT, pcl::PointXYZI> detector;
    pcl::PointCloud<pcl::PointXYZI>::Ptr keypoints_temp(new pcl::PointCloud<pcl::PointXYZI>);
    detector.setNonMaxSupression(true);
    detector.setRadiusSearch(10 * resolution);
    detector.setThreshold(1E-6);
    detector.setInputCloud(cloud);
    detector.compute(*keypoints_temp);
    pcl::console::print_highlight("Detected %d points !\n", keypoints_temp->size());
    pcl::copyPointCloud(*keypoints_temp, *keys);
}

void getFeatures(const pcl::PointCloud<PointT>::Ptr &cloud, const pcl::PointCloud<PointT>::Ptr &keys,
    double resolution, pcl::PointCloud<FeatureT>::Ptr features)
{
    // 法向量
    pcl::NormalEstimation<PointT, PointNT> nest;
    nest.setKSearch(10);
    pcl::PointCloud<PointNT>::Ptr cloud_normal(new pcl::PointCloud<PointNT>);
    nest.setInputCloud(cloud);
    nest.setSearchSurface(cloud);
    nest.compute(*cloud_normal);
    std::cout << "compute normal\n";

    pcl::SHOTEstimation<PointT, PointNT, FeatureT> shot;
    shot.setRadiusSearch(18 * resolution);
    shot.setInputCloud(keys);
    shot.setSearchSurface(cloud);
    shot.setInputNormals(cloud_normal);
    shot.compute(*features);
    std::cout << "compute feature\n";
}

int main(int argc, char** argv)
{
    // 读取点云
    pcl::PointCloud<PointT>::Ptr cloud_src(new pcl::PointCloud<PointT>);
    pcl::io::loadPCDFile(argv[1], *cloud_src);

    pcl::PointCloud<PointT>::Ptr cloud_tgt(new pcl::PointCloud<PointT>);
    pcl::io::loadPCDFile(argv[2], *cloud_tgt);

    // 计算模型分辨率
    double resolution = computeCloudResolution(cloud_src);

    // 提取关键点
    pcl::PointCloud<PointT>::Ptr keys_src(new pcl::PointCloud<pcl::PointXYZ>);
    getHarrisKeyPoints(cloud_src, resolution, keys_src);

    pcl::PointCloud<PointT>::Ptr keys_tgt(new pcl::PointCloud<pcl::PointXYZ>);
    getHarrisKeyPoints(cloud_tgt, resolution, keys_tgt);

    // 特征描述
    pcl::PointCloud<FeatureT>::Ptr features_src(new pcl::PointCloud<FeatureT>);
    getFeatures(cloud_src, keys_src, resolution, features_src);

    pcl::PointCloud<FeatureT>::Ptr features_tgt(new pcl::PointCloud<FeatureT>);
    getFeatures(cloud_tgt, keys_tgt, resolution, features_tgt);

    // 计算对应匹配关系
    pcl::registration::CorrespondenceEstimation<FeatureT, FeatureT> cor_est;
    cor_est.setInputCloud(features_src);
    cor_est.setInputTarget(features_tgt);
    boost::shared_ptr<pcl::Correspondences> cor(new pcl::Correspondences);
    cor_est.determineReciprocalCorrespondences(*cor);
    std::cout << "compute Correspondences " << cor->size() << std::endl;

    // 计算旋转平移矩阵
    Eigen::Matrix4f transformation(Eigen::Matrix4f::Identity());
    getTransformation(keys_src,keys_tgt, resolution, *cor, transformation);

    /* 
    // 也可以不用关键点对应关系直接获取旋转平移矩阵
    Eigen::Matrix4f transformation(Eigen::Matrix4f::Identity());
    pcl::registration::TransformationEstimationSVD<pcl::PointXYZ, pcl::PointXYZ> svd;
    svd.estimateRigidTransformation(*cloud_src, *cloud_tgt, transformation);
    */

    // 显示
    pcl::visualization::PCLVisualizer viewer;
    viewer.addPointCloud(cloud_src, "cloud_src"); // 显示点云
    viewer.addPointCloud(cloud_tgt, "cloud_tgt");

    pcl::visualization::PointCloudColorHandlerCustom<PointT> red_src(keys_src, 255, 0, 0);
    pcl::visualization::PointCloudColorHandlerCustom<PointT> red_tgt(keys_tgt, 255, 0, 0);
    viewer.addPointCloud(keys_src, red_src, "keys_src"); //显示关键点,红色,加粗
    viewer.addPointCloud(keys_tgt, red_tgt, "keys_tgt");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "keys_src");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "keys_tgt");

    for (size_t i = 0; i < cor->size(); ++i) // 显示关键点匹配关系
    {
        PointT temp1 = keys_src->points[cor->at(i).index_query];
        PointT temp2 = keys_tgt->points[cor->at(i).index_match];
        std::stringstream ss;
        ss << "line_" << i;
        viewer.addLine(temp1, temp2, ss.str());
    }

    pcl::PointCloud<PointT>::Ptr cloud_trans(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::transformPointCloud(*cloud_src, *cloud_trans, transformation); // 将原点云旋转

    pcl::visualization::PointCloudColorHandlerCustom<PointT> green_trans(cloud_trans, 0, 255, 0);
    viewer.addPointCloud(cloud_trans, green_trans, "cloud_trans");

    viewer.spin();

    system("pause");
    return 0;
}

results matching ""

    No results matching ""