资讯专栏INFORMATION COLUMN

pcl之FPFH配准

shuibo / 812人阅读

摘要:所以,很多时候,都先对原始点云进行简化,对简化后的数据做配准计算,在将所获得的配准参数应用到原始点云,以提高计算效率。要可视化对应关系,首先需要计算对应关系本文配准为例效果粗配

什么是fpfh特征

有关快速点云直方图(fpfh)特征的数学描述,在这里不做过多介绍,可以查看fpfh。也可以查看PCL的官网解释,中文版可直接搜索pcl中国fpfh。

主程序

首先还是一堆头文件(当然好多头文件在这里没用到,可自行删除)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  //包含fpfh加速计算的omp(多核并行计算)
#include 
#include  //特征的错误对应关系去除
#include  //随机采样一致性去除
#include 
#include 

为了方便记:

using namespace std;
typedef pcl::PointCloud pointcloud;
typedef pcl::PointCloud pointnormal;
typedef pcl::PointCloud fpfhFeature;

为了使用fpfp特征匹配,声明一个计算fpfh特征点的函数:

fpfhFeature::Ptr compute_fpfh_feature(pointcloud::Ptr input_cloud,pcl::search::KdTree::Ptr tree)
{
        //法向量
        pointnormal::Ptr point_normal (new pointnormal);
        pcl::NormalEstimation est_normal;
        est_normal.setInputCloud(input_cloud);
        est_normal.setSearchMethod(tree);
        est_normal.setKSearch(10);
        est_normal.compute(*point_normal);
        //fpfh 估计
        fpfhFeature::Ptr fpfh (new fpfhFeature);
        //pcl::FPFHEstimation est_target_fpfh;
        pcl::FPFHEstimationOMP est_fpfh;
        est_fpfh.setNumberOfThreads(4); //指定4核计算
        // pcl::search::KdTree::Ptr tree4 (new pcl::search::KdTree ());
        est_fpfh.setInputCloud(input_cloud);
        est_fpfh.setInputNormals(point_normal);
        est_fpfh.setSearchMethod(tree);
        est_fpfh.setKSearch(10);
        est_fpfh.compute(*fpfh);

        return fpfh;
        
}

可以看出,在计算Fpfh特征时,首先需要计算点集的法向量(法向量是点云的一个非常重要的特征,本该多带带处理,仅在这里为了方便,少写两行代码,将其封装在FPFH特征的计算中),根据计算好的法向量,计算FPFH特征。计算fpfh特征时,近邻点集个数不易取得过大,,否则一则导致计算量增大,二会使得fpfh的计算失去意义(通其他特征计算一样,过大的近邻点集合不能反映局部特征)。

主函数:

int main (int argc, char **argv)
{
        if (argc < 3)
        {
                cout<<"please input two pointcloud"<::Ptr tree (new pcl::search::KdTree ());

        fpfhFeature::Ptr source_fpfh =  compute_fpfh_feature(source,tree);
        fpfhFeature::Ptr target_fpfh =  compute_fpfh_feature(target,tree);
        
         //对齐(占用了大部分运行时间)
        pcl::SampleConsensusInitialAlignment sac_ia;
        sac_ia.setInputSource(source);
        sac_ia.setSourceFeatures(source_fpfh);
        sac_ia.setInputTarget(target);
        sac_ia.setTargetFeatures(target_fpfh);
        pointcloud::Ptr align (new pointcloud);
        //  sac_ia.setNumberOfSamples(20);  //设置每次迭代计算中使用的样本数量(可省),可节省时间
        sac_ia.setCorrespondenceRandomness(6); //设置计算协方差时选择多少近邻点,该值越大,协防差越精确,但是计算效率越低.(可省)
        sac_ia.align(*align); 
        end = clock();
        cout <<"calculate time is: "<< float (end-start)/CLOCKS_PER_SEC< view (new pcl::visualization::PCLVisualizer("fpfh test"));
        int v1;
        int v2;
        
        view->createViewPort(0,0.0,0.5,1.0,v1);
        view->createViewPort(0.5,0.0,1.0,1.0,v2);
        view->setBackgroundColor(0,0,0,v1);
        view->setBackgroundColor(0.05,0,0,v2);
        pcl::visualization::PointCloudColorHandlerCustom sources_cloud_color(source,250,0,0);
        view->addPointCloud(source,sources_cloud_color,"sources_cloud_v1",v1);
        pcl::visualization::PointCloudColorHandlerCustom target_cloud_color (target,0,250,0);
        view->addPointCloud(target,target_cloud_color,"target_cloud_v1",v1);
        view->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,2,"sources_cloud_v1");

        pcl::visualization::PointCloudColorHandlerCustomaligend_cloud_color(final,255,0,0);
        view->addPointCloud(align,aligend_cloud_color,"aligend_cloud_v2",v2);
        view->addPointCloud(target,target_cloud_color,"target_cloud_v2",v2);
        view->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,4,"aligend_cloud_v2");
        view->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,2,"target_cloud_v2");

        //   view->addCorrespondences(source,target,*cru_correspondences,"correspondence",v1);//添加显示对应点对
        while (!view->wasStopped())
        {
                // view->spin();
                view->spinOnce(100);
                boost::this_thread::sleep (boost::posix_time::microseconds (100000));
                  

        }
         pcl::io::savePCDFile ("crou_output.pcd", *align);
         //  pcl::io::savePCDFile ("final_align.pcd", *final);
        
        return 0;
}

