PCL模块介绍

原文链接:PCL Walkthrough

PCL官网文档: Documentation

PCL(Point Cloud Library)是在吸收了前人点云相关研究基础上建立起来的大型跨平台开源C++编程库,它实现了大量点云相关的通用算法和高效数据结构,涉及到点云获取、滤波、分割、配准、检索、特征提取、识别、追踪、曲面重建、可视化等。支持多种操作系统平台,可在Windows、Linux、Android、Mac OS X、部分嵌入式实时系统上运行。如果说OpenCV是2D信息获取与处理的结晶,那么PCL就在3D信息获取与处理上具有同等地位,PCL是BSD授权方式,可以免费进行商业和学术应用。

Overview

PCL划分成了许多模块化的库,下图展示了最重要的一组已发布的PCL模块。

功能一览

下图是百度百科上的PCL架构图。

架构图

Filters(滤波器)

下图展示了一个消除噪声的案例。

特征

由于测量误差,某些数据集呈现出大量阴影点。这使得局部点云3D特征的估计变得更为复杂。

其中的一些异常值可以通过对每个点的领域进行统计分析过滤除,同时修建那些不符合特定标准的点。

PCL中稀疏异常值去除实现是基于距离分布的计算,这里的距离指的是每个点到相邻点的距离。

对于每个点,计算从它到所有邻近点的平均距离。假设得到的分布是具有均值和标准偏差的高斯分布,所有其平均距离在【全局距离平均值和标准偏差定义的区间】之外的点,可以被视为异常点,并且从数据集中裁剪掉。

Filters 模块教程 http://pointclouds.org/documentation/tutorials/#filtering-tutorial

相关模块

Features(特征)

3D Features tutorial 中有关于PCL中如何使用Fearture的理论入门知识。

Features库包含用于从点云数据进行3D特征估计的数据结构和机制。

3D特征是以特定3D点或空间位置为表征,其以该点附近的可用信息来描述geometrical pattern

在查询点周围选择的数据空间通常被称为K领域

下图展示了所选查询点及其选定K领域。

K领域

两个使用最广泛的几何点特征是查询点 $p$ 所在曲面的估计曲率和法线。它们都被认为是局部特征,因为它们使用有它的 $k$ 个最近邻提供的信息表征了一个点。

为了高效地确定这些邻近点,通常使用八叉树(octress)或KD树(KD-trees)等空间分解技术将输入数据集分割成更小的块,然后在那个空间执行最近邻搜索。

根据应用,可以选择在 $p$ 附近确定固定数目的 $k$ 个点,也可以选择在【以 $p$ 为中心, $r$ 为半径的】球体内找到的所有点。

毫无争议的是,估计点 $p$ 处的表面法线和曲率变化的最简单的方法就是执行 $k-邻近点$ 曲面片的特征分解(即计算特征向量和特征值)。 因此,对应于最小特征值的特征向量近似为点 $p$ 处的表面法线 $n$ ,同时利用特征值进行估计表面曲率变化为:

$$ {λ_0} \over {λ_0+λ_1+λ_2} $$ $其中,λ_0<λ_1<λ_2$

Features 模块教程 <http://pointclouds.org/documentation/tutorials/#features-tutorial>

相关模块

Keypoints(关键点)

Keypoints库包含了两个点云关键点检测算法的实现。

关键点(也称为兴趣点)是图像或者点云中稳定、独特,且可以用明确定义的检测标准进行识别的点。

通常情况下,点云中关键点的数目远小于点云中点的总数目,并且当与每个关键点处的局部特征描述符结合使用时,关键点和描述符可用于形成一个紧凑但具有描述性的表征,来描述原始数据。

下图展示了从距离图像中提取NARF关键点:

关键点

Keypoints 模块教程 <http://pointclouds.org/documentation/tutorials/#keypoints-tutorial>

相关模块

Registration(注册)

将几个数据集组合成为一个全局一致模型通常是使用称为注册的技术来实现的。

关键在于确定数据集之间的对应点,并找到一个能够最小化对应点之间距离(对齐误差)的转换。这个过程是重复的,因为对应关系搜索受到数据集的相对位置和方向的影响。

一旦确定对齐误差低于设定的阈值,就认为注册完成。

Registration库为有组织的和无组织的(通用)的数据集实现了大量的点云注册算法。例如,PCL包含一组常大的算法用来估计多组对应关系,同时包含拒绝不良对应关系的方法,以及可靠的估计变换方法。

多组数据集

注册

Registration 模块教程 http://pointclouds.org/documentation/tutorials/#registration-tutorial

相关模块

Kd-tree(K维树)

Kd-tree tutorial 有PCL中Kd-trees如何起作用的初级理论解释。

Kd-tree库使用FLANN提供kd-tree的数据结构,该结构允许快速的最近邻搜索。

