目录
PCL点云算法汇总及实战案例汇总的目录地址链接:
一、概述
FPFH(Fast Point Feature Histograms,快速点特征直方图)是一种基于点云的三维特征描述子,主要用于点云特征提取和配准。相比于PFH,FPFH通过降低复杂度优化了计算效率。FPFH描述子利用点云中的法向量和几何信息,生成33维的特征向量,可以用于识别和匹配点云中的关键点。
1.1原理
FPFH的计算分为以下几个步骤:
1.2实现步骤
- 读取点云数据:从PCD文件中读取点云数据。
- 法向量计算:基于KdTree搜索算法,计算点云的法向量。
- FPFH特征计算:通过法向量和几何信息,生成FPFH特征描述子。
- 直方图可视化:将FPFH特征可视化为直方图,展示每个点的特征分布。
1.3应用场景
- 点云配准:FPFH特征可以用于不同点云之间的特征匹配和配准。
- 物体识别:通过FPFH特征可以进行三维物体识别和分类。
- 关键点检测:FPFH可以用于检测点云中的关键点和特征点。
二、代码实现
2.1关键函数
2.1.1 法向量计算
void computeNormals(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals)
{
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
ne.setInputCloud(cloud); // 设置输入点云
ne.setSearchMethod(tree); // 设置搜索方法
ne.setKSearch(30); // 设置K近邻搜索
ne.setNumberOfThreads(4); // 设置使用的线程数
ne.compute(*normals); // 计算法向量
}
2.1.2 FPFH特征计算
void computeFPFH(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals, pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfh_features)
{
pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
fpfh.setInputCloud(cloud); // 设置输入点云
fpfh.setInputNormals(normals); // 设置法向量
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
fpfh.setSearchMethod(tree); // 设置搜索方法
fpfh.setRadiusSearch(0.5); // 设置搜索半径为5厘米
fpfh.compute(*fpfh_features); // 计算FPFH特征
}
2.1.3 直方图可视化
void visualizeFPFH(pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfh_features)
{
pcl::visualization::PCLPlotter plotter;
plotter.setTitle("FPFH Feature Histogram"); // 设置标题
plotter.setShowLegend(true); // 显示图例
plotter.addFeatureHistogram<pcl::FPFHSignature33>(*fpfh_features, "fpfh", 5); // 可视化第五个点的FPFH特征
plotter.setWindowSize(800, 600); // 设置窗口大小
plotter.spinOnce(30000000); // 显示
}
2.2完整代码
#include<iostream>
#include<vector>
#include <pcl/point_types.h>
#include <pcl/features/fpfh.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d_omp.h> // 使用OMP进行法向量估计
#include <pcl/visualization/pcl_plotter.h> // 用于可视化直方图
using namespace std;
// 计算法向量
void computeNormals(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals)
{
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
ne.setInputCloud(cloud); // 设置输入点云
ne.setSearchMethod(tree); // 设置搜索方法
ne.setKSearch(30); // 设置K近邻搜索
ne.setNumberOfThreads(4); // 使用多线程加速
ne.compute(*normals); // 计算法向量
}
// 计算FPFH特征
void computeFPFH(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals, pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfh_features)
{
pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
fpfh.setInputCloud(cloud); // 设置输入点云
fpfh.setInputNormals(normals); // 设置法向量
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
fpfh.setSearchMethod(tree); // 设置搜索方法
fpfh.setRadiusSearch(0.5); // 设置搜索半径为5厘米
fpfh.compute(*fpfh_features); // 计算FPFH特征
}
// 可视化FPFH直方图
void visualizeFPFH(pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfh_features)
{
pcl::visualization::PCLPlotter plotter;
plotter.setTitle("FPFH Feature Histogram"); // 设置标题
plotter.setShowLegend(true); // 显示图例
plotter.addFeatureHistogram<pcl::FPFHSignature33>(*fpfh_features, "fpfh", 5); // 可视化第五个点的FPFH特征
plotter.setWindowSize(800, 600); // 设置窗口大小
plotter.spinOnce(30000000); // 显示
}
int main()
{
// 1. 读取点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read("person2.pcd", *cloud);
// 2. 计算法向量
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
computeNormals(cloud, normals);
// 3. 计算FPFH特征
pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfh_features(new pcl::PointCloud<pcl::FPFHSignature33>);
computeFPFH(cloud, normals, fpfh_features);
// 4. 可视化FPFH特征直方图
visualizeFPFH(fpfh_features);
return 0;
}