先看一段代码,从代码讲起。
pcl::PFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::PFHSignature125> pfh_tgt;
pfh_tgt.setInputCloud(cloud_tgt);
pfh_tgt.setInputNormals(cloud_tgt_normals);
pcl::search::KdTree<PointT>::Ptr tree_tgt_fpfh(new pcl::search::KdTree<PointT>);
pfh_tgt.setSearchMethod(tree_tgt_fpfh);
pcl::PointCloud<pcl::PFHSignature125>::Ptr pfhs_tgt(new pcl::PointCloud<pcl::PFHSignature125>());
pfh_tgt.setRadiusSearch(0.05);
pfh_tgt.compute(*pfhs_tgt);
我们可以看到这段代码中使用了这个类:
pcl::PFHEstimation
这是提供包含点和法线的给定点云数据集的点特征直方图(PFH)描述符,并且继承自:
class pcl::PCLBase< PointT >
==============================================================================
此外,可以通过附加调用setSearchSurface(PointCloudConstPtr&)指定要使用的相邻点集。 此调用是可选的,当未给出搜索表面时,默认使用输入点云数据集。
要分清楚两种点,上面的概念才好理解:
第一种点的特征,用第二种点来描述,这就是特征估计。
因为总是需要setInputCloud(),所以我们可以使用
假设我们有两个点云,P = {p_1,p_2,… p_n}和Q = {q_1,q_2,…,q_n}。 下图显示了所有四种情况:
1、setIndices() = false, setSearchSurface() = false
无疑这是PCL中最常用的一种形式,第一类点是输入的全体点云数据,第二类点也是输入的全体点云数据。这种应用模式,将对输入的所有点进行特征估计,用来特征表示的相邻点集也都来自输入点云。当给定一个待估计的点,便用输入点云自身的其他点表示待估计点的特征。
如左1图所示, 首先,我们估计p_1的相邻点集,然后是p_2的相邻点集,依此类推,直到我们遍历完了P中的所有点。
2、setIndices()= true,setSearchSurface()= false
这种应用模式下,第一类点由输入点云数据与索引列表共同决定,即只估计输入点云中索引号在索引列表中的那些点,第二类的点则是完整的输入点云数据集。
如左2图所示,我们假设p_2的索引不在给定的索引列表中,因此不会估计p_2处的相邻点集或特征。
3、setIndices()= false,setSearchSurface()= true
这种应用模式下,第一类点是输入的全体点云数据,第二类点是则由setSearchSurface()指定。
如左3图所示,假设Q = {q_1,q_2}是第一类点,P是第二类点,即P是Q的搜索表面,则q_1和q_2的相邻点集或特征将用P中的点进行表示。
4、setIndices()= true,setSearchSurface()= true
这可能是最罕见的情况,其中给出了索引和搜索表面。在这种应用模式下,第一类点由输入点云数据与索引列表共同决定,第二类点由setSearchSurface()指定。
如左4图所示,假设q_2的索引不是为Q给出的索引向量的一部分,因此在q_2处不会估计相邻点集或者特征信息。
使用setSearchSurface()最有用的例子是:
当我们有一个点云密度非常大的输入数据集时,基于计算花费的考虑,我们不想估计其中所有点的特征,而是想更精准地估计某些关键点(比如用pcl_keypoints中的方法获得的),或者估计点云的下采样版本中的点(比如用体素格滤波器获得)。 在这种情况下,我们可以通过setInputCloud()传入下采样/关键点作为数据输入,并将原始点云数据作为setSearchSurface()传入,从而灵活高效地实现估计指定点的特征。
==============================================================================
这是一个基类,是实现大多数PCL特征直方图算法使用的方法。
这个区别可以在这段代码中看出来:
//加载类,然后声明一个指针。
pcl::PFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::PFHSignature125> pfh_src;
pfh_src.setInputCloud(cloud_src);
cout << "输入inputcloud指针大小为:" << cloud_src->size() << endl;
cout<<"输入inputcloud指针大小为: "<<pfh_src.getInputCloud()->size()<<endl;
可以看出来,getInputCloud()这个成员函数,是同指针cloud_src作用相同的。最后的结果为:
输入inputcloud指针大小为:4655
输入inputcloud指针大小为:4655
const IndicesConstPtr & indices
const IndicesPtr & indices
const PointIndicesConstPtr & indices
第四种为参数不同(只能用于有序点云):
void pcl::PCLBase< PointT >::setIndices (std::size_t row_start,
std::size_t col_start,
std::size_t nb_rows,
std::size_t nb_cols )
这是pcl::Feature< PointInT, PointOutT > 的几个派生类
从pcl::Feature< PointInT, PointOutT > 中派生出有11个类,分别是:
用于点云数据的差分法线尺度滤波(正态差估计)实现。
对于点云中的每一个点,减去两个搜索半径不同的法线(sigma_s, sigma_l),这些法线的差异提供了一个基于尺度的特征,可以进一步用于过滤点云,有点像高分差分在图像处理中的差异,但不是在表面。
当两个搜索半径关联为sigma_l=10*sigma_s时,两个搜索半径之间的八度可以作为一个滤波器带宽。对于合适的值和阈值,它可以用于表面边缘提取。
包含一个派生类: pcl::GFPFHEstimation< PointInT, PointLT, PointOutT >,GFPFHEstimation估计包含点和标签的给定点云数据集的全局快速点特征直方图(GFPFH)描述符。
包含了8九个派生类。
1、pcl::BoundaryEstimation< PointInT, PointNT, PointOutT >:用角度判据估计一组点是否位于表面边界上。边界特征的约定为:1、如果不能估计一个查询点的最近邻居,边界特征将被设置为NaN(不是一个数字),2、它是不可能估计一个点的边界属性,没有有限的三维坐标。因此,任何在x、y、z上包含NaN数据的点,其边界特征属性都被设置为NaN。
2、pcl::PFHEstimation< PointInT, PointNT, PointOutT >:fpfhestimate估计包含点和法线的给定点云数据集的快速点特征直方图(FPFH)描述符。PointOutT常用的类型是pcl::FPFHSignature33。PFH功能的约定是:1、如果不能估计查询点的最近邻居,PFH特性将设置为NaN(而不是一个数字),2、它是不可能估计一个PFH描述点,没有有限的三维坐标。因此,在x、y或z上包含NaN数据的任何点都将其PFH特性属性设置为NaN。
3、pcl::GRSDEstimation< PointInT, PointNT, PointOutT >:为包含点和法线的给定点云数据集估计基于辐射的全球表面描述符(GRSD)。
4、pcl::PPFEstimation< PointInT, PointNT, PointOutT >
5、pcl::PPFRGBEstimation< PointInT, PointNT, PointOutT >
6、pcl::PPFRGBRegionEstimation< PointInT, PointNT, PointOutT >
7、 pcl::RSDEstimation< PointInT, PointNT, PointOutT >:为包含点和法线的给定点云数据集估计基于辐射的表面描述符(局部表面曲线的最小和最大半径)。
8、pcl::SHOTEstimationBase< PointInT, PointNT, PointOutT, PointRFT >:估计一个包含点和法线的给定点云数据集的方向直方图描述符的特征。
利用积分图像对有有序点云进行表面法向估计。
待续未完。。。。