1、 6种点云特征描述子简概
NARF(Normal Aligned Radial Feature)特征点描述子:NARF描述子是一种基于法线对齐的径向特征描述子。它通过将点云表面分割为小的网格单元,并计算每个单元中的法线直方图,从而提取特征。NARF描述子对于点云的曲率和形状变化比较敏感,可用于目标检测和场景识别等任务。
PFH(Point Feature Histogram)和 FPFH(Fast Point Feature Histogram)点特征直方图描述子:PFH和FPFH是一类常用的点云特征描述子。它们通过计算点与其邻域内其他点之间的相对位置和法线之间的关系构建直方图描述子。PFH描述子计算相对复杂,而FPFH是对PFH进行了优化,提高了计算效率。这些描述子通常用于点云配准、识别和匹配等任务。
RoPs(Rotational Projection Statistics)特征:RoPs特征是一种基于旋转投影统计的描述子。它将点云投影到多个不同的视点上,并统计每个视点上的投影信息,如高度、密度和曲率等。RoPs特征对点云的旋转和尺度变化具有较好的不变性,可用于目标分类和识别等任务。
VFH(Viewpoint Feature Histogram)视点特征直方图描述子:VFH描述子是一种基于视点的特征描述子。它计算点云中每个点与其他点之间的相对位置和法线之间的关系,并构建直方图描述子。VFH描述子主要用于点云的识别和分类任务,对视点变化具有较好的不变性。
GASD(Global Alignment of Spatial Distribution)全局对齐的空间分布描述子:GASD描述子是一种基于空间分布的全局特征描述子。它通过将点云投影到三维直方图中,并统计点云在不同区域的分布情况来构建描述子。GASD描述子对点云的全局形状和分布特征进行建模,常用于点云的识别和分类。
基于惯性矩和偏心率的描述子:这种描述子是一种基于点云几何属性的特征描述子。它通过计算点云的惯性矩和偏心率等几何属性,来表征点云的形状特征。这种描述子通常用于点云的形状分析和识别任务
2、提取PFH(Point Feature Histogram)特征描述子
代码
#include <pcl/point_types.h>
#include <pcl/features/pfh.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/features/normal_3d.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);
// --------------------
// K近邻搜索法线估计
// --------------------
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normalEstimation;
normalEstimation.setInputCloud(cloud);
normalEstimation.setRadiusSearch(0.03);//领域半径,每个点的领域范围
pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
normalEstimation.setSearchMethod(kdtree);// kd树搜索每个点的领域点
normalEstimation.compute(*normals); // 用每个点的领域点估计其法线向量
// -----------------------------------------------------------------------------
// 计算PFH特征描述子
// 使用点云数据和对应的法线数据作为输入。
// 然后通过设置最近邻搜索方法和搜索半径,对每个点在其邻域内进行特征计算,生成PFH特征描述子。
// 计算结果存储在pfhs中,可以用于后续的点云处理任务
// -----------------------------------------------------------------------------
pcl::PFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::PFHSignature125> pfh; // 创建PFHEstimation对象
pfh.setInputCloud(cloud); // 输入点云数据
pfh.setInputNormals(normals); // 输入法线数据
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>()); // 创建KdTree对象tree
pfh.setSearchMethod(tree); // 将tree设置为PFH估计过程中用于搜索最近邻点的方法
pcl::PointCloud<pcl::PFHSignature125>::Ptr pfhs(new pcl::PointCloud<pcl::PFHSignature125>()); // 用于存储计算得到的PFH特征描述子
pfh.setRadiusSearch(0.08); // 设置搜索半径,指定在计算每个点的PFH描述子时使用的邻域范围; 必须大与估算法向量的领域半径
pfh.compute(*pfhs); // 计算点云的PFH特征描述子
//--------------
// 打印PFH描述子
// --------------
unsigned long size = pfhs->points.size();
for (int j = 0; j < size ; ++j){
pcl::PFHSignature125 &signature125 = pfhs->points[j];
float *h = signature125.histogram;
printf("%d: %f, %f,%f \n", j, h[1], h[2], h[3]);
}
// -----------------
// 可视化法线
// ----------------
pcl::visualization::PCLVisualizer viewer("PCL Viewer");
viewer.setBackgroundColor(0.0, 0.0, 0.5);
viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 1, 0.01, "normals");
while (!viewer.wasStopped()){
viewer.spinOnce();
}
return 0;
}