原来如此!简单总结SLAM中的各种地图

作者 | LarryDong  编辑 | 3D视觉之心

原文链接:https://zhuanlan.zhihu.com/p/708050126

点击下方卡片,关注“自动驾驶之心”公众号

戳我-> 领取自动驾驶近15个方向学习路线

>>点击进入→自动驾驶之心SLAM技术交流群

本文只做学术分享,如有侵权,联系删文

自己搞了这么多年SLAM,使用的主要还是点云地图。虽然知道种种地图表征,但一直没有梳理过。最近集中时间学习了一下各种地图,在这里进行整理与分享。能力有限,难免有不恰之处,请批评指正。

1、地图的不同分类方式

地图有多种不同的分类方式,网上有不少帖子介绍各种各样的地图,但并没有非常完整的总结地图应该怎么分类。论文[1]中将地图分成以下几种:拓扑地图、度量地图、度量-语义地图和混合地图。我觉得按照这种方式进行归类相对比较科学。

1.1 拓扑地图

拓扑地图(Topological Map)使用节点和边来表示环境,其中节点表示重要位置(如拐角、门口),边表示这些位置之间的可达路径。拓扑地图注重表示环境的连接关系,而不是具体的几何细节。这种地图表示方法适用于大型、复杂环境中的高效路径规划和导航。个人简单理解为,是一种表示拓扑关系、不存在准确距离信息的地图,例如:我家地图是,客厅在中间,周围连着卧室、书房、厨房、卫生间,书房又连着阳台。

bbd00a222180cbc06ddf8031ffc95f99.png

1.2 度量地图/尺度地图/几何地图

度量地图(Metric Map)或几何地图(Geometric Map)是SLAM种较为常用的一种表示方法,常见的点云(PointCloud)、八叉树地图(OctoMap)、栅格地图(Grid Map)等都属于度量地图,下一节会展开介绍。个人简单的理解为,能够从这个地图中获取具体的尺度信息,例如某个点距离某个点多远、XXX障碍物面积有多大。

根据地图的稠密程度,度量地图还可进一步分为:稀疏地图、稠密地图。稀疏地图例如视觉SLAM建立的特征点地图,是稀疏的,一般多用于自身定位而难以直接导航;而RGBD或LiDAR可以建立稠密地图。

根据地图是连续的还是离散的,还可进一步分为:离散地图、连续地图。栅格地图、体素地图(Voxel Map)就是典型的离散地图,把空间进行了划分,然后离散化表达;连续地图是采用高斯过程或者NeRF方式建立的地图。

489296e9efb2b1551514cf8dddb37d94.png
离散地图(左)与连续地图(右)

1.3 语义地图

语义地图(Semantic Map)是包含了语义信息的地图,语义信息可以是物体的种类、姿态和形状等描述。例如,无人驾驶需要知道地图中那些是车道、哪些是障碍。需要注意的是,只要包含于语义信息就可以算是语义地图,尺度地图、拓扑地图也可以是语义地图。

e65386f31cf35be5e9e3d5236210508e.png
带语义信息的点云地图(左)和带语义信息的拓扑地图(右)

1.4 混合地图与多层级地图

混合地图(Hybrid Map)是一种结合多种地图表示的地图,例如在大范围导航时,我们可能既需要拓扑信息(从客厅到卧室),又需要尺度信息(走多少米),这就需要混合地图。

分层级地图(Hierarchy Map)顾名思义,是多层次的地图表示,通过将环境信息组织成不同层次以提高数据管理和处理的效率。例如无人驾驶时,顶层地图表示全局的道路网络,底层表示局部的道路详细结构,可以理解成“分辨率”从粗到细的过程,以适应不同的任务需求。

2、尺度地图细分

2.1 特征地图

特征地图(Feature Map)是仅保留特征的地图,常见于视觉SLAM。一些场景,例如水下的定位放置一些标志物,这样建立的地图就是特征点地图。视觉SLAM一般提取特征点匹配后建立特征点地图。除了点特征意外,线特征和面特征也可以建立地图,但也属于是特征地图的一种。

65306be4744e7e7bbeb55ef71de4b0fa.png
左:水下声呐建立的声呐目标特征点地图;中:vSLAM建立的特征点地图;右:线+面特征地图

2.2 点云地图

点云地图(Point Cloud Map)是利用点云形式表示地图,常见的激光雷达SLAM建立的都是点云地图。

5657ec92cc07980ad6215d12e5bb0812.png

2.3 栅格地图

栅格地图(Grid Map)将空间划分为均匀的网格,每个网格存储一个值,表征地图的属性。一种常见的方式,用三种状态:占用、空闲、未知,表示某个栅格是否被占用,这种表达方式称作“占用栅格地图”(Occupancy Grid Map),机器人导航常用栅格地图,在“空闲”栅格中规划运动轨迹。一般来说,栅格地图指的是二维平面地图。

1cb73a629525fe08a47ec22d8028523d.png

2.4 体素地图

