如何将三维点云三角面重构

关于三维点云 的重构方法,有很多,但是我是初学者带面编程能力有点弱,所以想请教大神有这方面的代码可以借鉴吗

https://blog.csdn.net/zkl99999/article/details/56511727

O. 初始化参数

一. 初始化一个三角面片:

  1. 计算所有点的重心;

  2. 找到离重心最近的一个点,设为ptn0;

  3. 在ptn0的领域内,计算出最远的距离,找到距离它1/3len(但还是大于最小距离)的一个点作为ptn1;

    1. 在领域中找到一个点ptn2,使得它们构成的外接圆的半径最小;

由这三个点构成一个三角面片,并且标记为边界点。

二. 构建Mesh:

  1. 首先 从Mesh当中找到所有的边界半边;

  2. 对于其中的每一条边界半边:如果端点还可以扩展,则进行如下操作,否则下一条:

    1) 首先从这条边的上下两条邻边进行扩展,如果扩展成功则对新增加的那条边也进行三角重建;并且将重建构成的新的半边加入到半边集合当中。

    2) 如果不能在上下两条边中进行扩展,则找出这两个端点的所有未使用的邻近点;

    3) 对上面的每一个邻近点,构成三角形的第三个端点,但是要符合几个要求:

          A. 新加入的两条边长度要小于阈值;
    
          B. 三角形的内角都在一定的范围内: (20~100°)
    
          C. 形成的二面角要大于阈值。
    

    D. 形成的三角面片的外接圆半径最小。

    E. 形成的新的面里面不能有边界点或者不能再扩展的点

    4)找到符合重建的点以后,重建一个三角面片,同时重建新加入的两条边(只在前后两条边当中去重建),最后重建新加入的两条边放入到半边队列当中。

5) 如果某条半边的两个点都不能重建,则删除,直到半边队列当中没有边为止。

三.删除重建有重叠的三角片:

  1. 首先找到边界点但非孤立点;

    1. 对于每一个这样的点找到它的领域的边界面;如果边界面的个数小于2则没有重叠;如果有面与面之间的角度< 30° 则表示有重叠。
    2. 如果出现重叠,将这些面删掉。

四、更新各个点的使用情况

遍历Mesh当中的每一个点, 对相应的点赋值上相应的标志位: 边界点: PT_BOUND 孤立的点:PT_NOT_USED 在面里面的点PT_IN_MESH 其余的点 PT_TRI_USED

五、对孔洞进行填补

  1. 找到各个孔洞:

    A。找到所有的边界边放在一个队列当中;
    

    B. 从其中的一条半边开始,找到那条以这条边的起点为终点的半边,依次去找,直到找到以第一条的终点为起点的边为止;就找到一个孔洞,其余的类似;

    C. 判断孔洞的有效性:1. 如果只有三条边,则可能是一个孤立的面
    

2.如果是4条边可能是两个孤立的面。。

3.如果边数载2--8 之间的时候,有共同的顶点也不行

    遇到上述3种情况都需要把面删除掉。
  1. 对孔洞进行填补:

    1).* 如果边的数目小于20 删掉它周围的面,重新来,;如果是一般的孔洞则进行填补,否则不填补。

    2). 进行以上操作以后,再进行两次 提取孔洞。进行填补的工作。

  2. 再次更新点的使用信息,和上面一样

最简单的方法就是三角形分割方法了。
point_out是点云数据(N行3列)
tri_out = delaunay(point_out(:,1),point_out(:,2),point_out(:,3)); %点云数据的三角形分割参数
qm_out = trisurf(tri_out,point_out(:,1),point_out(:,2),point_out(:,3),'LineStyle','none'); %用三角形分割方法进行三维重建

%% 稍微加一些光影效果 看起来能更像一些
material shiny % dull shiny
light('position',[0 -10 1.5],'style','infinite') %'local' 'infinite'
lighting phong; % flat gouraud phong none