八叉树及应用

article/2025/10/28 23:06:32

八叉树及应用

    • 八叉树的定义
    • 如何搭建一颗八叉树
    • 八叉树的作用
    • 八叉树的实际应用

上一次介绍了KD树及应用,这次介绍一下八叉树,主要从定义、结构、作用及应用几个方面进行理解。

八叉树的定义

八叉树是在描述三维空间坐标场景中常用的一种数据结构。如下图所示,一个空间自身作为根节点,当需要细分内部区域时,将空间划分为八个小空间,即八个子节点,若某个小节点还需要细分,则继续往下划分八个子节点,就这样将一个空间不断的划分为子空间,都用根节点和其八个子节点连接起来,这样的树状存储结构就是八叉树。
在这里插入图片描述
特别注意:树中任一节点的子节点恰好只会有八个,或零个,也就是子节点不会有0与8以外的数目。

如何搭建一颗八叉树

1、设定最大递归深度。这决定了最小子空间的包围盒大小
2、以尺寸最大的场景作为根节点。可以是立方体或长方体
3、依序将单位元元素丢入能包含且没有子节点的立方体。是指将你想要存储的坐标归类到所属子节点的包围盒。
4、若没达到最大递归深度,就进行细分八等份,再讲该立方体所装的单位元元素全部分组给八个子立方体。
5. 若发现子立方体所分配到的单位元元素数量不为零且跟父立方体一样,则该子立方体停止细分
(因为根据空间分割理论,细分的空间所得到的分配必定较少,若是一样的数目,再怎么切,数目还是一样)
6、重复3,直到达最大递归深度。

八叉树的作用

八叉树的结构决定了八叉树具有的功能,由于每个元素都在树结构中,可以快速定位到各个元素,并且时间复杂度很小。可以用来碰撞检测、邻域检索、空间变化检测、压缩等功能。
优点,使用八叉树可以快速进行三维目标的集合运算,如交、并、补、差等,亦可快速进行最邻近区域或点的搜索。
缺点,存储空间消耗。

八叉树的实际应用

1、八叉树在PCL中的压缩例子

// 用于显示数据
pcl::visualization::CloudViewer viewer;
// 用于压缩、解压点云数据
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA>* PointCloudEncoder;
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA>* PointCloudDecoder;
// 用于接收到设备数据时的回调响应
void  cloud_callback(const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud);//  interface->start ();之后,设备获取一帧数据,就回调一次次函数,不断刷新压缩后的点云
void  cloud_callback(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);}}int main()
{// 压缩选项详情在: /io/include/pcl/compression/compression_profiles.hpcl::io::compression_Profiles_e compressionProfile = pcl::io::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;// 初始化压缩和解压缩对象  其中压缩对象需要设定压缩参数选项,解压缩按照数据源自行判断PointCloudEncoder = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA> (compressionProfile, true);PointCloudDecoder = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA> ();//创建从OpenNI获取点云的抓取对象pcl::Grabber* interface = new pcl::OpenNIGrabber ();// 建立回调函数boost::function<void(const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f = boost::bind (&SimpleOpenNIViewer::cloud_callback, this, _1);//建立回调函数和回调信息的绑定boost::signals2::connection c = interface->registerCallback (f);// 开始接受点云的数据流interface->start ();while (!viewer.wasStopped ()){sleep (1);}interface->stop ();// 删除压缩与解压缩的实例delete (PointCloudEncoder);delete (PointCloudDecoder);
return 0;
}

在这里插入图片描述

2、体素内邻近搜索、K邻近搜索、半径内邻近搜索

void main ()
{pcl::PintCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<PointXYZ>);cloud->width=1000;cloud->height=1;cloud->pionts.resize(cloud->width*cloud->height);for(int i=0;i<cloud->points.size();i++){cloud->points[i].x=1024.0f*rand()/(RAND_MAX+1.0f);cloud->points[i].y=1024.0f*rand()/(RAND_MAX+1.0f);cloud->points[i].z=1024.0f*rand()/(RAND_MAX+1.0f);}pcl::octree::OctreePointCloudSearch<pcl::PointXYZ>octree(128.0f)//初始化octree,分辨率为128.0octree.setInputCloud(cloud);octree.addPointsFromInputCloud();// 根据点云搭建octreevector<int>piontIndexVec;// 存储体素邻近的点的索引//体素内邻近搜索if(octree.voxelSearch(searchPoint,piontIndexVec))//searchPoint为搜索的关键点{for(int i=0;i<piontIndexVec.size();i++){// 每个点的操作}}//K邻近搜索int k=10;vector<int>knnIndex;vector<float>knnDistance;if(octree.nearestKSearch(searchPoint,k,knnIndex,knnDistance)>0){//  相关操作}//半径内邻近搜索float radius=256.0f;vector<int>radiusIndex;vector<float>radiusDistance;if(octree.radiusSearch(searchPoint,radius,radiusIndex,radiusDistance)>0){//  相关操作}
}

3、无序点云数据集的空间变化检测

