无序点云的快速三角化

本小节描述了怎样使用贪婪投影三角化算法对有向点云进行三角化,具体方法是先将有向点云投影到某一局部二维坐标平面内,再在坐标平面内进行平面内的三角化,再根据平面内三位点的拓扑连接关系获得一个三角网格曲面模型。

贪婪投影三角化算法原理是处理一系列可以使网格“生长扩大”的点(边缘点),延伸这些点直到所有符合几何正确性和拓扑正确性的点都被连上。该算法的优点是可以处理来自一个或者多个扫描仪扫描得到并且有多个连接处的散乱点云。但该算法也有一定的局限性,它更适用于采样点云来自于表面连续光滑的曲面并且点云密度变化比较均匀的情况。

该算法的三角化过程是局部进行的,首先沿着一点的法线将该点投影到局部二维坐标平面内并连接其他悬空点,然后在进行下一点。所以这里我们设置如下参数:

1)函数SetMaximumNearestNeighbors(unsigned)和SetMu(double),这两个函数的作用是控制搜索邻域大小。前者定义了可搜索的邻域个数,后者规定了被样本点搜索其邻近点的最远距离,(是为了适应点云密度的变化),特征值一般是50-100和2.5-3(或者1.5每栅格)。

2)函数SetSearchRadius(double),该函数设置了三角化后得到的每个三角形的最大可能边长。

3)函数SetMinimumAngle(double)和SetMaximumAngle(double),这两个函数是三角化后每个三角形的最大角和最小角。两者至少要符合一个。典型值分别是10和120度(弧度)。

4)函数SetMaximumSurfaceAgle(double)和SetNormalConsistency(bool),这两个函数是为了处理边缘或者角很尖锐以及一个表面的两边非常靠近的情况。为了处理这些特殊情况,函数SetMaximumSurfaceAgle(double)规定如果某点法线方向的偏离超过指定角度(注:大多数表面法线估计方法可以估计出连续变化的表面法线方向,即使在尖锐的边缘条件下),该点就不连接到样本点上。该角度是通过计算法向线段(忽略法线方向)之间的角度。函数SetNormalConsistency(bool)保证法线朝向,如果法线方向一致性标识没有设定,就不能保证估计出的法线都可以始终朝向一致。第一个函数特征值为45度(弧度)、第二个函数缺省值为false。

本小节我们一起学习用贪婪投影三角化算法对有向点云进行三角化的例子。

代码

首先,在PCL(Point Cloud Learning)中国协助发行的书[1]提供光盘的第15章例3文件夹中,打开名为greedy_projection.cpp的代码文件,同文件夹下可以找到相关的测试点云文件table_scene_lms400_downsampled.pcd。

解释说明

下面对打开的文件关键语句进行解析。

#include                      //PCL中所有点类型定义的头文件

#include                        //打开关闭pcd文件的类定义的头文件

#include             //kdtree搜索对象的类定义的头文件

#include              //法向量特征估计相关类定义的头文件

#include                     //贪婪投影三角化算法类定义的头文件

以上代码是与本程序相关的类和函数的头文件声明。

//将一个xyz点类型的pcd文件打开并存储到对象PointCloud中

  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);//定义点云对象指针

  sensor_msgs::PointCloud2 cloud_blob;

  pcl::io::loadPCDFile ("table_scene_lms400_downsampled.pcd", cloud_blob);//加载bun0.pcd文件

  pcl::fromROSMsg (cloud_blob, *cloud);                                     //*数据最终存储在cloud中

由于例子中用到的pcd文件只有XYZ坐标,所以我们把它加载到对象PointCloud< PointXYZ>中,上面代码打开pcd文件,并将点云存储到cloud指针对象中。

 pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;//法线估计对象

  pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);//存储估计的法线

  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);//定义kd树指针

  tree->setInputCloud (cloud);                        //用cloud构建tree对象

  n.setInputCloud (cloud);                            //为法线估计对象设置输入点云

  n.setSearchMethod (tree);                          //设置搜索方法

  n.setKSearch (20);                                 //设置k搜索的k值为20

  n.compute (*normals);                              //估计法线存储结果到normals中

