快速点特征直方图(Fast Point Feature Histograms,FPFH)介绍
快速点特征直方图(Fast Point Feature Histograms,FPFH)是一种基于点的描述子,用于描述点云数据中的局部几何信息。FPFH描述子是在法线估计的基础上计算的,它以每个点为中心,考虑其邻域内的几何特征并生成一个直方图。
FPFH描述子的计算过程如下:
-
对于点云中的每个点,获取其法线向量。
-
构建归一化的球形邻域,以当前点为球心,设置一个半径内的邻域点作为邻居。
-
对于当前点和邻居点对,计算其相对位置和法线的角度差,形成一个6维的特征向量。
-
基于计算的6维特征向量,构建一个直方图。FPFH描述子的每个bin代表角度信息的范围,通过统计落在每个bin中的邻居数量,形成直方图。
-
将所有点的FPFH描述子组合起来,形成整个点云的特征表示。
FPFH描述子具有以下特点:
-
它可以描述点云的局部几何信息,捕捉点与其邻居之间的关系。
-
FPFH描述子对于点云的尺度、旋转和平移具有一定的不变性。
-
由于FPFH描述子的计算复杂度较低,它在实时应用和大规模点云处理中具有优势。
FPFH描述子常用于点云匹配、目标识别、三维重建、配准和分类等计算机视觉和机器人领域的任务中。
代码:
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/features/fpfh.h>
#include <pcl/features/fpfh_omp.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
int main(){
// 读取点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("/home/jason/file/pcl-learning/data/bunny.pcd", *cloud);
// -------
// 估计法线
// -------
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; // 创建法线估计对象
ne.setInputCloud(cloud); // 点云数据输入
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>()); // 创建Kd树对象
ne.setSearchMethod(tree); // 把Kd树作为搜索方法
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>()); // 用于存储法向量
ne.setRadiusSearch(0.03); // 设置搜索半径
ne.compute(*cloud_normals); // 计算法向量
// ---------------------
// 估计FPFH特征描述子
// pcl::FPFHEstimationOMP 多核
// --------------------
// pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;// 创建FPFH估计对象
pcl::FPFHEstimationOMP<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
fpfh.setNumberOfThreads(8); // 设置线程数量
fpfh.setInputCloud(cloud); // 点云数据输入
fpfh.setInputNormals(cloud_normals); // 法向量数据输入
fpfh.setSearchMethod(tree); // 设置kd树为搜索方法
pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs(new pcl::PointCloud<pcl::FPFHSignature33>()); // 用于保存FPFH特征描述子
fpfh.setRadiusSearch(0.05); // 设置搜索半径,指定在计算每个点的FPFH描述子时使用的邻域范围; 必须大与估算法向量的领域半径
fpfh.compute(*fpfhs); // 计算点云的FPFH特征描述子
// 每个点有一个特征向量
cout<< "cloud size: " << cloud->size() << std::endl
<< "fpfhs size: " << fpfhs->size() << std::endl;
return 0;
}