PFH点特征直方图及其pcl用法

部分参考:https://blog.csdn.net/qq_25491201/article/details/51104390

1.点的特征

表面法线和曲率可以好的代表一个点的几何特征。然而它们算得很快,而且算法简单,但是它们不能捕获细节,它们只是点的近邻的几何特征的近似估计。作为一个直接的结论,大多数的场景往往会包括很多有着相似特征的点,这会减少它们所带来的消息量,也容易造成混淆和错误的匹配。

这时候就要一个具备更加丰富信息的特征描述方法——点特征直方图Point Feature Histogram

PFH的目标是通过使用一个点周围的多维直方图来编码一个点的k个最近邻的几何属性。这个高维空间提供了一些有用的特征代表,同时关于6位位姿不变的,同时和可以很好的应对不同的采样密度和近邻的噪声水平。

下面的图展示了一个PFH在计算Pq这个点时候的影响区域图,Pq这个点用红色标记并放在半径为r的圆圈的中央,然后它的所有近邻(离点的距离小于半径r)都通过一个网格来间接的相邻着。下面的PFH描述器作为了一个直方图计算了所有匹配的点之间的关系,有一个O(k方)的复杂度。
在这里插入图片描述在这个区域之内,每两个点可以组成一对(Ps, Pt),我们在这一对点中的其中一个点为原点建立UVW坐标系:
在这里插入图片描述
在这里插入图片描述
u v w三条基向量以Ps为原点,显然是相互垂直的。上图和公式并不一致,比如V的方向。图仅仅是示意。

使用上面的uvw的坐标系,ns法线和ni法线的差可以转化为下面的3个角度的差异(因为他们的模都是一样的):

在这里插入图片描述
d是两点距离的平方

这样我们把这四个值
在这里插入图片描述
称为“特征值”,四个特征值的集合组成了点Ps的“特征”。但是经常我们会省略d,会获得更好的效果,因此一个点对应三个特征值。

2.将特征放入点特征直方图PFH

对于Ps的邻域,有一系列的Ps、Pt点对,对于每一个Ps就可以计算他对应的四个特征值。

那么如何将特征放在直方图里面呢?对于三个特征值中的每一个具体特征,我将其等分成5份,这样就存在555=125个区间,这125个区间构成了一个125bins的直方图。这样对于一个点的三个特征值,根据每一个特征值的细分,分发到这125个区间中。对目标点的邻域中的所有点按照此种方法进行统计,实现对目标点的直方图特征描述。

在论文《Aligning Point Cloud Views using Persistent Feature Histograms》中,使用了4个特征值,每个特征值分成两份(2^4=16 bins)。对特征分发的结果:
在这里插入图片描述

3. 快速点特征直方图FPFH

FPFH是PFH的加速版本,经过实测能提升1/3的速度(大概)。

参考:https://blog.csdn.net/u011736771/article/details/85103293

PFH和FPFH计算方式之间的主要区别总结如下:

FPFH没有对全互连点的所有邻近点的计算参数进行统计,因此可能漏掉了一些重要的点对,而这些漏掉的对点可能对捕获查询点周围的几何特征有贡献。
PFH特征模型是对查询点周围的一个精确的邻域半径内,而FPFH还包括半径r范围以外的额外点对(但不超过2r的范围);
因为采用权重计算的方式,所以FPFH结合SPFH值,重新捕获邻近重要点对的几何信息;
由于大大地降低了FPFH的整体复杂性,因此FPFH有可能使用在实时应用中;
通过分解三元组,简化了合成的直方图。也就是简单生成d分离特征直方图,对每个特征维度来单独绘制,并把它们连接在一起。

不再详述,感兴趣地读者可参考论文:《Fast Point Feature Histograms (FPFH) for 3D Registration》

4. PFH和FPFH的pcl用法

这里仅仅介绍FPFH的用法。

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>             // 法线
#include <pcl/features/fpfh_omp.h>   // fpfh计算,omp加速方法




pcl::search::KdTree<pcl::PointXYZI>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZI>());
std::mutex mPFH;

.........一系列操作,获得待计算点云 cloud
					
					mPFH.lock(); // 计算直方图的时候记得锁一下