由于本例中使用的三角化算法输入必须为有向点云,所以需要使用PCL中的法线估计方法预先估计出数据中每个点的法线,上面的代码就完成该预处理。

 pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (newpcl::PointCloud<pcl::PointNormal>);

  pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);//连接字段,cloud_with_normals存储有向点云

由于XYZ坐标字段和法线字段需要在相同PointCloud对象中,所以创建一个新的PointNormal类型的点云来存储坐标字段和法线连接后的点云。

  pcl::search::KdTree<pcl::PointNormal>::Ptr tree2 (newpcl::search::KdTree<pcl::PointNormal>);

//定义搜索树对象

  tree2->setInputCloud (cloud_with_normals);                //利用点云构建搜索树

  pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;//定义三角化对象

  pcl::PolygonMesh triangles;                               //存储最终三角化的网格模型

以上代码是对三角化对象相关变量进行定义。

  gp3.setSearchRadius (0.025);//设置连接点之间的最大距离(即为三角形最大边长)为0.025

//设置各参数特征值,详见本小节前部分对参数设置的描述

  gp3.setMu (2.5);//设置被样本点搜索其邻近点的最远距离为2.5,为了适应点云密度的变化

  gp3.setMaximumNearestNeighbors (100); //设置样本点可搜索的邻域个数为100

  gp3.setMaximumSurfaceAngle(M_PI/4);   //设置某点法线方向偏离样本点法线方向的最大角度为45度

  gp3.setMinimumAngle(M_PI/18);         //设置三角化后得到三角形内角最小角度为10度

  gp3.setMaximumAngle(2*M_PI/3);        //设置三角化后得到三角形内角最大角度为120度

  gp3.setNormalConsistency(false);       //设置该参数保证法线朝向一致

gp3.setInputCloud (cloud_with_normals);//设置输入点云为有向点云cloud_with_normals

gp3.setSearchMethod (tree2);           //设置搜索方式为tree2

gp3.reconstruct (triangles);           //重建提取三角化

以上代码设置参数特征值和实际三角化的过程。

//附加顶点信息

  std::vector<int> parts = gp3.getPartIDs();

  std::vector<int> states = gp3.getPointStates();

对每个点来说,ID字段中中含有连接组件和该点本身的“状态”(例如 gp3.FREE, gp3.BOUNDARY或gp3.COMPLETED)可以被检索到。

编译并运行该程序

利用光盘提供的CMakeLists.txt文件,在cmake中建立工程文件,并生成相应的可执行文件。生成执行文件后,就可以运行了,在cmd中键入命令:

...>greedy_projection.exe

运行之后在三维可视化窗口可看到三角化重建后的曲面模型,如图2所示,对比重建前的点云与重建后的曲面模型,由于点云中有离群点所以重建结果在空间也有三角化的碎片,其他的部分重建效果一般,与点云本身密度和平滑程度有关,读者可以自行试验不同的处理后的点云,观察重建效果。

保存并观察结果

存储成VTK文件,可以作为网格模型做后续处理。

#include

...

saveVTKFile ("mesh.vtk", triangles);

图1 贪婪三角化之前点云

图2 贪婪三角化之后曲面模型

敬请关注PCL(Point Cloud Learning)中国更多的点云库PCL(Point Cloud Library)相关官方教程。

