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

article/2025/10/28 22:52:55

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

  • 原理
  • Code
    • CmakeList.txt
    • CPP
      • 体素 近邻 搜索
      • K 近邻 搜索
      • 半径内 近邻 搜索
  • Result

原理

建立空间索引在点云数据处理中有着广泛的应用,常见的空间索引一般 是自顶而下逐级划分空间的各种空间索引结构。
比较有代表性的包括

  • BSP树
  • KD树
  • KDB树
  • R树
  • 四叉树
  • 八叉树
    这些结构中,KD树和八叉树使用比较广泛

八叉树定义: 八叉树(Octree)是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素,每个节点有八个子节点,这八个子节点所表示的体积元素加在一起就等于父节点的体积。一般中心点作为节点的分叉中心。

八叉树算法思想

(1). 设定最大递归深度。

(2). 找出场景的最大尺寸,并以此尺寸建立第一个立方体。

(3). 依序将单位元元素丢入能被包含且没有子节点的立方体。

(4). 若没达到最大递归深度,就进行细分八等份,再将该立方体所装的单位元元素全部分担给八个子立方体。

(5). 若发现子立方体所分配到的单位元元素数量不为零且跟父立方体是一样的,则该子立方体停止细分,因为跟据空间分割理论,细分的空间所得到的分配必定较少,若是一样数目,则再怎么切数目还是一样,会造成无穷切割的情形。

(6). 重复3,直到达到最大递归深度。

