PCL: Surface模块之GreedyProjectionTriangulation表面重建

参考文献:

        关于此类的详细信息和学术上的理论推导大家可以查看ZoltanCsaba Marton的文章“On Fast SurfaceReconstruction Methods for Large and Noisy Point Clouds”。

用法小结:

        顾名思义,这是个三角网格算法,对离散点云进行三维重建。通过阅读上述文献和不断的实验,我来分享一下使用此类的一些心得:

  1. 当然使用此类之前最好还是阅读一下上述文章,这对了解算法的流程和参数的意义很重要。
  2. 实际上此类是上述文章中所提供方法的一个阉割版本,在使用此类的过程中我发现其鲁棒性并没有那么强,甚至可以说相当的脆弱。
  3. PCL官网上的原话“处理无组织的点云,对局部平滑和密度平滑变化的点云有很好的效果”(英语吃力,多多谅解)。
  4. 三角网格之前需要进行法向量估计,点云需要光顺处理,此类对点云的和法向量的质量要求非常的高。
       总之,由于种种制约,我认为此类只适合粗略的重建(可以粗略看下结果);但若非得使用此类,那么对点云的预处理就会显得相当重要,当然随之而来的是巨大的工作量。

详细介绍:

参数输入输出口:

          此类由基类MeshConstruction派生,生成对象的方式也很简单,如下:

Pcl:: GreedyProjectionTriangulation gp3

        其中PointInT只能为pcl::PointNormal,因为此类并无估计法向量的功能,只能从外部输入。

成员函数:

        这里我就不一一介绍所有的成员函数了,只是把几个非常重要的成员函数给列出来,并给出其的使用方法。

  1. inline void setMu(double mu) mu是个加权因子,对于每个参考点,其映射所选球的半径由mu与离参考点最近点的距离乘积所决定,这样就很好解决了点云密度不均匀的问题,mu一般取值为2.5-3。

  2. inline void setMaximumNearestNeighbors (int nnn)临近点阈值设定。一般为80-100。

  3. inline void setSearchRadius (double radius) 搜索半径的设定(这个参数必须由用户指定),它决定的重建后三角形的大小。

  4. inline void setMinimumAngle (double minimum_angle)和 inline void setMaximumAngle(double maximum_angle) 三角形最大、最小角度的阈值。

  5. inline void setMaximumSurfaceAngle (doubleeps_angle) 两点的法向量角度差大于此值,这两点将不会连接成三角形,这个就恰恰和点云局部平滑的约束呼应,如果一个点是尖锐点那么它将不会和周围的点组成三角形,其实这个也有效的滤掉了一些离群点。这个值一般为45度。

  6. inline void setNormalConsistency (boolconsistent) 输入的法向量是否连续变化的。这个一般来讲是false,除非输入的点云是全局光滑的(比如说一个球)。

  7. 当然还有一些函数继承于MeshConstruction,kdtree的加速搜索,process的进行等等,这里就不一一介绍了。

效果展示:

        我使用的PCL版本为1.6.0 all-in-one,IDE为vs2010。源码和源点云文件我已上传到CSDN(点此下载)。首先我们看一下原始点云,我扫描的是一个长方体盒子(并没有顶盖和底盖):

PCL: Surface模块之GreedyProjectionTriangulation表面重建_第1张图片

        然后,我们设定参数,进行处理,所需要的核心代码如下(我只是列出了部分需要设定参数的代码):

pcl::NormalEstimation n;
n.setKSearch (30);  // 法向量估计
pcl::GreedyProjectionTriangulation gp3;
gp3.setSearchRadius (0.05);  // 搜索半径
gp3.setMu (2.5);  // 加权因子
gp3.setMaximumNearestNeighbors (300);  // 最近临近点最值
gp3.setMaximumSurfaceAngle(M_PI/2);  // 法向量夹角差值阈值
gp3.setMinimumAngle(M_PI/36);
gp3.setMaximumAngle(5*M_PI/6);  // 三角形角度约束
gp3.setNormalConsistency(false);

        由上述代码片可知:一共有8个数据需要设定,这里我们修改不同的数据看下效果图:

PCL: Surface模块之GreedyProjectionTriangulation表面重建_第2张图片

        8个参数分别为:8,10,2.5,100,pi/4,pi/18,2×pi/3,false。

PCL: Surface模块之GreedyProjectionTriangulation表面重建_第3张图片

        将参数改为:8,50,2.5,100,pi/4,pi/18,2×pi/3,false,也就是在上述基础上将搜索半径增加为50,由于增大了单元三角形的面积,所以图中画红圈的空洞已经被填充。

PCL: Surface模块之GreedyProjectionTriangulation表面重建_第4张图片

        这里我们将8个参数改为:8,50,2.5,100,pi/2,pi/18,2×pi/3,false,也就是在上述基础上将两点法向量差阈值增加为pi/2,尖锐点的部分得以填充。

PCL: Surface模块之GreedyProjectionTriangulation表面重建_第5张图片

        我们再将参数改为:8,50,2.5,100,pi/2,pi/36,5×pi/6,false,也就是在上述基础上将三角形的角度范围扩大到5度到150度(代码中用弧度表示),三角形的形态的到大幅度扩充,由图可以看出左右两个面的空洞已经基本消灭。

PCL: Surface模块之GreedyProjectionTriangulation表面重建_第6张图片

        当然,这个时候肯定少不了斯坦福小兔子,这里我把8个参数设为:30,0.05(我自己扫描的点云单位是mm,小兔子的是m),2.5,300,pi/2,pi/36,5×pi/6,false。最终的效果如上述3幅图片,小的空洞依稀可见。我认为有两方面原因:(1)法向量的估计误差(我使用的是PCL中提供的基本法向量估计算法);(2)GreedyProjectionTriangulation算法本身的局限性。

        对了我的邮箱为[email protected],我也是刚刚接触这个领域,希望与大家多多交流共同学习、共同进步。

你可能感兴趣的:(Point,Cloud,Library(点云库))