Kd-tree(K-dimentinal tree)是一种空间分割数据结构,它将一组 $k$ 维点存储在树结构中,从而实现高效地范围搜索和最近邻搜索。

在处理点云数据时,最近邻搜索是一项核心操作,可用于查找【点或特征描述符组之间的】对应关系,或者定义一个或多个点周围的局部领域。

Kd-tree

Kd-tree2

Kd-tree 模块教程 http://pointclouds.org/documentation/tutorials/#kdtree-tutorial

相关模块

Octree(八叉树)

Octree库提供了从点云数据创建分层数据结构的有效办法。这可以对点数据集进行空间区分,下采样和搜索操作。

每个八叉树节点有八个子节点或者没有子节点。根节点描述了封装所有点的立方体边界框。在树的每一层,空间被二分进行细分,这使得体积分辨率增加。

OCtree库提供了有效的最近邻搜索例程,例如

  • Neighbors within Voxel Search
  • K Nearest Neighbor Search
  • Neighbors within Radius Search

它会自动调整点数据集的维度。

一组叶节点类提供附加功能,例如空间“占用”和“每个体素的点密度”检查。

序列化和反序列化功能可以将八叉树结构有效地编码为二进制格式。

此外,内存池实现可以在需要高速创建八叉树的场景中减少高耗的内存分配和重新分配操作。

下图展示了最低树级别的八叉树节点的体素边界框。八叉树体素围绕斯坦福兔子表面的每个3D点。红点表示点数据。这幅图是用octree_viewer创建的。

八叉树

Octree 模块教程 http://pointclouds.org/documentation/tutorials/#octree-tutorial

相关模块

Segmentation(分割)

Segmentation库包含用于将点云分割成不同群集的算法。

这些算法最适合处理有多个空间隔离区组成的点云。

在这种情况下,聚类通常用于将云分解成组成部分,然后可以独立处理。

cluster extraction tutorial 有关于集群方法如何工作的理论入门。下面两幅图说明了平面模型分割(上)和柱面模型分割的效果(下)。

平面模型分割

柱面模型分割

Segmentation 模块教程 http://pointclouds.org/documentation/tutorials/#segmentation-tutorial

相关模块

Sample Consensus(抽样一致)

Sample Consensus库保存了类似RANSAC这样的抽样一致方法和类似平面和柱体这样的模型。

这些可以自由组合以检测点云中的特定模型及其参数。

Random Sample Consensus tutorial可以找到解释抽样一致算法如何工作的理论入门。

这个库中实现的一些模型包括:线条,平面,柱体和球体。平面拟合经常用于检测常见室内表面,如墙壁,地板和桌面。其他模型可用于检测和分割具有常见几何结构的物体(例如,将杯子拟合为圆柱体模型)。

抽样一致

Sample Consensus 模块教程 http://pointclouds.org/documentation/tutorials/#sample-consensus

相关模块

Surface(表面/曲面)

Surface库处理的是从3D扫描中重建原始曲面。

根据当前的任务,这可以是比如船体,用网格表示或具有法线的平滑/重采样表面。

如果点云数据噪声嘈杂,或者有多个未完全对齐的扫描组成,平滑和重采样就很重要了。可以调整表面估计的复杂性,并且如果有需要,可以相同的步骤中估计法线。

重采样

网格划分是一种通用的方法来用点数据创建一个表面,目前提供了两种算法:非常快的原始点的三角化方法和较慢的基于平滑和填充的网格划分方法

网格划分

创建凸面或凹面船体很重要,比如,当需要简化表面的表示或者当需要提取边界的时候。

Surface 模块教程 http://pointclouds.org/documentation/tutorials/#surface-tutorial

相关模块

Range Image(距离图像/深度图)

Range_image库包含两个用于表示和处理深度图的类。

距离图像(或深度图)是指其像素表示距传感器原点的距离或深度的图像。

距离图像是常见的3D表示形式,并且通常有立体相机或ToF相机生成。

了解了相机的内部标定参数之后,可将距离图转换为点云。

距离图像

Range Image 模块教程 http://pointclouds.org/documentation/tutorials/#range-images

相关模块

I/O(输入输出)

IO库包含了读取和写入点云数据(PCD)文件的类和函数,以及从各种传感器设备捕获点云。

以下教程介绍了其中一些功能:

I/O 模块教程 http://pointclouds.org/documentation/tutorials/#i-o

相关模块

Visualization(可视化)

Visualization库是为了能够快速原型化和快速将【在3D点云数据上运行算法的结果】可视化而构建的,与OpenCV用于显示2D图像和在屏幕上绘制基本2D形状的highgui例程类似。

该库提供了下面这些方法:

  • pcl::PointCloud<T> format 渲染和设置任何 $n-D$ 点云数据的视觉属性(颜色、点大小、不透明度等);