下面实现用octree在点云数据中进行空间划分及近邻搜索
实现

  • 体素内近邻搜索(Neighbors within VOxel Search)
  • K近邻搜索(K Nearest Neighbor Search
  • 半径内近邻搜索”(Neighbors within Radius Search)

Code

CmakeList.txt


# 声明要求的 cmake 最低版本
cmake_minimum_required(VERSION 2.8 )# 声明工程名称
project(octree_search)# 添加c++ 11 标准支持
set(CMAKE_CXX_FLAGS "-std=c++11")# 寻找PCL的库
find_package(PCL REQUIRED COMPONENT common io visualization)# 添加头文件
include_directories(${PCL_INCLUDE_DIRS})
add_definitions( ${PCL_DEFINITIONS} )#添加一个可执行程序
add_executable(Octree_Search octree_search.cpp)#链接PCL 库
target_link_libraries(Octree_Search ${PCL_LIBRARIES})

CPP

#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <vector>
#include <ctime>

需要包含的头文件
cloud_viewer.h 这个文件如果不看 点云 的 话 可以不要

=======================================================

    //用系统时间初始化随机种子srand ((unsigned int) time (NULL));//声明一个点云指针 并分配空间pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);//定义点云大小  点云个数1000个,无序cloud->width =1000;cloud->height =1;cloud->points.resize (cloud->width * cloud->height);//循环给点云赋值 通过 随机数  点云的坐标 0-1024for(size_t 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);            }

通过系统数据创建随机变量 。 创建一个1000个点的点云,为每个点的x,y,z坐标赋值 0-1024

显然 正常 就是一个 立方体。 把点云显示出来就是这样
在这里插入图片描述
显示的话 加上如下 代码 在最后面

    pcl::visualization::CloudViewer viewer("Cloud Viewer");viewer.showCloud(cloud);while (!viewer.wasStopped ()){}

=======================================================

    /* 设置分辨率 描述的是最低一级 八叉树 的 最小体素 的 尺寸*/float resolution =128.0f;/*创建 一个 八叉树 实例*/pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(resolution);/* 赋值八叉树的 点云 */octree.setInputCloud (cloud);//设置输入的点云octree.addPointsFromInputCloud ();//将输入的点云添加到八叉树

构建 八叉树 的部分

第一行 分辨率 的 参数 就是 八叉树 最小 的 体素的尺寸
然后就是 输入点云 和 构建 就可以了

=======================================================

    //构建一个  搜索点pcl::PointXYZ searchPoint;searchPoint.x=1024.0f* rand () / (RAND_MAX +1.0f);searchPoint.y=1024.0f* rand () / (RAND_MAX +1.0f);searchPoint.z=1024.0f* rand () / (RAND_MAX +1.0f);

构建一个 搜索点 x、y、z 取值 0-1024 随机

=======================================================
上面构建了 八叉树 一个搜索点 下面就可以搜索了

体素 近邻 搜索

    // 创建一个 搜索后 保存 的 点的索引值 的 向量std::vector<int>pointIdxVec;/*执行体素近邻搜索  函数很简单  参数 就是 搜索的点  和返回的索引值 向量*/if (octree.voxelSearch (searchPoint, pointIdxVec)){// 打印 搜索 的 点 的位置std::cout<<"Neighbors within voxel search at ("<<searchPoint.x<<" "<<searchPoint.y<<" "<<searchPoint.z<<")"<<std::endl;//打印搜索到的点 的 位置for (size_t i=0; i<pointIdxVec.size (); ++i){std::cout<<"    "<< cloud->points[pointIdxVec[i]].x <<" "<< cloud->points[pointIdxVec[i]].y <<" "<< cloud->points[pointIdxVec[i]].z <<std::endl;}}

函数 octree.voxelSearch (searchPoint, pointIdxVec)
就是执行 体素近邻搜索 函数

  • 参数1 -----搜索的点
  • 参数2 ----- 返回的索引值 向量

=======================================================

K 近邻 搜索

   //设置K的个数int K = 10;// 创建一个 搜索后 保存 的 点的索引值 的 向量std::vector<int>pointIdxNKNSearch;// 创建一个 搜索后 保存 的 点的距离平方值 的 向量std::vector<float>pointNKNSquaredDistance;//打印 K近邻 搜索 的点  和 K个数std::cout<<"K nearest neighbor search at ("<<searchPoint.x<<" "<<searchPoint.y<<" "<<searchPoint.z<<") with K="<< K <<std::endl;/*执行 K近邻 搜索  函数 参数 搜索点  K个数  搜索结果的点索引值存放向量  搜索结果点距离平方存放向量*/if (octree.nearestKSearch (searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) >0){//打印搜索到的点 的 位置 和距离for (size_t i=0; i<pointIdxNKNSearch.size (); ++i){std::cout<<"    "<<   cloud->points[ pointIdxNKNSearch[i] ].x <<" "<< cloud->points[pointIdxNKNSearch[i] ].y <<" "<< cloud->points[pointIdxNKNSearch[i] ].z <<" (squared distance: "<<pointNKNSquaredDistance[i] <<")"<<std::endl;}}

函数 octree.nearestKSearch (searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance)
执行 K近邻 搜索 函数

  • 参数1 ----- 搜索点
  • 参数2 ----- K个数
  • 参数3 ----- 搜索结果的点索引值存放向量
  • 参数4 ----- 搜索结果点距离平方存放向量
    =======================================================

半径内 近邻 搜索

    // 创建一个 搜索后 保存 的 点的索引值 的 向量std::vector<int>pointIdxRadiusSearch;// 创建一个 搜索后 保存 的 点的距离平方值 的 向量std::vector<float>pointRadiusSquaredDistance;// 设置搜索的半径  随机0-256float radius =256.0f* rand () / (RAND_MAX +1.0f);//打印 半径搜索 的 点 的 位置  和  半径 std::cout<<"Neighbors within radius search at ("<<searchPoint.x<<" "<<searchPoint.y<<" "<<searchPoint.z<<") with radius="<< radius <<std::endl;/* 执行 半径 近邻 搜索  参数 搜索点  半径   搜索结果的点索引值存放向量  搜索结果点距离平方存放向量 */if (octree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) >0){   //打印搜索到的点 的 位置 和距离for (size_t i=0; i<pointIdxRadiusSearch.size (); ++i){std::cout<<"    "<<   cloud->points[ pointIdxRadiusSearch[i] ].x <<" "<< cloud->points[pointIdxRadiusSearch[i] ].y <<" "<< cloud->points[pointIdxRadiusSearch[i] ].z <<" (squared distance: "<<pointRadiusSquaredDistance[i] <<")"<<std::endl;}}

函数 octree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance)
执行 半径 近邻 搜索 函数

  • 参数1 ----- 搜索点
  • 参数2 ----- 半径
  • 参数3 ----- 搜索结果的点索引值存放向量
  • 参数4 ----- 搜索结果点距离平方存放向量
    =======================================================

Result

在这里插入图片描述
在这里插入图片描述


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

相关文章

基于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;定点…

腾讯TDSQL全时态数据库系统论文入选VLDB

当地时间2019年8月26至30日&#xff0c;VLDB 2019会议在美国加利福尼亚召开&#xff0c;腾讯分布式数据库TDSQL与中国人民大学最新联合研究成果被VLDB 2019接收并将通过长文形式发表。VLDB是国际数据管理与数据库领域顶尖的学术会议之一&#xff0c;这是继去年腾讯TDSQL相似度计…

顶会VLDB‘22论文解读:CAE-ENSEMBLE算法

摘要&#xff1a;针对时间序列离群点检测问题&#xff0c;提出了基于CNN-AutoEncoder和集成学习的CAE-ENSEMBLE深度神经网络算法&#xff0c;并通过大量的实验证明CAE-ENSEMBLE算法能有效提高时间序列离群点检测的准确度与效率。 本文分享自华为云社区《VLDB22 CAE-ENSEMBLE论文…