体素地图(Voxel Map)可以理解为三维的栅格地图,当然也包括占用体素地图(Occupancy Grid Map)。如果是无人机这类的导航,一般需要用到3D的栅格地图。和点云地图相比,体素地图的“分辨率”更低,对点云地图进行了离散化。

10b9e7f29cf8806d9f6a4cbafc718ce9.png
室内场景的占用栅格地图(左)和用于无人机导航的占用栅格地图(右)

2.5 高程地图

高程地图(Elevation Map)也称2.5D地图。如果是平坦地面、二维场景,用栅格地图就可以;如果是无人机,需要用到三维场景体素地图;但如果是无人车在非平坦路面运行、或者是四足/轮式机器人在野外的行进,需要对地形进行建模,常用的方式就是高程地图,例如经典的elevation mapping就是建立的高程地图[2]。在栅格地图的基础上增加了一个维度即高度。

4798861209ad1f507a744943243e7f9d.png

2.6 神经辐射场地图

神经辐射场地图(Neural Radiance Fields, NeRF)是一种新兴的三维场景表示和渲染技术,通过神经网络隐式地表示三维空间中的颜色和密度场。其特点是高精度、连续表示、数据驱动。具体可参考[6]。

9cfe525133531565469974a930182de8.png

2.x 八叉树地图、ikdtree地图、哈希地图等

这些我认为不属于具体的地图表征形式,只是地图存储的数据结构。具体来说:

  • 八叉树地图(Octree Map)是利用八叉树数据结构存储体素地图,可以节省数据存储空间。具体实现例如 OctoMap[3]

  • ikdtree地图是动态kd-tree的地图,存储的是原始点云形式,由Fastlio2[4]采用,专门用于处理点云数据的高效存储、增量更新和查询

  • 哈希地图(Hash Map)使用哈希函数将二维或者三维空间坐标映射到哈希表中,用于存储和检索空间信息,节省存储空间,存取速度快,可以存储点云地图、体素地图

除此之外,还有其他改进例如i-octree[5]等,不展开介绍。

3、一些讨论

这里记录一些自己学习的困惑,或者其他地方的讨论。

3.1 为什么要关注地图的表示?

对于最基础的SLAM而言,实现了定位与建图任务就可以了。但问题是,建立的地图要干什么、如何服务后面的任务?如果不加以考虑、忽视建图,就完全是一个定位过程了。所以,需要根据后续任务决定建立什么地图。

3.2 无人驾驶的高精度地图是什么?

个人简单总结,就是:尺度地图的绝对坐标精度更高,所包含的道路交通信息元素丰富细致。按照第一部分的分类,应该数据多层级地图。

4、小结

本文整理了一些SLAM领域常见的地图,但并没有细致讨论每种地图的优缺点以及应用场景。

参考文献

[1] Survey on Active Simultaneous Localization and Mapping: State of the Art and New Frontiers

[2] GitHub - ANYbotics/elevation_mapping: Robot-centric elevation mapping for rough terrain navigation

[3] https://octomap.github.io/

[4] FAST-LIO2: Fast Direct LiDAR-inertial Odometry

[5] zhujun:【ICRA 2024】i-Octree:快速、轻量级的动态八叉树

[6] LONER: LiDAR Only Neural Representations for Real-Time SLAM

投稿作者为『自动驾驶之心知识星球』特邀嘉宾,欢迎加入交流!重磅,自动驾驶之心科研论文辅导来啦,申博、CCF系列、SCI、EI、毕业论文、比赛辅导等多个方向,欢迎联系我们!

f48a747ae0621724acc8ad128b9dd51b.jpeg

① 全网独家视频课程

BEV感知、BEV模型部署、BEV目标跟踪、毫米波雷达视觉融合多传感器标定多传感器融合多模态3D目标检测车道线检测轨迹预测在线高精地图世界模型点云3D目标检测目标跟踪Occupancy、cuda与TensorRT模型部署大模型与自动驾驶Nerf语义分割自动驾驶仿真、传感器部署、决策规划、轨迹预测等多个方向学习视频(扫码即可学习

954ef634f0d2a673f51cb45c035ced60.png

网页端官网:www.zdjszx.com

② 国内首个自动驾驶学习社区

国内最大最专业,近3000人的交流社区,已得到大多数自动驾驶公司的认可!涉及30+自动驾驶技术栈学习路线,从0到一带你入门自动驾驶感知2D/3D检测、语义分割、车道线、BEV感知、Occupancy、多传感器融合、多传感器标定、目标跟踪)、自动驾驶定位建图SLAM、高精地图、局部在线地图)、自动驾驶规划控制/轨迹预测等领域技术方案大模型、端到端等,更有行业动态和岗位发布!欢迎扫描下方二维码,加入自动驾驶之心知识星球,这是一个真正有干货的地方,与领域大佬交流入门、学习、工作、跳槽上的各类难题,日常分享论文+代码+视频

9ec06bc3d88a360d755a3a9ead2707ae.png

③【自动驾驶之心】技术交流群

