快速特征点直方图描述器(FPFH)

PFH的理论上的时间复杂度是O(nk的平方),n是点的数量,k是最近邻的个数。对于实时系统来说,这压根就是不行的,所以作为PFH规划的简化版本,FPFH把计算复杂度减少成O(nk),但是还具有很好的和PFH差不多的区分能力。

第一步我们先计算了每个查询点Pq的一系列值,并把它叫做SPFH(Simplified Point Feature Histgram)

第二步每个点的最近邻是重新分配,SPFH值将用来权衡FPFH的值:

这里的Wk代表了两点的距离。权重(weight)的组合是非常重要的,下面的图显示了这一点:

快速特征点直方图描述器(FPFH)_第1张图片

可以看到越近的权重越大,线越粗。

因此,给定一个点Pq,这个算法第一步评估了SPFH的值,通过创造它和它的近邻的匹配。这个过程将一直重复,通过近邻SPFH的值不停的改变权重,最终生成了Pq的FPFH。

PFH与FPFH之间的差异

1.FPFH没有和它所有的近邻有着联系,因此可能会丢失一些值的匹配。

2.PFH模型可以更精确的描述表面,而FPFH则包括了额外的点的配对在半径为r的圆的外面(最多不会超过2r)

3.因为权重的组合,FPFH结合了SPFH的值并且重新获取了一些点的近邻。

4.FPFH复杂度大大降低,计算更快。

5.最终的直方图是简化了。

快速特征点直方图描述器(FPFH)_第2张图片

 

预估FPFH的特征值

FPFH的执行使用了11个分发的子区间,和一个非相关的组合(33位的数组),把它存在pcl::FPFHSignature33这个点类型里面。

下面的代码段,预估了一个所有点的FPFH的特征集合

#include 
#include 

{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal> ());

  ... read, pass in or create a point cloud with normals ...
  ... (note: you can create a single PointCloud<PointNormal> if you want) ...

  // Create the FPFH estimation class, and pass the input dataset+normals to it
  pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
  fpfh.setInputCloud (cloud);
  fpfh.setInputNormals (normals);
  // alternatively, if cloud is of tpe PointNormal, do fpfh.setInputNormals (cloud);

  // Create an empty kdtree representation, and pass it to the FPFH estimation object.
  // Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
  pcl::search::KdTree<PointXYZ>::Ptr tree (new pcl::search::KdTree<PointXYZ>);

  fpfh.setSearchMethod (tree);

  // Output datasets
  pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs (new pcl::PointCloud<pcl::FPFHSignature33> ());

  // Use all neighbors in a sphere of radius 5cm
  // IMPORTANT: the radius used here has to be larger than the radius used to estimate the surface normals!!!
  fpfh.setRadiusSearch (0.05);

  // Compute the features
  fpfh.compute (*fpfhs);

  // fpfhs->points.size () should have the same size as the input cloud->points.size ()*
}

调用FPFHEstimation时实际做了这么几步

1.PFH的步骤

2.使用每个SPFH,通过一个权重组合来赋值给FPFH。

类似于PFH我们可以把这段代码反正compute()函数前,进行优化

for (int i = 0; i < normals->points.size(); i++)
{
  if (!pcl::isFinite<pcl::Normal>(normals->points[i]))
  {
    PCL_WARN("normals[%d] is not finite\n", i);
  }
}

我们可以用OpenMP进行优化

使用OpenMP可以进行多线程计算。类名叫做pcl::FPFHEstimationOMP,

 

你可能感兴趣的:(pcl,pcl,点云,FPFH,直方图)