void main ()
{pcl::PintCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<PointXYZ>);cloud->width=1000;cloud->height=1;cloud->pionts.resize(cloud->width*cloud->height);for(int i=0;i<cloud->points.size();i++){cloud->points[i].x=1024.0f*rand()/(RAND_MAX+1.0f);cloud->points[i].y=1024.0f*rand()/(RAND_MAX+1.0f);cloud->points[i].z=1024.0f*rand()/(RAND_MAX+1.0f);}//OctreePointCloudChangeDetector 这个对象允许同时在内存中保管两个八叉树,内部使用内存池管理pcl::octree::OctreePointCloudChangeDetector<pcl::PointXYZ>octree(128.0f)//初始化octree,分辨率为128.0octree.setInputCloud(cloud);octree.addPointsFromInputCloud();// 根据点云搭建octreeoctree.switchBuffers();// 交换缓冲区,使用新的八叉树结构pcl::PintCloud<pcl::PointXYZ>::Ptr cloudB(new pcl::PointCloud<PointXYZ>);cloudB->width=1000;cloudB->height=1;cloudB->pionts.resize(cloudB->width*cloudB->height);for(int i=0;i<cloudB->points.size();i++){cloudB->points[i].x=1024.0f*rand()/(RAND_MAX+1.0f);cloudB->points[i].y=1024.0f*rand()/(RAND_MAX+1.0f);cloudB->points[i].z=1024.0f*rand()/(RAND_MAX+1.0f);}octree.setInputCloud(cloudB);octree.addPointsFromInputCloud();// 根据点云cloudB搭建octree//getPointIndicesFromNewVoxels()探测两个点云中体素间的不同,只能检测增加的点,不能检测减少的点vector<int>newPointIndex;octree.getPointIndicesFromNewVoxels(newPointIndex);//cloudB对比于原始cloud,添加了哪些点,这些点是在cloudB中for(int i=0;i<newPointIndex.size();i++){// ~~~相关操作}
}

http://chatgpt.dhexx.cn/article/uYAUv4P7.shtml

相关文章

八叉树场景管理

目录 什么是八叉树(八叉树的数据结构)八叉树的图例八叉树的实现算法八叉树的场景管理器代码实现八叉树的应用场景 1.什么是八叉树——八叉树的数据结构 八叉树是一个树形结构&#xff0c;它的特点就是每个节点正好拥有八个子节点。它的这个结构特点正好能把空间立方体平均分成对…

基于八叉树的空间划分及搜索操作

基于八叉树的空间划分及搜索操作 原理CodeCmakeList.txtCPP体素 近邻 搜索K 近邻 搜索半径内 近邻 搜索 Result 原理 建立空间索引在点云数据处理中有着广泛的应用&#xff0c;常见的空间索引一般 是自顶而下逐级划分空间的各种空间索引结构。 比较有代表性的包括 BSP树KD树K…

基于C++的八叉树颜色删减实验

基于八叉树颜色删减实验 一、实验目的及要求 实现真彩色到256色的颜色转换算法 提供的代码&#xff1a; main.cpp &#xff1a;提供了主控函数main &#xff0c;八叉树类octTree 和八叉树节点结构octNode 。 代码的编译&#xff1a; 由于需要使用bmp的信息头和文件头结构…

八叉树 java_图像八叉树量化讲解 Java版本

这篇文章主要讲解八叉树算法的原理&#xff0c;并用java进行实现 1.算法原理 八叉树最早是在1988年&#xff0c;由 M. Gervautz 和 W. Purgathofer 提出&#xff0c;该算法的最大优点是效率高&#xff0c;占用内存少。在图像量化中的思路是&#xff0c;图像rgb通道的值均为8比特…

详解八叉树地图

个人博客&#xff1a;http://www.chenjianqu.com/ 原文链接&#xff1a;http://www.chenjianqu.com/show-102.html 八叉树地图 八叉树地图(OctoMap)就是一种灵活的、压缩的、又能随时更新的地图。八叉树示意图如下&#xff1a; 一个大立方体不断地均匀分成八块&#xff0c;直…

PCL可视化八叉树格网

1 原理 八叉树其实是一种特殊的由上至下的体素&#xff0c;其构造原理在这里不再进行赘述&#xff0c;详细的构造方式可参考博客&#xff1a;https://blog.csdn.net/qq_32867925/article/details/109094719 有时候为了将点云、构造的层次八叉树需要进行可视化&#xff0c;便于…

松散八叉树

1八叉树简述 1.1定义1.2数据1.3树的建立 1.3.1计算包围体的大小与中心点1.3.2判断物体所属的包围盒2松散八叉树 2.1松散八叉树的建立 八叉树简述 定义 八叉树是一种对三维世界进行场景管理的理想的空间数据结构。八叉树中根节点包含一个立方体包围盒。每个非叶子节点都拥有八…

八叉树学习

八叉树学习 八叉树结构八叉树的存储结构1. 规则八叉树&#xff1a;2.线性八叉树&#xff1a;3.一对八式八叉树 参考网站 八叉树结构 八叉树结构是由 Hunter 博士于1978年首次提出的一种数据模型。八叉树结构通过对三维空间的几何实体进行体元剖分&#xff0c;每个体元具有相同…

PCL中的八叉树

目录 &#xff08;1&#xff09;什么是八叉树 &#xff08;2&#xff09;PCL中八叉树的体素形成和PCL中基于八叉树的点云压缩 &#xff08;3&#xff09;基于八叉树的k邻域搜索、半径搜索和体素近邻搜索 &#xff08;4&#xff09;基于八叉树和基于 kd-tree 的k邻域搜索、半…

八叉树 java_java简单实现八叉树图像处理代码示例

一晃工作有段时间了&#xff0c;第一次写博客&#xff0c;有点不知道怎么写&#xff0c;大家将就着看吧&#xff0c;说的有什么不正确的也请大家指正。 最近工作中用到了一个图像压缩的功能。找了一些工具&#xff0c;没有太好的选择。最后选了一个叫jdeli的&#xff0c;奈何效…

八叉树

http://hi.baidu.com/onlywater/blog/item/905c5e162ed18f4021a4e9c1.html 一、八叉树基本原理&#xff1a; 用八叉树来表示三维形体&#xff0c;并研究这种表示下的各种操作以及应用&#xff0c;是进入80年代后开展起来的。这种方法&#xff0c;既可以看成是四叉树方法在三维…

Octree(八叉树)

1. 算法原理 八叉树&#xff08;Octree&#xff09;是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素&#xff0c;每个节点有八个子节点&#xff0c;将八个子节点所表示的体积元素加在一起就等于父节点的体积。八叉树是四叉树在三维空间上的扩…

【PCL自学:ocTree】八叉树(octree)的原理及应用案例(点云压缩,搜索,空间变化)

PCL中八叉树&#xff08;octree&#xff09;的原理及应用案例 一、什么是八叉树ocTree&#xff1f;1.八叉树原理 二、八叉树应用案例1.点云压缩2.用八叉树进行空间划分和搜索操作3.无序点云数据的空间变化检测 一、什么是八叉树ocTree&#xff1f; 1.八叉树原理 上世纪80年代&…

十进制小数化为二进制小数的方法是什么_十进制转成二进制的两种方式

第一种&#xff1a;用2整除的方式。 用2整除十进制整数&#xff0c;得到一个商和余数&#xff1b;再用2去除商&#xff0c;又会得到一个商和余数&#xff0c;如此重复&#xff0c;直到商为小于1时为止&#xff0c;然后把先得到余数作为二进制数的低位有效位&#xff0c;后得到的…

Python 利用内置函数把二进制小数转换为十进制

如果需要把一个二进制整数转换为十进制整数&#xff0c;只需要简单的一行&#xff1a; int(1101,2) 但如果有一个二进制小数的话&#xff0c;就需要自己实现一个函数了。 不过&#xff0c;许多人是这样写的&#xff1a;(图片取自这里) 可是&#xff0c;由于python本身并不适…

[学习笔记] 二进制小数表示方法

文章目录 科学计数法二进制推广计算机中的小数EXCESS表示系统特殊情况举例&#xff08;float&#xff09;普通情况最大正实数普通情况最小负实数普通情况最小正实数特殊情况最大正实数 科学计数法 科学计数法想必大家都很熟悉了&#xff0c;往往通过如下形式表示一个实数&…

十进制小数化为二进制小数的方法是什么_二进制的转换

二进制是在计算机中常用的一种进制数&#xff0c;其数据用0和1两个数码来表示数据。我们人类常用的是十进制&#xff0c;那么二进制和十进制之间是有一个转换方法的。 二进制转换十进制 一个二进制数转换为十进制数&#xff0c;是比较简单的&#xff0c;其方法就是用每一个位置…

二进制小数的意义

回忆小学学的十进制小数的意义&#xff1a; 15.23这个小数&#xff0c;1是十位&#xff0c;5是个位&#xff0c;2是十分位&#xff0c;3是百分位。这个小数的意义为&#xff1a;&#xff0c;因为最低位为百分位&#xff0c;所以分母是100。 小数末尾加上0或去掉0&#xff0c;小…

浮点数(小数)在计算机中如何用二进制存储?

浮点数在计算机中如何用二进制存储&#xff1f; 前言 前面我有篇博文详解了二进制数&#xff0c;以及如何同二进制数表示整数。但是&#xff0c;计算机处理的不仅仅是整数&#xff0c;还有小数&#xff0c;同样小数在计算机也是用二进制进行存储的&#xff0c;但是&#xff0…

二进制小数的表示

二级制小数分为两大类&#xff1a;1、定点数&#xff1b;2、浮点数。 定点数 定点数&#xff1a; &#xff08;1&#xff09;小数点位置固定不变的数。 &#xff08;2&#xff09;定点数有定点整数和定点小数。 &#xff08;定点整数&#xff1a;小数部分为0&#xff1b;定点…