//                     pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);  // for PFH
                    pcl::PointCloud<pcl::PointNormal>::Ptr normals(new pcl::PointCloud<pcl::PointNormal>);  // for FPFH
                    // ================================================================================================
                    // ================================================================================================
                    // ================================================================================================
                    // ================================================================================================

                    pcl::FPFHEstimationOMP<pcl::PointXYZI, pcl::PointNormal, pcl::FPFHSignature33> fpfh_omp;
                    pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs(new pcl::PointCloud<pcl::FPFHSignature33>());
                    //  法线估计
                    pcl::NormalEstimation<pcl::PointXYZI, pcl::PointNormal> ne;
                    ne.setInputCloud(cloud);   // cloud 是待计算的输入点云
                    ne.setSearchMethod(tree);
                    ne.setKSearch(10);
                //    ne.setRadiusSearch(0.03);
                    ne.compute(*normals);
                    // 直方图计算
                    std::cout<< "法线"<<normals->points[100]<<std::endl;
                    fpfh_omp.setInputCloud(cloud);
                    fpfh_omp.setInputNormals(normals);
                    fpfh_omp.setSearchMethod(tree);
                    fpfh_omp.setNumberOfThreads(8);
                    fpfh_omp.setRadiusSearch(0.5);   
                    fpfh_omp.compute(*fpfhs);
                    mPFH.unlock();
                    //==================================================================================================
                    // ================================================================================================
                    // ================================================================================================
                    // ================================================================================================

5. 如何根据一团点云的PFH判断这一陀点云的平面性是否好呢?待研究~

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: PFH描述子的输出直方图是一种将三维云数据表示为局部表面特征的方法,其输出直方图由四个部分组成:数、法向量、曲率和球面坐标。其中,数是指该局部表面内的的数量;法向量是指该局部表面内的的法向量的方向;曲率是指该局部表面内的的曲率大小;球面坐标是指该局部表面内的的球面坐标系下的坐标。这些信息可以被用于云配准、目标识别等应用中。 ### 回答2: PFH (Point Feature Histogram) 描述子是一种用于描述三维云数据的特征表示方法。它通过计算云中每个与其邻居之间的关系,构建了一个三维直方图,来表示云数据的局部几何信息。 PFH 描述子的输出直方图是一个具有固定维度的向量。其维度根据选择的参数进行定义,通常在32到128之间。每个维度对应一个局部几何特征的计数。 具体的计算流程如下: 1. 对于云中的每个,首先选择一组与该相邻的邻居集合。 2. 对于每个邻居,计算其与当前之间的距离和该邻居的法线方向与当前法线方向之间的角度差。 3. 根据这两个距离和角度差的组合,确定其所属的直方图bin。 4. 统计每个bin中对的数量,得到一个局部几何特征直方图。 5. 将所有直方图组合在一起,形成最终的输出直方图PFH 描述子的输出直方图能够反映云中的局部几何信息。每个维度对应一个特定的局部几何特征。通过计算不同维度之间的相似度,可以用于云配准、三维目标识别等任务中。直方图的每个bin都是一个计数值,反映了该局部几何特征云中的分布情况。通过对比不同云的直方图,可以评估它们之间的相似性或差异性。 总而言之,PFH 描述子的输出直方图是一个向量,用于表示三维云数据的局部几何信息。它能够反映云中不同局部几何特征的分布情况,并通过计算相似度用于不同的应用领域。 ### 回答3: PFH描述子是一种用于描述三维云数据的特征向量。在计算PFH描述子时,首先需要选择一个参考,然后计算该与其相邻之间的法线差异(即法线之间的差异角度)。然后,将这些差异角度分成若干个范围,构建一个角度直方图。接下来,将该参考与其他所有进行比较,计算它们之间的法线差异,并根据差异角度将其分配到对应的角度直方图中。最后,将所有的角度直方图拼接到一起,构成了PFH描述子的输出直方图PFH描述子的输出直方图具有以下特: 1. 维度:PFH描述子输出的直方图维度取决于所选择的角度差异范围的数量。通常,选择15到30个范围,所以输出的直方图维度为15到30维。 2. 特征表示:PFH描述子通过统计法线之间的角度差异来描述云的局部几何结构。直方图中的每个bin用于记录在对应角度范围内的的数量,从而表示了该角度范围内的角度差异的重要程度。 3. 值范围:输出直方图中的每个bin的值表示了该角度范围内的的数量。通常,该值的范围为0到整个云中的最大数量。 4. 可视化:PFH描述子的输出直方图可以在二维平面上进行可视化,其中横轴表示不同的角度范围,纵轴表示对应范围内的数量,从而形成一个柱状图。 通过PFH描述子的输出直方图,我们可以更好地理解云的局部几何结构,并利用这些特征来进行云分类、检索、匹配等任务。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值