详解八叉树地图

article/2025/10/28 22:54:28

 个人博客:http://www.chenjianqu.com/

原文链接:http://www.chenjianqu.com/show-102.html

八叉树地图

    八叉树地图(OctoMap)就是一种灵活的、压缩的、又能随时更新的地图。八叉树示意图如下:

1.jpg

    一个大立方体不断地均匀分成八块,直到变成最小的方块为止。整个大方块可以看成是根节点,而最小的块可以看作是“叶子节点”。于是,在八叉树中,当我们由下一层节点往上走一层时,地图的体积就能扩大八倍。某个方块的所有子节点都被占据或都不被占据时,就没必要展开这个节点。

    八叉树的节点存储了它是否被占据的信息。可以用0表示空白,1表示占据。更好的选择是用概率形式表达某节点是否被占据的事情。比方说,用一个浮点数 x∈[0,1]来表达。这个x一开始取 0.5。如果不断观测到它被占据,那么让这个值不断增加;反之,如果不断观测到它是空白,那就让它不断减小即可,这样可以动态地建模了地图中的障碍物信息。X不断减小或增加可能会超出[0,1]的范围,因此更好的方式是使用概率对数值来描述:y = logit(x) = log(x/(1-x)) ,反变换为 x = logit-1(y) = exp(y)/(exp(y)+1) 。存储 y 来表达节点是否被占据。当不断观测到“占据”时,让 y增加一个值;否则就让 y 减小一个值。当查询概率时,再用逆 logit 变换,将 y 转换至概率即可。

    假设我们在RGB-D 图像中观测到某个像素带有深度 d,这说明了一件事:我们在深度值对应的空间点上观察到了一个占据数据,并且,从相机光心出发,到这个点的线段上,应该是没有物体的(否则会被遮挡)。利用这个信息,可以很好地对八叉树地图进行更新,并且能处理运动的结构。

 

代码实现

    使用的库为Octomap,地址为:https://github.com/OctoMap/octomap  ,包含 octomap 地图与 octovis(一个可视化程序),二者都是 cmake 工程,分别编译安装即可。

CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
project(octomaptest)set( CMAKE_BUILD_TYPE Release )
set( CMAKE_CXX_FLAGS "-std=c++11" )# opencv 
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# eigen 
include_directories( "/usr/include/eigen3/" )
# pcl 
find_package( PCL REQUIRED COMPONENT common io filters )
include_directories( ${PCL_INCLUDE_DIRS} )
add_definitions( ${PCL_DEFINITIONS} )
# octomap 
find_package( octomap REQUIRED )
include_directories( ${OCTOMAP_INCLUDE_DIRS} )add_executable( octomaptest main.cpp )
target_link_libraries( octomaptest ${OpenCV_LIBS} ${PCL_LIBRARIES} ${OCTOMAP_LIBRARIES} )
install(TARGETS octomaptest RUNTIME DESTINATION bin)

main.cpp

#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <octomap/octomap.h>    // for octomap 
#include <Eigen/Geometry> 
#include <boost/format.hpp>  // for formating stringsusing namespace std;int main( int argc, char** argv )
{vector<cv::Mat> colorImgs, depthImgs;    // 彩色图和深度图vector<Eigen::Isometry3d> poses;         // 相机位姿ifstream fin("./data/pose.txt");    for ( int i=0; i<5; i++ ){//读取图片boost::format fmt( "./data/%s/%d.%s" ); //图像文件格式colorImgs.push_back( cv::imread( (fmt%"color"%(i+1)%"png").str() ));depthImgs.push_back( cv::imread( (fmt%"depth"%(i+1)%"pgm").str(), -1 )); // 使用-1读取原始图像//读取位姿double data[7] = {0};for ( int i=0; i<7; i++ )fin>>data[i];Eigen::Quaterniond q( data[6], data[3], data[4], data[5] );Eigen::Isometry3d T(q);T.pretranslate( Eigen::Vector3d( data[0], data[1], data[2] ));poses.push_back( T );}// 计算点云拼接// 相机内参 double cx = 325.5;double cy = 253.5;double fx = 518.0;double fy = 519.0;double depthScale = 1000.0;cout<<"正在将图像转换为 Octomap ..."<<endl;// octomap tree octomap::OcTree tree( 0.02 ); // 参数为分辨率for ( int i=0; i<5; i++ ){cout<<"转换图像中: "<<i+1<<endl; cv::Mat color = colorImgs[i]; cv::Mat depth = depthImgs[i];Eigen::Isometry3d T = poses[i];//octomap库自带的简单店运octomap::Pointcloud cloud;  // the point cloud in octomap for ( int v=0; v<color.rows; v++ )for ( int u=0; u<color.cols; u++ ){unsigned int d = depth.ptr<unsigned short> ( v )[u]; // 深度值if ( d==0 ) continue; // 为0表示没有测量到if ( d >= 7000 ) continue; // 深度太大时不稳定,去掉Eigen::Vector3d point; point[2] = double(d)/depthScale; point[0] = (u-cx)*point[2]/fx;point[1] = (v-cy)*point[2]/fy; Eigen::Vector3d pointWorld = T*point;// 将世界坐标系的点放入点云cloud.push_back( pointWorld[0], pointWorld[1], pointWorld[2] ); }// 将点云存入八叉树地图,给定原点,这样可以计算投射线tree.insertPointCloud( cloud, octomap::point3d( T(0,3), T(1,3), T(2,3) ) );     }// 更新中间节点的占据信息并写入磁盘tree.updateInnerOccupancy();cout<<"saving octomap ... "<<endl;tree.writeBinary( "octomap.bt" );return 0;
}

    上述程序执行完了之后会生成八叉树地图octomap.bt,使用octovis即可查看地图,如下:

octomap.jpg

 

 


http://chatgpt.dhexx.cn/article/9ouomqGu.shtml

相关文章

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论文…

【轨迹压缩】Trajectory Simplification: On Minimizing the Direction-based Error [2015] [VLDB]

一、一个动机 保护方向信息的方向保持轨迹简化&#xff08;DPTS&#xff09;已被证明表现良好&#xff0c;而现有关于 DPTS 的研究 要求用户指定一个容错&#xff0c;在某些情况下用户可能不知道如何正确设置&#xff08;例如&#xff0c;容错只能在未来某个时间知道&#xff…

VLDB 2021 EAB最佳论文:深度解析机器学习的基数估计为何无法实现?

©作者 | 曲昌博单位 | 西蒙菲莎大学近日&#xff0c;IEEE 数据工程新星奖王健楠团队论文《Are We Ready for Learned Cardinality Estimation?》夺得数据库顶会 VLDB 2021 年度的 EA&B 最佳论文奖。 数据库是企业管理和查询数据的复杂软件系统。 近年来随着机器学习以…

Transformers如何处理表格数据?【VLDB2022教程】Transformer表格数据表示:模型和应用...

来源&#xff1a;专知 本文为教程介绍&#xff0c;建议阅读5分钟最近的研究工作通过开发表格数据的神经表示扩展了语言模型。 在过去的几年中&#xff0c;自然语言处理界见证了基于transformer的语言模型(LM)在自由文本的神经表示方面的进展。鉴于关系表中可用知识的重要性&…