自动驾驶之心是首个自动驾驶开发者社区,聚焦感知、定位、融合、规控、标定、端到端、仿真、产品经理、自动驾驶开发、自动标注与数据闭环多个方向,目前近60+技术交流群,欢迎加入!扫码添加汽车人助理微信邀请入群,备注:学校/公司+方向+昵称(快速入群方式)

55ad42e3f0c50b2bfb763fb6fb7a6ab0.jpeg

④【自动驾驶之心】全平台矩阵

6f6a65e5836dbbeb936f2c70c8a3a9ab.png

<think>好的,我需要回答用户关于体素地图边界的定义和实现方式的问题。首先,我要回顾用户提供的引用内容,看看是否有相关的信息。 根据引用1,体素是固定分辨率的三维栅格地图,而八叉树是可变分辨率的。这说明体素地图的边界可能与固定栅格的分辨率有关。引用4提到体素尺寸决定了立方体单元的大小,边界可能由这些单元的排列方式决定。 用户想知道边界如何定义和实现。可能的思路是,体素地图的边界由网格的划分方式确定。每个体素的位置由其索引乘以体素尺寸,从而确定空间坐标。例如,若体素尺寸是0.1米,索引为(2,3,4)的体素中心坐标可能是(0.2,0.3,0.4)。边界则是该立方体的六个面,范围为中心坐标±尺寸的一半。 实现方面,引用3中的Python代码使用Open3D库进行体素下采样,这可能涉及将点云分配到对应的体素网格中。确定边界需要计算每个体素的最小和最大坐标。例如,对于中心在(x,y,z)的体素,边界是x±voxel_size/2,同样适用于y和z轴。 另外,引用2提到了栅格最近邻的实现,可能涉及遍历相邻体素,这时候边界的处理很重要,比如判断是否超出地图范围。如果体素地图的边界是整个点云的最大和最小坐标范围,那么超出这个范围的体素可能被忽略或视为无效。 需要确认的是,体素地图的边界是否通常定义为整个三维空间的包围盒,然后根据体素尺寸划分网格。例如,点云的最大x、y、z和最小x、y、z确定整体边界,然后划分成多个体素。每个体素的边界由其索引和尺寸计算得出。 总结来说,体素边界的定义基于网格划分的规则,每个体素的几何边界由其位置和尺寸确定。实现时,需要计算每个体素的空间范围,可能涉及索引转换和坐标计算。此外,处理点云时,超出整体边界的区域可能不生成体素,或者在动态扩展时需要调整边界。</think>### 体素地图边界的定义与实现方法 #### 1. **边界的定义** 体素地图的边界由其三维网格划分规则决定: - **整体边界**:通常由输入点云数据的空间范围确定,即所有点的最小和最大坐标构成的包围盒。例如,若点云坐标范围为$x_{\min}$到$x_{\max}$、$y_{\min}$到$y_{\max}$、$z_{\min}$到$z_{\max}$,则整体边界为该立方体范围[^4]。 - **局部边界(单个体素)**:每个体素是一个立方体单元,其边界由中心坐标和体素尺寸计算得出。若体素中心坐标为$(x_c, y_c, z_c)$,尺寸为$s$,则其边界范围为: $$ x \in [x_c - s/2, x_c + s/2], \quad y \in [y_c - s/2, y_c + s/2], \quad z \in [z_c - s/2, z_c + s/2] $$ 超出整体边界的区域可能被视为无效或动态扩展[^1][^4]。 #### 2. **实现方式** 实现体素边界的关键步骤包括: - **步骤1:确定整体包围盒** 遍历点云数据,计算$x,y,z$轴的最小和最大值,形成初始边界立方体[^3][^4]。 ```python # 示例代码:计算点云包围盒 import open3d as o3d pcd = o3d.io.read_point_cloud("test.pcd") bbox = pcd.get_axis_aligned_bounding_box() # 获取包围盒 ``` - **步骤2:划分体素网格** 根据体素尺寸$s$,将包围盒划分为均匀的三维网格。每个体素的索引$(i,j,k)$与其空间坐标的关系为: $$ x_c = x_{\min} + (i + 0.5) \cdot s, \quad y_c = y_{\min} + (j + 0.5) \cdot s, \quad z_c = z_{\min} + (k + 0.5) \cdot s $$ 由此可推导每个体素的边界范围[^2]。 - **步骤3:体素与点的映射** 将每个点分配到对应的体素中,通过坐标计算其所属的体素索引: ```python # 示例代码:计算点对应的体素索引 def get_voxel_index(point, voxel_size, bbox_min): i = int((point[0] - bbox_min[0]) // voxel_size) j = int((point[1] - bbox_min[1]) // voxel_size) k = int((point[2] - bbox_min[2]) // voxel_size) return (i, j, k) ``` - **步骤4:动态边界扩展(可选)** 若点云数据动态增加,可实时调整整体边界并重新划分网格,但需权衡计算效率。 #### 3. **边界处理的应用场景** - **碰撞检测**:判断物体是否与体素边界相交。 - **地图裁剪**:仅处理特定边界范围内的体素,减少计算量。 - **可视化优化**:根据边界范围渲染可见区域的体素,如引用2中栅格最近邻的可视化。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值