---
title: "对PCL的理解"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/pcl-library-understanding/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/08-图形学与三维重构/对PCL的理解.md"
content_hash: 0c47df280eb5e187840c49c6116f48e96a0630528cd9957e8fd2ff379e98d9cb
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# 对PCL的理解

> 创建时间：2020/5/14 18:22

## 概述

点云库(Point Cloud Library, PCL) 是在吸收了前人在3D信息获取、处理等领域的研究成果的基础上建立起来的大型开源C++编程库。起初是ROS（Robot Operating System）下由来自于慕尼黑大学和斯坦福大学Radu博士等人维护和开发的开源项目，主要应用于机器人研究应用领域，随着各个算法模块的积累，于2011年独立出来，正式与全球3D信息获取、处理的同行一起，组建了强大的开发维护团队。截止目前，发展非常迅速，不断有新的研究机构等加入，在多个全球知名公司的资金支持下，不断提出新的开发计划，代码更新非常活跃，至今已从1.0版本已经发布到1.11版本。
PCl封装了该领域大量的算法和数据结构，涉及到点云获取、滤波、分割、配准、检索、特征提取、识别、追踪、曲面重建、可视化等功能，在3D信息获取与处理上具有很高的地位。

## 结构

PCL已经移植到Windows、MacOS、Linux、Android和IOS系统上。PCL 点云库含有如下的函数处理库：Boost 共享指针、Eigen 矩阵库、FLANN（Fast Library for Approximate Nearest Neighbors）最近邻开源库、VTK（Visualization Tool Kit）视觉化工具函数库、CUDA 并行计算、OpenNI 开放自然交互框架、Qhull 凸包。通过调用组合 这些 C++函数模板库就可以实现点云处理相关的点云获取、点云滤波、点云分割、点云配准、特征点检索、点云特征值提取、姿势识别、追踪、点云曲面重建、点云可视化等功能模块。
PCL 利用 OpenMP（Open Multi Processing）、 GPU、CUDA 等先进高性能计算技术，通过并行化提高 PCL 点云库算法实时处理能力。 PCL 点云库中的 K 近邻搜索操作是基于 FLANN 所实现的，处理速度较快。PCL 点云 库中的所有模块和算法都是通过 C++中的 Boost 函数库中的共享指针来传送数据的，因 而避免了多次复制系统内存中已存在的数据的情况。
PCL 点云库的架构如图所示。

图
PCL中一种典型的处理管线的基本接口流程是：
创建处理对象（如过滤器、特征估计器、分割）；
使用setInputCloud将输入点云数据传递给处理模块；
设置一些参数
调用计算（或过滤、分段等）获取输出。
图
PCL 点云库分模块的设计大大加快了开发的效率。对于复杂问题，可以将问题分成几个模块来解决，由于每个模块实现一个子功能，开发过程中出现错误也能及时定位问题。同时重复使用模块，可以避免重复劳动，一个模块被多次使用，也便于标准化每个功能。PCL1.11版包含如下16个模块：

### 模块

(1) pcl_common库包含大多数PCL库使用的通用数据结构和方法。 核心数据结构包括PointCloud类和用于表示点，表面法线，RGB颜色值，特征描述符等的多种点类型。它还包含用于计算距离/范数，均值和协方差，角度转换的众多功能。 ，几何变换等。
(2) pcl_features库包含用于根据点云数据估算3D特征的数据结构和机制。 3D要素是空间中某个3D点或位置的表示，它们基于该点周围可用的信息来描述几何图案。 在查询点周围选择的数据空间通常称为k邻域。
(3) pcl_filters库包含用于3D点云数据过滤应用程序的异常值和噪声消除机制。
(4) pcl_geometry 库包含计算几何数据结构和算法。
(5) pcl_io库包含用于读取和写入点云数据（PCD）文件以及从各种传感设备捕获点云的类和函数。
(6) pcl_kdtree库提供了kd-tree数据结构，该结构允许快速最近的邻居搜索。
(7) pcl_keypoints库包含两个点云关键点检测算法的实现。 关键点（也称为兴趣点）是图像或点云中稳定、独特且可以使用定义明确的检测标准进行识别的点。
(8) pcl_octree库提供了从点云数据创建分层树数据结构的有效方法。这样就可以对点数据集进行空间分区、下采样和搜索操作。
(9) pcl_outofcore库为点云提供了八叉树数据结构，这些点云太大而无法存储在主存储器中。 数据位于一些辅助存储（磁盘）介质上的基于目录的八叉树目录中。 pcl_outofcore提供了用于构造和遍历场外八叉树的框架，用于将一组已注册的PCD文件转换为场外八叉树的命令行工具pcl_outofcore_process和用于渲染场外八叉树的pcl_outofcore_viewer。
(10) pcl_ recognition 模块包含用于对象识别应用程序的算法。
(11) pcl_registration库为两个有组织的（通用）数据集实现了过多的点云配准算法。
(12) pcl_sample_consensus库包含RANSAC之类的SAmple Consensus（SAC）方法以及诸如平面和圆柱体之类的模型。可以自由组合以检测点云中的特定模型及其参数。
(13) pcl_search库提供了使用不同数据结构搜索最近邻居的方法
(14) pcl_segmentation库包含用于将点云划分为不同簇的算法。 这些算法最适合处理由多个空间隔离区域组成的点云。 在这种情况下，群集通常用于将云分解成其组成部分，然后可以对其进行独立处理。
(15) pcl_surface库用于根据3D扫描的点云数据集重建原始表面。
(16) pcl_visualization使我们能够快速原型化和可视化在3D点云数据上运行的算法的结果。

