FPFH (Fast Point Feature Histograms)快速点特征描述符。
http://pointclouds.org/documentation/tutorials/fpfh_estimation.php#fpfh-estimation这是pcl官网的英文文档
https://blog.csdn.net/u013235582/article/details/100811346对应的中文翻译
点特征直方图PFH:PFH公式的目标是通过使用多维值直方图来概括点周围的平均曲率,从而对点的k邻域几何属性进行编码。这个高维超空间为特征表示提供了一个信息特征,对下垫面的6D姿态是不变的,并且很好地处理了邻域中存在的不同采样密度或噪声水平。 点特征直方图表示基于k邻域中的点与其估计的表面法线之间的关系。简而言之,它试图通过考虑估计法线方向之间的所有交互来尽可能好地捕捉采样的表面变化。因此,生成的超空间取决于每个点的表面法线估计的质量。
对于要求实时或接近实时的应用程序,密集点的特征直方图的计算效率是一个一个主要问题。FPFH将算法的计算复杂度降低到O(nk),同时仍然保留了PFH的大部分识别能力。
快速点特征直方图作为pcl_features库的一部分在PCL中实现。默认的FPFH实现使用11个子分区(binning subdivisions)(例如,四个特征值中的每一个都将使用其值区间中的这许多个bins),以及一个去相关的方案(见上面:特征直方图分别计算并赋值),结果是一个33字节的浮点值数组。它们存储在pcl::FPFHSignature33 点类型中。
给的源代码看不太懂啥个啥,就用了上面给的documentation链接里的代码,但是代码又不全,就补充完整了一下。但这个算法很慢,瞎找了一个比较小一点的点云,就这还算了好久。
https://blog.csdn.net/elephant18/article/details/102904478 显示最后的描述符
#include <pcl/point_types.h>
#include <pcl/features/fpfh.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/integral_image_normal.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
using namespace std;
int
main ()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>());
pcl::io::loadPCDFile("milk.pcd", *cloud);
//计算法线
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZ>());
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud(cloud);
ne.setSearchMethod(tree1);
ne.setRadiusSearch(0.03);
ne.compute(*normals);
// 创建FPFH估计类,并将输入数据集+法线传递给它
pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
fpfh.setInputCloud(cloud);
fpfh.setInputNormals(normals);
//或者,如果cloud是tpe PointNormal,则执行fpfh.setInputNormals(cloud);
// 创建一个空的kdtree表示,并将其传递给FPFH估计对象。
// 它的内容将根据给定的输入数据集填充到对象中(因为没有其他搜索表面)。
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree2(new pcl::search::KdTree<pcl::PointXYZ>());
fpfh.setSearchMethod(tree2);
// 输出数据集
pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs(new pcl::PointCloud<pcl::FPFHSignature33>());
// 使用半径为5cm的球体中的所有邻居
// 重点:这里使用的半径必须大于用于估计表面法线的半径!!
fpfh.setRadiusSearch(0.05);
// 计算特征
fpfh.compute(*fpfhs);
// fpfhs->points.size () 和 cloud->points.size ()一样
cout << "原始点云点数:" << cloud->points.size() << endl;
cout << "fpfh数:" << fpfhs->points.size() << endl;
//特征描述的输出
for (int i = 0; i < fpfhs->points.size(); i++) {
pcl::FPFHSignature33 descriptor = fpfhs->points[i];
cout << descriptor << endl;
}
return 0;
}
结果: