PCL中八叉树(octree)的原理及应用案例
一、什么是八叉树ocTree?
1.八叉树原理
上世纪80年代,八叉树结构被提出来,用来表示空间中的区域划分,简单来说,空间可以被分为8个象限,想象一下假设空间中存在一个笛卡尔坐标系,则该坐标系将空间分为了8个象限,每个象限又可以按照这种方式再建立一个笛卡尔坐标系,再划分为8个象限,以此类推,空间中任何一块区域都可以被n个笛卡尔坐标划分。

以上图为例:
如果所生成的八叉树的节点可分为三类:
灰节点: 它对应的立方体部分的为V所占据;
白节点: 它对应的立方体没有V的内容;
黑节点: 它对应的立方体全部为V所占据。
后两类又称为叶节点。立方体的八叉树的逻辑结构是这样的:将立方体内的空间划分,并记录成树结构,其上的节点要么是叶节点,要么是有八个子节点的灰节点。
因此任意空间都可以被划分为树状结构,而如果要找到某子空间,只需遍历八叉树即可找到,且效率较高。
关于八叉树的存储结构,有兴趣深入研究的同学可以参考这篇文章:
https://blog.csdn.net/qq_37855507/article/details/90957798
二、八叉树应用案例
1.点云压缩
点云由巨大的数据集组成,这些数据集描述了与距离、颜色、法线等附加信息相关的三维点。此外,它们可以以很高的速度创建,因此会占用大量内存资源。一旦点云必须在速率受限的通信信道上存储或传输,就必须想办法对这类数据进行压缩。点云库提供点云压缩功能。它允许编码所有类型的点云,包括无组织的点云,其特征是不存在点索引、分辨率、密度和/或点顺序。此外,底层的八叉树数据结构能够有效地合并来自多个数据源的点云数据。

下面,我们将解释如何有效地压缩单点云和点云流。在给出的示例中,我们使用OpenNIGrabber捕获点云,并使用PCL点云压缩技术进行压缩。请看如下示例代码:
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/compression/octree_pointcloud_compression.h>
#include <stdio.h>
#include <sstream>
#include <stdlib.h>
#ifdef WIN32
# define sleep(x) Sleep((x)*1000)
#endif
class SimpleOpenNIViewer
{
public:
SimpleOpenNIViewer () :
viewer (" Point Cloud Compression Example")
{
}
//在OpenNIGrabber捕获循环执行的回调函数中(以下部分代码),首先将捕获的点云压缩到stringstream缓冲区中。接下来是一个解压步骤,该步骤将压缩的二进制数据解码为一个新的点云对象。然后将解码后的点云发送到点云查看器。
void
cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud)
{
if (!viewer.wasStopped ())
{
// 存储被压缩后点云的流
std::stringstream compressedData;
// 创建输出的解压缩后点云指针
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloudOut (new pcl::PointCloud<pcl::PointXYZRGBA> ());
// 压缩点云
PointCloudEncoder->encodePointCloud (cloud, compressedData);
// 解压缩点云
PointCloudDecoder->decodePointCloud (compressedData, cloudOut);
// 显示解压缩后的点云
viewer.showCloud (cloudOut);
}
}
void
run ()
{
// 布尔值:是否显示统计信息(是)
bool showStatistics = true;
// 配置文件列表查看这个头文件: /io/include/pcl/compression/compression_profiles.h
// 此处是枚举类型,包括压缩配置(分辨率,在/离线,颜色信息)
pcl::io::compression_Profiles_e compressionProfile = pcl::io::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;
// 实例化八叉树点云压缩用于编码和解码
PointCloudEncoder = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA> (compressionProfile, showStatistics);
PointCloudDecoder = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA> ();
// 创建OpenNI设备的抓取器
pcl::Grabber* interface = new pcl::OpenNIGrabber ();
// 定义回调函数,用于回调点云采集设备
std::function<void(const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f =
[this] (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr& cloud) {
cloud_cb_ (cloud); };
// 注册链接回调函数.此例子中是带有颜色信息的点云。
boost::signals2::connection c = interface->registerCallback (f);
// 开始接收点云,
interface->start ();
while (!viewer.
1万+


的原理及应用案例点云压缩,搜索,空间变化&spm=1001.2101.3001.11974&articleId=123028763&d=1&t=3&u=2ab0ade73c02457383c47b4a637e4738)

被折叠的 条评论
为什么被折叠?