贪婪投影三角化算法中的参数设置相关推荐

  1. 【PCL-3】点云模型网格化--贪婪投影三角化算法

    贪婪投影三角化算法是一种对原始点云进行快速三角化的算法,该算法假设曲面光滑,点云密度变化均匀,不能在三角化的同时对曲面进行平滑和孔洞修复. 方法: (1)将三维点通过法线投影到某一平面: (2)对投影 ...

  2. PCL中GreedyProjection三角化算法简介与示例

    文章目录 前言 一.PCL点云三角化 1.1 Delaunay三角剖分 1.2 贪婪三角化 二.程序示例 总结 前言 Delaunay三角剖分最初应用于2维领域,而与Greedy三角化算法的结合,使之 ...

  3. c语言rr算法,[判断题] 在RR、PF、MAXC/I三种算法中,RR算法的用户公平性最好

    [判断题] 在RR.PF.MAXC/I三种算法中,RR算法的用户公平性最好 更多相关问题 在等差数列中,有,则此数列的前13项之和为()A.24B.39C.52D.104 已知y=xlnx,则y(10 ...

  4. libvlc_media_add_option 函数中的参数设置

    libvlc_media_add_option   函数中的参数设置 Usage: vlc [options] [stream] ... You can specify multiple stream ...

  5. 对等网络限制计算机数量吗,Windows对等网中网络参数设置和资源共享.doc

    学生实验报告 实验课名称: 计算机网络教程 实验项目名称:Windows对等网中网络参数设置和资源共享实验 Windows对等网中网络参数设置和资源共享 一.实验目的 1. 学习Windows支持的网 ...

  6. Hibernate的HQL中in参数设置和JdbcTemplete中的in参数

    写代码的时候突然忘记了,在此记录一下: Hibernate的HQL中in参数设置 public void updateDeviceByIDS(Long[] devicepkarr, DeviceINF ...

  7. CloudComparePCL Ear Clipping三角化算法

    文章目录 一.原理概述 二.PCL中的EarClipping 三.实现过程 四.实现效果 参考资料 一.原理概述 该算法是一个多边形三角化的算法,多边形的一个顶点和它相邻两个顶点可以组成一个三角形,如 ...

  8. Delaunay三角化算法

    1.首先了解一下什么是Delaunay三角网 Delaunay三角剖分是前苏联数学家 Delaunay在 1934年提出的:对于任意给定的平面点集 ,只存在着唯一的一种三角剖分方法 ,满足所谓的&qu ...

  9. Random Forest算法中的参数详解

    本篇不是介绍RF的,关于RF网上有很多通俗易懂的解释 西瓜书与统计学习方法等很多教材中的解释也都足够 本篇仅针对如何使用sklearn中的RandomForestClassifier作记录 一.代码怎 ...

最新文章

  1. PHP的学习--PHP的引用
  2. 利用动态规划求连续数组最大和以及最大子矩阵的和
  3. SAP Spartacus UnitDetailsComponent对应的UI插入,是在路由框架里完成的
  4. 静态变量读取属性文件_一种通过变量插值读取属性的方法
  5. java数据分析库,威力加强版
  6. 微信小程序navigateBack如何带参数
  7. insert exec 语句不能嵌套_Python基础入门知识点——if 语句简介
  8. [HDOJ1823] Luck and Love(线段树,树套树)
  9. QT编程-----------------窗口部件的使用(QWidget和QDialog)
  10. springmvc应用-自定义参数解析器
  11. sim868 建立tcp链接时的步骤所对应hex码
  12. GNURadio(一)
  13. html5无法绘制线条,Html5画布 - 使用fabric.js绘制完美线条或不使用
  14. 无法打开**,因为此版本的应用程序不支持其项目类型(.vcproj)
  15. wiki百科关于区块链的介绍
  16. Unity Addressable学习笔记一(整体介绍)
  17. Pandas+Pyecharts | 广州市已成交房源信息数据可视化
  18. 如何利用python刷微博粉丝_使用python进行新浪微博粉丝爬虫
  19. [转]帐号登录事件(事件编号与描述)
  20. 2023年全国最新会计专业技术资格精选真题及答案6

热门文章

  1. 你的线上办公软件,是帮手还是杀手?
  2. ICLR 2023 Oral | Batch Norm层等暴露TTA短板,开放环境下解决方案来了
  3. Python之父宣布退休
  4. 解释SAR/INSAR/DINSAR的概念
  5. 【博学谷学习记录】超强总结,用心分享|产品经理竞品分析报告怎么写?
  6. linux下的i2c
  7. JVM 虚拟机栈详解
  8. JVM虚拟机(3)_设置栈内存大小
  9. 速来围观,一分钟快速了解 BFF
  10. 基于PHP的网络教学平台设计与实现