---
title: "贪婪投影三角化算法中的参数设置"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/greedy-projection-triangulation-parameters/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/08-图形学与三维重构/贪婪投影三角化算法中的参数设置.md"
content_hash: 01df331c2511248fe9c25729b7b4a4e5721d9a3e4b55ce1c62dc38c94433e65c
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# 贪婪投影三角化算法中的参数设置

> 创建时间：2020/5/20 0:31
[
![assets/csdn-logo.png](/media/87d49165b2d3849b59a2.png)
](https://www.csdn.net/ "CSDN首页")

[博客](https://blog.csdn.net/ "博客")

[学院](https://edu.csdn.net/ "学院")

[下载](https://download.csdn.net/ "下载")

[论坛](https://bbs.csdn.net/ "论坛")

[问答](https://ask.csdn.net/ "问答")

[直播](https://live.csdn.net/ "直播")

[招聘](http://job.csdn.net/ "招聘")

[APP](https://www.csdn.net/apps/download "APP")

[VIP会员](https://mall.csdn.net/vip "VIP会员")

![assets/csdn-sou.png](/media/4bd50f0278e67bc97300.png)

[](https://mp.csdn.net/)[创作中心](https://mp.csdn.net/)

[
_[附件不可用：assets/2_princepengy]_
](https://i.csdn.net/)

![assets/reprint.png](/media/ef8f495ed5b92e5c0f18.png)

[xuanzijie](https://me.csdn.net/wkxxuanzijie920129) 2016-05-14 11:19:24
![assets/%E8%B4%AA%E5%A9%AA%E6%8A%95%E5%BD%B1%E4%B8%89%E8%A7%92%E5%8C%96%E7%AE%97%E6%B3%95%E4%B8%AD%E7%9A%84%E5%8F%82%E6%95%B0%E8%AE%BE%E7%BD%AE__articleRead.png](/media/6bc9458e146a0d5f12eb.png)
 5011
![assets/%E8%B4%AA%E5%A9%AA%E6%8A%95%E5%BD%B1%E4%B8%89%E8%A7%92%E5%8C%96%E7%AE%97%E6%B3%95%E4%B8%AD%E7%9A%84%E5%8F%82%E6%95%B0%E8%AE%BE%E7%BD%AE__collect.png](/media/5019ebef3c1c92ba8250.png)
 收藏 5

展开

## 无序点云的快速三角化

##

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

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

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

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::Ptr cloud (new pcl::PointCloud);//定义点云对象指针**

 **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 n; _// 法线估计对象_**

 **pcl ::PointCloud::Ptr normals (new pcl::PointCloud); _// 存储估计的法线_**

 **pcl ::search::KdTree::Ptr tree (new pcl::search::KdTree); _// 定义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::Ptr cloud_with_normals (newpcl::PointCloud);**

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

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

 **pcl ::search::KdTree::Ptr tree2 (newpcl::search::KdTree);**

 ** _// 定义搜索树对象_**

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

 **pcl ::GreedyProjectionTriangulation 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);**

![assets/20130102_220858.png](/media/5cbb87107d8637816f6c.png)

图1 贪婪三角化之前点云

![assets/20130102_220949.png](/media/692a7dd5c477def08904.png)

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

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

2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