## pcl_surface模块

点云库PCL的整体结构和功能已经在第二章2.2节进行了介绍。本节将介绍PCL当中与表面重建相关的模块。
pcl_surface模块该模块包含了点云曲面重建的基础算法和数据结构，用来实现对3D扫描获得的原始曲面的重构。重构的表面可以是：凸包或凹包、图形的网格表示、带法线的重采样或带法线的经过光滑或重采样的表面。
输入系统的点云数据有些会含有噪声，有些由多次扫描的结果构成却无法完美对齐，对于这样的数据集来说，进行光滑和重采样是很重要的。在光滑重采样的过程中，该模块可以对拟合的表面的复杂性进行调整，如果需要的话，该模块还可以进行法向量估计。
三角网格化是一种常用的由点集进行表面重建的方法。该模块提供了两种三角网格化算法：

  1. 原始点集的直接快速三角化

  2. 需要进行光滑和补洞操作的速度较慢的网格化算法。
如果用户需要对图形获取简化版的面表示或者需要提取模型的边界时，可以使用该模块提供的凸包或凹包创建功能。
surface模块目前包含17个类和2个函数，依赖于模块common，search，kdtree，octree。

### 类

 ConcaveHull< PointInT >
计算凹包
 ConvexHull< PointInT >
计算凸包
 EarClipping
封装了Ear Clipping三角化算法
 GreedyProjectionTriangulation< PointInT >
封装了贪婪投影三角化算法
 MarchingCubes< PointNT >
MarchingCubesHoppe< PointNT >
MarchingCubesRBF< PointNT >
封装了几种移动立方体算法
 MovingLeastSquares< PointInT, PointOutT >
封装了移动最小二乘法，用来进行法线估计、点云平滑和数据重采样
 OrganizedFastMesh< PointInT >
对有组织的点云数据集进行快速网格化
 Poisson< PointNT >
封装了泊松算法
 SurfaceReconstruction< PointInT >
表面重构类的基类

## pcl_common

## pcl_geometry

库包含计算几何数据结构和算法。

#### 关于面数

PolygonMesh包含成员 vector polygons
该数组的元素Vertices是一个类，Vertices的成员std::vector vertices才是顶点数组
因此对于三角面片模型mesh.polygons.size()就是三角面的个数

## PCD文件格式

PCL文件格式是点云库PCL的原生文件格式。本节将对其进行简单介绍。
PCD文件格式的出现不是重复造轮子，而是对现有的文件格式的一种补充。现存的文件格式出于某种原因无法支持一些PCL给n维点云处理带来的扩展。
PCD并不是第一个支持3维点云数据的文件类型。计算机图形和计算几何社区已经发明了不少文件格式，这些类型的文件用来描述激光扫描技术获取到的任意多边形和点云，例如：PLY、STL、OBJ、X3D等格式的文件。这些文件格式是在如今先进的传感技术和算法出现之前诞生的，显然，出于各种不同的目的、处于不同的时期创造出来的这些文件格式都会存在一些缺点。
PCD文件采用ASCII码进行编码。每个PCD文件都包含一个头部，这个头部对存储在PCD文件当中的点云的特定属性进行标识和声明。头部的每一项使用换行符(\n)进行分隔。
PCD格式文件有不同修订号，如PCD_V5,PCD_V6等，而PCL库中正式版本的是0.7，即PCD_V7。从0.7版本开始，PCD格式文件头主要包含的字段如下：

  1. VERSION - 指定PCD文件的版本

  2. FIELDS - 指定一个点的每个维度或字段的名称，例子如下：
FIELDS x y z # 表示每个三维点存储坐标值XYZ
FIELDS x y z rgb # 表示每个三维点存储坐标值XYZ和RGB颜色值
FIELDS x y z normal_x normal_y normal_z # 表示每个三维点存储坐标值XYZ和表面法向量

  3. SIZE - 指定每个维度或字段占用的字节数

  4. TYPE - 指定每个维度或字段的数据类型。
I表示有符号整数类型int8(char), int16 (short), and int32 (int)
U表示无符号整数类型uint8 (unsigned char), uint16 (unsigned short), uint32 (unsigned int)
F表示浮点型

  5. COUNT - 指定每个维度含有的元素个数。默认是1

  6. WIDTH
对于无组织的数据集，它表示点云的总点数。
对于有组织的数据集，它表示点云数据集的宽度（即每一行的点个数）。

  7. HEIGHT的含义类似。
注：类似于像素图片或矩阵这样，我们将数据被划分成很多行和很多列的点云称为有组织的数据集。

  8. VIEWPOINT - 标注数据集中顶点的获取视点。这可能会用于不同坐标系的顶点转换或者为某些数据集提供一些特性，诸如表面法向量集合这样的需要一致的方向的数据。
视点信息字段的形式是：三元组表示的平移量(tx ty tz) + 四元组表示的旋转量(qw qx qy qz)。其默认值是：VIEWPOINT 0 0 0 1 0 0 0

  9. POINTS - 标注点云中点的总数。

  10. DATA - 指示被存储的点云的数据类型。0.7版本支持两种数据类型: ASCII码和二进制。See the next section for more details.
PCL认为从DATA字段之后的下一个字节开始就是点云数据，这些数据将会被作为点集数据来解析。
下图是PCD文件的一个片段。