采用FPFH特征配准,效果不错,但是计算效率非常低,尤其针对大规模点云数据时。所以,很多时候,都先对原始点云进行简化,对简化后的数据做配准计算,在将所获得的配准参数应用到原始点云,以提高计算效率。

体素网格简化

主要程序:

        //pcl::ApproximateVoxelGrid approximate_voxel_grid;
        pcl::VoxelGrid approximate_voxel_grid;
        approximate_voxel_grid.setLeafSize(0.5,0.5,0.5); //网格边长.这里的数值越大,则精简的越厉害(剩下的数据少)
        pointcloud::Ptr source (new pointcloud);
        pointcloud::Ptr sample_sources (new pointcloud);
        approximate_voxel_grid.setInputCloud(source);
        approximate_voxel_grid.filter(*sample_source);
        cout << "source voxel grid  Filte cloud size is " << sample_source->size()<

针对体素网格简化,PCL提供了两种方法:其一,pcl::ApproximateVoxelGrid 类;其二, pcl::VoxelGrid类。可以看出,第二中比第一中少了“大约”approximate,也就是说第二种某些情况下比第一种更精确。原因是:第一种方法是利用体素网格的中心(长方体的中心)代替原始点,而第二种则是对体素网格中所有点求均值,以期望均值点代替原始点集

可视化

在如上主程序中,已经包含了可视化的功能,更过可视化可看我的博客pcl可视化那些事,在这里,细致的讲一下如何添加对应点对的可视化功能。
要可视化对应关系,首先需要计算对应关系,本文配准为例:

      pcl::registration::CorrespondenceEstimation crude_cor_est;

      boost::shared_ptr cru_correspondences (new pcl::Correspondences);
      crude_cor_est.setInputSource(source_fpfh);
      crude_cor_est.setInputTarget(target_fpfh);
        //  crude_cor_est.determineCorrespondences(cru_correspondences);
      crude_cor_est.determineReciprocalCorrespondences(*cru_correspondences);
      cout<<"crude size is:"<size()<
效果(粗配)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/9676.html

相关文章

  • pcl可视化的那些事

    摘要:在点云数据预处理中,要想知道点云的形状需要可视化要想了解精简去噪简化压缩的结果需要可视化配准中,对应点对的显示对应点对的去除结果配准变化的过程需要可视化下可直接在命令行输入或可直接显示中的点云文件。 可视化:一目了然 如题所示,可视化的重要性不必多说。在点云数据预处理中,要想知道点云的形状需要可视化; 要想了解精简/去噪/简化/压缩 的结果需要可视化; 配准中,对应点对的显示/对应点对...

    Rocture 评论0 收藏0
  • PCL ICP 算法实现

    摘要:是什么,即最近点迭代算法,是最为经典的数据配准算法。实例展示之变种有很多变种,有的,也有的,一般后者的计算速度快一些,是基于法向量的,需要输入数据有较好的法向量,具体使用时建议根据自己的需要及可用的输入数据选择具体方法。 ICP是什么? ICP(Iterative Closest Point),即最近点迭代算法,是最为经典的数据配准算法。其特征在于,通过求取源点云和目标点云之间的对应点...

    ShowerSun 评论0 收藏0
  • PCL ICP 算法实现

    摘要:是什么,即最近点迭代算法,是最为经典的数据配准算法。实例展示之变种有很多变种,有的,也有的,一般后者的计算速度快一些,是基于法向量的,需要输入数据有较好的法向量,具体使用时建议根据自己的需要及可用的输入数据选择具体方法。 ICP是什么? ICP(Iterative Closest Point),即最近点迭代算法,是最为经典的数据配准算法。其特征在于,通过求取源点云和目标点云之间的对应点...

    kuangcaibao 评论0 收藏0
  • 三维重建工具——pclpy教程Surface

    摘要:实际分割发生在。于是为了转移注意力,让找工作的这段时间有点事做,这时候正好看到之前发的一个笔记三维重建工具使用教程阅读和点赞量都比较高,而且有很多小伙伴在评论区问问题,我意识到了有很多学的小伙伴可能对点云处理很感兴趣。 ...

    FrancisSoung 评论0 收藏0
  • Linux下 PCL源码安装

    摘要:既然选择了,那末接下来便是理所当然的事情获取源码包。建议此源码安装不针对任何系统,,等都适用。若打算源码安装,在安装之前最好先更新一下系统,这样基本能保证所安装的包为最新包。 不得不知的PCL 所谓PCL(Point Cloud Library)其实就是一个开源的c++代码库,它实现了大量点云相关的通用算法和高效的数据管理结构,不仅涉及逆向工程领域,其还在模式识别,机器人视觉,计算机图...

    iamyoung001 评论0 收藏0

发表评论

0条评论

shuibo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<