Bunny

  • 从一组点或从参数方程画出屏幕上的基本3D形状(例如圆柱体、球体、线、多边形等);

3D形状

  • 用于2D图的直方图可视化模块(PCLHistogramVisualizer);

直方图

  • 用于pcl::PointCloud<T> 数据集的多种几何和颜色处理程序;

几何处理

颜色处理

  • pcl::RangeImage 的可视化模块

深度图可视化

这个包使用VTK库进行深度图的3D渲染和2D操作。

要实现自己的可视化工具,可以参考库中的测试和案例。

Visualization 模块教程 http://pointclouds.org/documentation/tutorials/#visualization-tutorial

相关模块

Common(公共库)

Common库包含了大多数PCL库使用的公共数据结构和方法。

核心数据结构包括PointCloud类和用于表示点,曲面法线,RGB颜色值,特征描述符等的多种点类型。

它还包括用于计算距离/范数,均值和协方差,角度转换,几何变换等大量函数。

Search(搜索)

Search库提供了使用不同数据结构搜索最近邻的方法,包括:

  • KdTree
  • Octree
  • brute force
  • specialized search for organized datasets

相关模块

Binaries

这一节提供了PCL中常用工具的快速参考。

  • pcl_viewer :一种可视化PCD(点云数据)的快速方法。有关PCD文件的更多信息可以在PCD file format tutorial找到。
    语法是:pcl_viewer <file_name 1..N> <pcd or vtk> <options>,option选项如下:

    • -bc r,g,b = 背景颜色
    • -fc r,g,b = 前景颜色
    • -ps X = 点大小(1..64)
    • -opaque X = 渲染点云不透明度(0..1)
    • -ax n = 使能屏幕上显示XYZ轴,并缩放到n
    • -ax_pos X,Y,Z = 如果坐标使能,设置它们空间中的X,Y,Z位置(默认0,0,0)
    • -cam () = 使用给定的相机设置作为初始视图
      (*) [Clipping Range / Focal Point / Position / ViewUp / Distance / Field of View Y / Window Size / Window Pos] 或使用包含同样信息的 <filename.cam>文件
    • -multiview 0/1 = 使能/关闭自动-多视 视点渲染(默认关闭)
    • -normals 0/X = 关闭/使能 每个第X点的曲面法线的显示(默认关闭)
    • -normals_scale X = 将正常单位向量调整为X(默认0.02)
    • -pc 0/X = 关闭/使能每个第X点的主曲率的显示(默认关闭)
    • -pc_scale X = 将主曲率向量调整为X(默认0.02)

    (注意:对于多个.pcd文件,需要提供多个-{fc,ps,opaque}等参数;它们将自动分配给正确的文件)

    用例:

    pcl_viewer -multiview 1 data/partial_cup_model.pcd data/partial_cup_model.pcd data/partial_cup_model.pcd

    以上将加载partial_cup_model.pcd文件3次,并创建一个多视口渲染。

    viewer

  • pcd_convert_NaN_nan:将“NaN”值转换为“nan”值。(注意,从PCL版本1.0.1开始,NaN的字符串表示形式为“nan”。)

    用法:pcd_convert_NaN_nan input.pcd output.pcd

  • convert_pcd_ascii_binary:将PCD(点云数据)文件从ASCII转换为二进制文件,反之亦然。

    用法:convert_pcd_ascii_binary <file_in.pcd> <file_out.pcd> 0/1/2 (ascii/binary/binary_compressed) [precision (ASCII)]

  • concatenate_points_pcd:将两个或多个PCD(点云数据)文件的点连接成为一个PCD文件。

    用法:oncatenate_points_pcd <filename 1..N.pcd>

    (注意:结果PCD文件会是“output.pcd”)

  • pcd2vtk:将PCD(点云数据)文件转换为VTK格式。

    用法:pcd2vtk input.pcd output.vtk

  • pcd2ply:将PCD(点云数据)文件转换为PLY格式。

    用法:pcd2ply input.pcd output.ply

  • mesh2pcd:将CAD模型转换为PCD(点云数据)文件,使用射线追踪操作。

    语法:mesh2pcd input.{ply,obj} output.pcd <options> ,option选项如下:

    • -level X = 曲面细分球体级别 (默认值:2)
    • -resolution X = 角度增量的球体分辨率 (默认值: 100 deg)
    • -leaf_size X = 体素网格的XYZ叶片大小,用于数据缩减 (默认值: 0.010000 m)
  • octree_viewer:八叉树的可视化

    语法:octree_viewer <file_name.pcd> <octree resolution>

    用例:./octree_viewer ../../test/bunny.pcd 0.02

    八叉树可视化

如有侵权,立马删除。