这里主要针对PCL库中outofcore做一些介绍,查询外网文献以及相关模块的相关资料写出以下内容,该模块就是为了实现大规模点云的载入与显示,渲染等问题。 什么是outofcore outofcore,可以理解为使用内存映射的方法,来处理大规模点云无法载入到内存的问题,并且这里暂且将其翻译为“核外八叉树”,因为根据PCL中的实现方法,就是以八叉树的方法实现了内存映射的算法。 在PCL中基于外存(out of core)的数据处理方法,借助于八叉树理论在完成大规模点云的前提处理,并使用一种八叉树领域的搜索方法构建出散乱数据的拓扑结构。在可视化与计算机图形学领域,基于外核的算法是涉及用来处理大数据量模型运行在有限内存中的方法,简单来说,通过限制访问到一个小的,处于高速缓存中的模型的字块实现的。 首先我们看一下PCL 的Outofcore的模块介绍,该模块介绍是就是通过内存映射的方法以及八叉树的数据结构实现大规模点云的存储,数据位于某些辅助存储介质上基于目录的八叉树层次结构中,并且PCL——outofcore提供了构造和遍历outofcore八叉树的框架,其他的辅助函数在后面将会具体讲解。 PCL中的outofcore模块是由Urban Robotic整合起来,并且在PCL中实现了相关的例程,本文是在查阅了大量的相关资料的基础上总结而成,其中难免会有一些理解错误, 所以该框架能够满足一下几种条件: Out-of-core octree(核外八叉树)其实就是运行内存不足以载入大量的数据情况下,采用内存映射的方法,并且将数据存储为八叉树的形式保存在硬盘上。 为了满足数据查询的要求,这里采用了八叉树存储结构【以前的文章介绍过八叉树】八叉树是基于空间驱动的分区方法,如果数据分布严重的不均匀,这种方法可能会有严重不平衡的缺点,在这种情况下提出了使用KDtree,需要较少的内存用于树结构并且能够快速的实现数据的访问,但是一般pcl中的实现是主要使用了八叉树只希望该模块能够支持快速的数据更新,并且八叉树是非常适合的实现核外实现的算法,因为每个级别的分区都是相同的,因此不需要读取额外的信息。 一般来说这种方法很少有开源的方案供大家使用,其中PCL中就是一个较好的实现了核外八叉树模块的算法,开源的模块中只关注核外的八叉树实现以及可视化的部分,并且树的深度或者分辨率完全由用户自行定义。 以上是PCL1.7版本以上outofcore模块实现核外八叉树的类,其中对cJSON的依赖关系作为pcl_outofcore的依赖项已经链接在一起,并且将函数已经封装到两个独立的类OutofcoreOctreeNodeMetadata和OutofcoreOctreeMetadata PCL中实现outofcore的文件概括介绍 outofcore模块中实现核外八叉树的四个主要的hpp文件 1.octree.hpp 2. octree2.hpp 3.octree ram container.hpp 4. octree disk container.hpp 头文件: (a) octree base.h (b) octree base node.h (c) octree abstract node container.h∗ (d) metadata.h∗: 实现metadata的抽象类 (e) outofcore node data.h∗:实现核外节点层级的数据文件的接口(tree.oct idx) (f) outofcore base data.h∗:实现和外八叉树高层级数据接口(tree.octree JSON file) (g) OutofcoreDepthFirstIterator.h∗:核外八叉树的深度优先迭代器,可以直接访问外部节点的类 (h) OutofcoreIteratorBase.h∗: 基于pcl中octree模块中迭代器的抽象迭代器的类 (i) octree disk container.h: 磁盘容器的IO (j) octree ram container.h: 核外八叉树的核心数据结构(不再需要了) (k) outofcore node data.h: 包含主节点数据结构以及用于插入和查询的递归方法 (l) boost.h: 包含pcl outofcore中所需的所有boost头文件 (m) cJSON.h: 为了与PCL构建系统兼容,已进行了较小的修改 模板实现类的文件: (a)octree base.hpp (b) octree base node.hpp (c) octree disk container.hpp (d) octree ram container.hpp (e) OutofcoreDepthFirstIterator.hpp (f) OutofcoreIteratorBase.hpp 源文件 (a) cJSON.cpp (b) outofcore node data.cpp (c) outofcore base data.cpp Outofcore节点的格式 在磁盘上每个内部节点和叶子节点最多可以包含两个文件, *.oct idx 以oct_idx为后缀的JSON数据文件,格式为: { 可以使用OutofcoreOctreeNodeMetadata类直接访问此JSON数据。此类将接口抽象到磁盘上的JSON数据,因此从理论上讲,该格式可以轻松更改为XML,YAML或其他所需格式。 *.pcd pcd文件包含与该节点关联的所有点云的标准格式(v7 +)PCD文件。该文件同样也适用于所有叶子节点,但仅适用于内部(“分支”)节点(如果已构建LOD)。通过OutofcoreOctreeDiskContainer类可以访问此文件。 根节点包含了一个附件的文件 *.octree 其中包含有关八叉树结构的高级信息。格式为: { 如果想使用PCL 中的outofcore模块只需要添加 #include <pcl/outofcore/outofcore.h> #include <pcl/outofcore/outofcore_impl.h> 具体实现后面将会更加具体例程的解释 PCL中outofcore模块实现了该算法具有哪些特点 点云的插入 点云查询 深度级别(LOD level of Depth):多分辨率的核外八叉树 buildLOD:buildLOD使用多分辨率方法重新构建outofcore八叉树的LOD。每个分支节点是其叶子的子采样的并集。子采样的百分比由setSamplePercent确定,默认为0.125^depth-maxdepth LOD算法的细节请查看【5】 实现从大规模点云生成核外八叉树的文件系统的代码以及可视化的代码:https://www.cnblogs.com/li-yao7758258/p/12011234.html 根据上面的处理的代码的实现提示: 使用深度参数化的方法
在PCL中使用OutCore算法可以使用自带的工具里的可执行文件 构造过程可以通过深度或分辨率参数化。如果指定了分辨率(即最大叶尺寸),则自动计算深度。如果设置的树太深:LOD的构建可能需要很长时间 pcl_outofcore_viewer 使用不同的深度可视化的结果
下面这是使用了真实的PCD点云数据,来做实验例程。该PCD文件是一个大规模的街景点云,该点云有200MB 该点云直接可视化的结果,我们可以看到点云的数量以及加载的时间 我们分别使用了生成了不同的深度和不同分辨率的核外八叉树文件 使用我们outofcore_viewer可视化的结果 该算法针对更大的点云采用上述的方法生成核外八叉树的形式,也可以很好实现点云的可视化 References 关于我们 目前微信交流群不断壮大,由于人数太多,目前有两个群,为了鼓励大家分享,我们希望大家能在学习的同时积极分享,将您的问题或者小总结投稿发到群主邮箱主邮箱dianyunpcl@163.com。 |
|