点云库PCL学习:特征描述与提取(FPFH)
快速点特征直方图(FPFH)描述子
已知点云P中有n个点,那么它的点特征直方图(PFH)的理论计算复杂度是(Onk2),其中k是点云P中每个点p计算特征向量时考虑的邻域数量。对于实时应用或接近实时应用中,密集点云的点特征直方图(PFH)的计算,是一个主要的性能瓶颈。此处为PFH计算方式的简化形式,称为快速点特征直方图FPFH(Fast Point Feature Histograms)。FPFH将计算复杂度降到了(Onk),但仍然保留了PFH的大部分特征。
PFH和FPFH的区别
PFH和FPFH计算方式之间的主要区别总结如下:
- FPFH没有对全互连 点的所有邻近点的计算参数进行统计,从图中可以看到,因此可能漏掉了一些重要的点对,而这些漏掉的对点可能对捕获查询点周围的几何特征有贡献。
- PFH特征模型是对查询点周围的一个精确的邻域半径内,而FPFH还包括半径r范围以外的额外点对(不过在2r内)
- 因为重新权重计算的方式,所以FPFH结合SPFH值,重新捕获邻近重要点对的几何信息;
- 由于大大地降低了FPFH的整体复杂性,因此FPFH有可能使用在实时应用中;
- 通过分解三元组,简化了合成的直方图。也就是简单生成d分离特征直方图,对每个特征维度来单独绘制,并把它们连接在一起。
估计FPFH描述子
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/time.h>
#include <pcl/features/fpfh.h> //FPFH
#include <pcl/visualization/pcl_plotter.h>//显示描述子
using namespace pcl;
int main(int argc, char **argv)
{
//读取点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("test.pcd", *cloud) == -1)
{
PCL_ERROR("Cloudn't read file!");
system("pause");
return -1;
}
//估计法线
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud(cloud);
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
ne.setSearchMethod(tree);
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
ne.setRadiusSearch(0.6); //使用半径在查询点周围0.6范围内的所有邻元素
ne.compute(*cloud_normals); //计算法线
//PHFH
pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
fpfh.setInputCloud(cloud);
fpfh.setInputNormals(cloud_normals);
pcl::search::KdTree<PointXYZ>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZ>);//创建一个空的kd树表示法
fpfh.setSearchMethod(tree1);//输出的数据集
pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs(new pcl::PointCloud<pcl::FPFHSignature33>());
//使用半径内0.8里面范围所有元素
fpfh.setRadiusSearch(0.8);//使用半径必须大于估计法线时使用的半径
fpfh.compute(*fpfhs);
//显示某点的fhfh特征
pcl::visualization::PCLPlotter plotter;
plotter.addFeatureHistogram<pcl::FPFHSignature33>(*fpfhs,"fpfh", 60);
//可视化
pcl::visualization::PCLVisualizer viewer("PCL Viewer");
viewer.setBackgroundColor(0.0, 0.0, 0.0);
viewer.addPointCloudNormals<pcl::PointXYZ,pcl::Normal>(cloud, cloud_normals, 1, 0.4, "normals");
viewer.addPointCloud(cloud,"cloud1");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,2, "cloud1");
while (!viewer.wasStopped())
{
plotter.plot();
viewer.spinOnce(100);
}
return 0;
}
估计结果
如图所示FPFH包含33个数据