十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SLAM从原理到实战:视觉与激光SLAM技术解析及ORB-SLAM3入门

SLAM从原理到实战:视觉与激光SLAM技术解析及ORB-SLAM3入门 1. 为什么我想聊聊SLAM这件事第一次听到SLAM这个词是在一个做扫地机器人的朋友那里。他跟我说他们家那台机器之所以能自己在客厅里绕来绕去还不撞墙靠的就是SLAM。当时我的反应是听起来好高级但跟我有什么关系后来自己开始接触机器人、无人机、AR这些东西才发现SLAM几乎无处不在而且它没有想象中那么遥不可及。SLAM的全称是Simultaneous Localization and Mapping中文叫“同时定位与建图”。拆开看就是两件事一是定位知道自己在哪里二是建图知道周围长什么样。难点在于这两件事互相依赖——你要建图得先知道自己站在哪你要定位又得先有一张地图。鸡生蛋蛋生鸡SLAM要做的就是把这个死循环解开。这篇内容我打算从原理讲到应用尽量不用复杂的数学公式用生活化的例子把核心逻辑讲清楚。适合谁看如果你是刚接触机器人、自动驾驶、AR/VR的学生或者开发者想搞明白SLAM到底是怎么回事这篇应该能帮你建立一个完整的认知框架。如果你已经有一定基础也可以看看我在实操部分踩过的坑和总结的经验说不定能帮你省点时间。2. SLAM到底在解决什么问题2.1 一个生活场景帮你理解SLAM的核心矛盾想象你被蒙上眼睛放进一个完全陌生的房间里。你的任务是一边摸索这个房间有多大、家具摆在哪里一边还要知道自己现在站在房间的哪个位置。更麻烦的是你每走一步之前摸到的信息就会变得模糊一点——因为你不知道自己走了多远、转了多少度。这就是SLAM要面对的核心问题。传感器激光雷达、摄像头、IMU等就是你的“手”算法就是你的“大脑”。大脑要根据手的触感判断周围环境同时还要推算自己移动了多少。两个任务同时进行互相修正。为什么说它难因为误差会累积。你往前走一步估计走了1米实际走了1.02米这个0.02米的误差在一步里微不足道。但你走100步之后误差就可能变成2米地图就完全对不上了。SLAM算法的核心工作之一就是不断地“纠偏”——用新的观测来修正之前的估计。2.2 定位和建图为什么必须同时做有人可能会问能不能先建好图再定位在某些场景下可以比如工厂里的AGV小车环境固定可以提前把地图建好之后只做定位就行。但更多场景下环境是未知的或者会变化的你不可能提前建图。比如一台探索未知洞穴的机器人它没有预先的地图必须边走边建。又比如AR眼镜用户在家里走动家具位置可能变了预建的地图不一定准也需要实时更新。这时候定位和建图就必须同时进行而且互相依赖。从数学角度看这是一个联合概率估计问题。我们要同时估计机器人位姿位置和姿态和地图特征点的位置。这两个估计量是耦合的不能分开独立求解。早期的SLAM方案试图把它们分开处理效果不好后来大家意识到必须联合估计才逐渐形成了现在的主流框架。2.3 SLAM系统的典型组成模块一个完整的SLAM系统通常包含以下几个部分传感器层负责采集原始数据。常见的有激光雷达、单目/双目/深度相机、IMU、轮式里程计等。前端Frontend也叫里程计负责从相邻帧数据中估计运动。比如视觉SLAM里用特征点匹配来算相机移动了多少。后端Backend负责优化。前端给出的估计有误差后端用图优化或者滤波的方法结合所有历史信息做全局优化。回环检测Loop Closure判断机器人是否回到了之前去过的地方。如果检测到回环就能大幅修正累积误差。建图Mapping根据优化后的位姿和观测数据构建环境地图。地图形式可以是栅格地图、点云地图、语义地图等。这几个模块不是孤立的它们之间有数据流动和反馈。前端给后端提供初始估计后端优化后反馈给前端回环检测的结果会触发全局优化建图的结果又会影响后续的定位精度。3. 主流SLAM方案的技术路线对比3.1 激光SLAM和视觉SLAM的区别这是最常见的分类方式。激光SLAM用激光雷达作为主要传感器视觉SLAM用相机。两者各有优劣适用场景也不同。激光雷达直接测量距离精度高不受光照影响建图效果直观。但激光雷达贵而且点云数据稀疏在纹理缺失的环境比如长走廊里容易退化。视觉SLAM用相机成本低信息丰富能提取语义信息。但相机受光照影响大快速运动时容易模糊而且单目相机有尺度不确定性。实际项目中怎么选如果预算充足、对精度要求高、环境光照变化大优先考虑激光SLAM。如果成本敏感、需要语义信息、环境纹理丰富视觉SLAM更合适。现在也有激光和视觉融合的方案取长补短但系统复杂度会上升。3.2 滤波方法和图优化方法的演进早期的SLAM用扩展卡尔曼滤波EKF把位姿和地图点都放在一个状态向量里用协方差矩阵描述不确定性。EKF的问题在于状态向量维度随地图点数量增长计算量是O(n²)大规模场景跑不动。而且EKF只做一阶线性化非线性强的时候误差大。后来图优化方法成为主流。把位姿和地图点看作图的节点观测看作边SLAM就变成了一个图优化问题。用稀疏矩阵求解计算效率高而且可以反复线性化精度更好。现在主流的SLAM系统比如ORB-SLAM、Cartographer都是基于图优化的。不过滤波方法也没有完全淘汰。在计算资源受限的嵌入式平台上EKF或者粒子滤波仍然有应用。比如一些低成本的扫地机器人用的就是粒子滤波做定位。3.3 直接法和特征点法的取舍视觉SLAM里还有一个重要分支特征点法和直接法。特征点法先从图像里提取特征点比如ORB、SIFT然后匹配相邻帧的特征点根据匹配关系算相机运动。优点是鲁棒性好对光照变化不敏感技术成熟。缺点是特征点提取耗时在纹理少的地方提不出足够的点。直接法不提取特征点直接用像素灰度值来优化相机运动。优点是能利用所有像素信息在纹理少的地方也能工作而且能建出半稠密或稠密地图。缺点是对光照变化敏感优化容易陷入局部极小值。ORB-SLAM是特征点法的代表精度高、鲁棒性好但建的是稀疏点云地图。LSD-SLAM、DSO是直接法的代表能建半稠密地图但在光照变化大的场景下容易丢。实际选型要看具体需求如果要精确的轨迹估计特征点法更稳如果要稠密地图做导航避障直接法或者深度相机方案更合适。4. 从零理解SLAM的核心算法逻辑4.1 前端里程计怎么从两帧数据算出运动前端里程计的任务是估计相邻时刻的运动。以视觉SLAM为例假设你有一帧图像和下一帧图像怎么算相机移动了多少特征点法的做法是先在两帧里分别提取特征点然后匹配。匹配上的点对理论上应该对应空间中的同一个点。根据这些点对的像素坐标变化可以解出相机的旋转和平移。这个过程叫“对极几何”或者“PnP求解”。具体来说如果知道至少4对匹配点就能用PnP算法解出相机位姿。实际中匹配点会有误匹配所以通常用RANSAC随机采样一致性来剔除 outliers。RANSAC的思路是随机选几对点算一个位姿看看有多少其他点符合这个位姿符合最多的那个就是最优解。直接法的做法不同。它不匹配特征点而是假设相邻帧的像素灰度不变通过优化光度误差来求相机运动。简单说就是如果相机没动同一空间点在两帧里的像素值应该一样相机动了像素位置变了但灰度值不变。根据这个约束可以反推出相机运动。4.2 后端优化怎么让误差不累积前端给出的运动估计有误差走几步之后轨迹就飘了。后端的作用就是利用所有历史观测做全局优化把误差摊平。图优化是现在的主流方法。把每个时刻的相机位姿作为一个节点相邻时刻的位姿之间有约束来自前端里程计回环检测给出的约束连接了不相邻的节点。所有约束构成一个图优化目标是最小化所有约束的误差。数学上这是一个非线性最小二乘问题。用高斯-牛顿法或者列文伯格-马夸尔特法迭代求解。每次迭代需要解一个稀疏线性方程组用舒尔补或者Cholesky分解加速。g2o、Ceres、GTSAM是常用的优化库实际项目中直接调用就行不用自己从头实现。这里有个关键点后端优化不是每次来新数据就全量优化那样计算量太大。通常用滑动窗口只优化最近一段时间的位姿老的位姿固定住。回环检测触发时才做全局优化。这样在精度和效率之间取得平衡。4.3 回环检测怎么认出“这地方我来过”回环检测是SLAM里最像“魔法”的部分。机器人走了一大圈回到起点怎么知道这是起点而不是一个长得像的地方视觉SLAM里常用词袋模型Bag of Words。先把图像里的特征点描述子聚类成“视觉单词”一张图像可以用这些单词的直方图表示。两帧图像的相似度就是直方图的相似度。如果当前帧和历史上某一帧的相似度超过阈值就认为可能形成了回环。词袋模型的关键是词典的构建。通常用大量图像离线训练一个视觉词典类似文本检索里的倒排索引。DBoW2、DBoW3是常用的库。ORB-SLAM里用的就是DBoW2做回环检测。回环检测也有误检的风险。如果环境里有重复纹理比如一样的椅子、一样的墙面可能把不同地方认成同一个地方。所以通常还要做几何验证假设形成了回环算一下位姿变换看看能不能把两帧的点云对齐。对不齐就拒绝这个回环。激光SLAM的回环检测通常用扫描匹配。把当前激光扫描和历史上的扫描做匹配如果匹配得分高就认为是回环。Cartographer里用的是分支定界算法加速扫描匹配能在较大范围内快速找到最优匹配。4.4 建图最终产出什么形式的地图SLAM的最终产出是一张地图。地图的形式取决于应用需求。栅格地图是最常见的把环境划分成小格子每个格子标记为占用、空闲或未知。导航避障通常用这种地图。激光SLAM建栅格地图很自然因为激光扫描本身就是距离测量。视觉SLAM建栅格地图需要先建点云再投影到二维平面。点云地图是三维的每个点有xyz坐标可能还有颜色信息。视觉SLAM和激光SLAM都能建点云地图。点云地图信息丰富但数据量大直接用于导航不太方便通常要转成栅格地图或者八叉树地图。语义地图是在几何地图基础上加了标签比如“这是桌子”“这是门”。语义信息对机器人理解环境很有帮助也是现在研究的热点。用深度学习做语义分割把像素或点云分类再投影到地图上。5. 动手实操用ORB-SLAM3跑通第一个SLAM案例5.1 环境准备和依赖安装理论讲多了容易飘咱们实际跑一个。我选ORB-SLAM3作为示例因为它是目前开源视觉SLAM里比较成熟、文档也比较全的。虽然叫ORB-SLAM3但它支持单目、双目、RGB-D还支持IMU融合功能很全。先准备环境。我用的是一台装了Ubuntu 20.04的笔记本配置是i7处理器、16G内存、没有独立显卡。ORB-SLAM3不需要GPUCPU跑就行但内存建议至少8G。依赖主要有这几个Pangolin做可视化的能看到相机轨迹和点云。OpenCV处理图像版本建议4.4以上。Eigen3矩阵运算库。DBoW2和g2oORB-SLAM3自带不用单独装。安装Pangolin的命令大概是这样sudo apt install libgl1-mesa-dev libglew-dev cmake git clone https://github.com/stevenlovegrove/Pangolin.git cd Pangolin mkdir build cd build cmake .. make -j4 sudo make installOpenCV和Eigen3用apt装就行sudo apt install libopencv-dev libeigen3-dev这些装完之后编译ORB-SLAM3本身git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git cd ORB_SLAM3 chmod x build.sh ./build.sh编译过程大概要十几分钟取决于机器性能。如果报错大概率是依赖版本问题仔细看错误信息通常是某个头文件找不到或者版本不兼容。5.2 用公开数据集跑通第一个轨迹编译成功后用公开数据集测试。ORB-SLAM3官方推荐EuRoC数据集是无人机拍的有双目和IMU数据。下载一个序列比如MH_01_easy。运行命令./Examples/Monocular-Inertial/mono_inertial_euroc \ ./Vocabulary/ORBvoc.txt \ ./Examples/Monocular-Inertial/EuRoC.yaml \ /path/to/MH_01_easy \ ./Examples/Monocular-Inertial/EuRoC_TimeStamps/MH01.txt如果一切正常会弹出一个窗口显示相机轨迹和特征点。轨迹应该是一条平滑的曲线如果看到轨迹跳变或者漂移可能是参数配置不对。这里有个坑ORB-SLAM3的配置文件里有很多参数比如相机内参、畸变系数、IMU噪声参数。用公开数据集时官方已经调好了直接用就行。但如果你用自己的设备这些参数必须自己标定否则跑出来的轨迹完全不能用。5.3 用自己的相机数据跑SLAM要注意什么如果你想用自己的相机跑ORB-SLAM3有几个关键点相机标定用棋盘格标定相机内参和畸变系数。OpenCV有现成的标定工具拍十几张不同角度的棋盘格照片跑一下就能得到内参矩阵和畸变向量。内参不准SLAM轨迹会系统性偏移。时间戳对齐如果是双目或者带IMU两个相机之间、相机和IMU之间的时间戳必须对齐。差几毫秒就可能导致轨迹漂移。通常用硬件触发或者软件时间同步来解决。图像频率ORB-SLAM3对图像频率有一定要求太低比如低于10Hz会导致跟踪丢失太高比如超过60Hz计算量太大跑不动。一般20-30Hz比较合适。光照条件视觉SLAM对光照敏感。避免强光直射、避免频繁的光照变化。如果必须在室外跑尽量选光照均匀的时间段。运动速度相机运动不能太快否则相邻帧之间特征点匹配不上。手持相机走路的速度一般没问题但如果是装在快速移动的机器人上要考虑用IMU辅助或者提高帧率。6. 实际项目中踩过的坑和排查经验6.1 跟踪丢失的常见原因和解决办法跟踪丢失是视觉SLAM最常见的问题。表现是轨迹突然中断或者地图点全部消失。原因通常有几种纹理太少对着白墙、纯色地板特征点提取不出来。解决办法是换场景或者用直接法SLAM或者加激光雷达辅助。运动太快相邻帧之间位移太大特征点匹配不上。解决办法是提高帧率或者用IMU预测运动做补偿。光照突变从室内走到室外或者灯光突然开关特征点描述子变化太大。解决办法是用对光照不敏感的特征比如ORB比SIFT好一些或者做光照归一化。遮挡相机被短暂遮挡比如有人从前面走过。ORB-SLAM3有一定的重定位能力短暂遮挡后能恢复但长时间遮挡就会丢。排查的时候先看可视化界面里特征点数量。如果特征点很少基本就是纹理问题。如果特征点很多但匹配不上可能是运动太快或者光照问题。6.2 建图漂移和回环检测失败的排查思路建图漂移的表现是机器人走了一圈回到起点但地图上起点和终点没重合差了一段距离。这说明累积误差没有被回环检测修正。先检查回环检测有没有触发。ORB-SLAM3的可视化界面里回环检测成功时会显示绿色的连线。如果一直没看到绿线说明回环没检测到。可能的原因一是词典不够好视觉单词区分度不够。可以换更大的词典或者针对你的场景重新训练词典。二是场景里重复纹理太多回环检测把不同地方认成同一个地方被几何验证拒绝了。三是确实没形成回环机器人走的路径没有闭合。如果回环检测触发了但漂移还是很大可能是后端优化没收敛。检查一下优化迭代次数和误差是否在下降。有时候是参数配置问题比如 Huber 核函数的阈值设得太大outliers 没被抑制住。6.3 计算资源不够时的优化策略SLAM很吃计算资源尤其是在嵌入式平台上。如果跑不动可以考虑这些优化降低图像分辨率ORB-SLAM3默认用640x480如果还跑不动可以降到320x240。特征点数量会减少但计算量大幅下降。减少特征点数量ORB-SLAM3默认每帧提取1000个特征点可以降到500甚至更少。精度会受一些影响但实时性会好很多。关闭局部建图线程ORB-SLAM3有三个线程跟踪、局部建图、回环检测。如果CPU核心少可以降低局部建图的频率或者暂时关闭回环检测。用轻量级方案如果ORB-SLAM3还是太重可以考虑VINS-Mono或者OKVIS它们更轻量适合嵌入式平台。或者用激光SLAM计算量通常比视觉SLAM小。7. SLAM在真实场景中的应用版图7.1 机器人导航和自动驾驶里的SLAM扫地机器人是SLAM最成功的商业化应用之一。早期的扫地机器人是随机碰撞式后来加了激光雷达和SLAM算法能建图、能规划路径体验完全不一样了。现在中高端扫地机器人基本都标配激光SLAM有些还加了视觉做辅助。自动驾驶里SLAM是定位模块的核心。虽然自动驾驶有GPS和RTK但隧道、地下车库、城市峡谷这些场景GPS信号不好必须靠SLAM做补充。激光SLAM在自动驾驶里用得比较多因为精度高、不受光照影响。视觉SLAM通常和激光融合提供语义信息。仓储AGV、巡检机器人、配送机器人也都依赖SLAM。这些场景通常环境比较固定可以用预建地图加实时定位的方案不一定需要完整的SLAM。但如果环境会变化比如货架位置经常调整就需要在线SLAM。7.2 AR/VR和手机上的SLAM应用AR眼镜和手机AR是视觉SLAM的另一个大市场。ARKit和ARCore底层都有SLAM用来跟踪手机或眼镜的运动把虚拟物体稳定地叠加在真实场景里。手机上的SLAM对计算资源要求很苛刻因为要同时跑SLAM、渲染、交互。所以手机SLAM通常用轻量级方案比如半直接法或者稀疏特征点法而且会大量利用IMU做辅助。苹果的ARKit用的是VIO视觉惯性里程计把相机和IMU融合精度和鲁棒性都很好。AR里的SLAM还有一个特殊需求尺度要准。单目SLAM有尺度不确定性建出来的地图和真实世界比例对不上虚拟物体就会太大或太小。所以AR通常用双目或者深度相机或者用IMU提供尺度信息。7.3 三维重建和数字孪生中的SLAM技术三维重建是SLAM的另一个重要应用。用相机绕物体拍一圈SLAM算法估计相机轨迹然后根据轨迹把多视角图像融合成三维模型。这叫SfMStructure from Motion和SLAM原理相通区别是SfM通常离线做SLAM在线做。数字孪生是最近比较火的概念把物理世界数字化在虚拟空间里做仿真和监控。SLAM是构建数字孪生的关键技术之一用来采集空间数据、构建三维模型。激光扫描加SLAM可以快速获取室内外的高精度点云用于建筑、工厂、城市的数字孪生。这个方向对SLAM的要求是精度高、覆盖全、自动化。手持激光扫描仪加SLAM算法边走边扫几个小时就能扫完一栋楼。后处理软件自动拼接点云、生成模型。相比传统的全站仪测量效率提升非常明显。8. 给SLAM初学者的学习路径建议8.1 先建立直觉再啃数学很多初学者一上来就啃《视觉SLAM十四讲》被里面的李群李代数、非线性优化劝退。我的建议是先建立直觉知道SLAM在干什么、每个模块解决什么问题然后再深入数学细节。可以先看一些可视化好的视频看看SLAM跑起来是什么效果。然后自己跑一个开源方案感受一下数据流动。有了直观感受之后再回头看数学会容易很多。数学是工具不是目的。知道为什么要用这个工具比会推导公式更重要。8.2 从跑通开源方案开始不要一上来就自己写SLAM。先跑通ORB-SLAM3、VINS-Mono、Cartographer这些成熟方案看看它们怎么配置、怎么运行、输出什么结果。跑通之后试着改一些参数看看效果怎么变化。比如改特征点数量、改优化迭代次数、改回环检测阈值观察轨迹和地图的变化。这个过程能帮你理解每个参数的作用也能帮你建立排查问题的能力。实际项目中大部分时间不是在写算法而是在调参和排查问题。跑通开源方案是培养这种能力的最好方式。8.3 选一个方向深入而不是贪多SLAM领域很广激光、视觉、多传感器融合、语义SLAM、深度学习SLAM每个方向都够研究很久。初学者容易贪多什么都想学结果什么都不精。建议选一个方向深入。如果对机器人导航感兴趣可以深入激光SLAM学Cartographer、LIO-SAM。如果对AR/VR感兴趣可以深入视觉惯性SLAM学VINS-Mono、ORB-SLAM3。如果对三维重建感兴趣可以学SfM和MVS。深入一个方向之后再横向扩展会容易很多。因为SLAM的底层逻辑是相通的图优化、回环检测、建图这些核心概念在各个方案里都有。把一个方向吃透再看其他方向能很快抓住重点。9. 我个人的一些实操体会SLAM这个领域理论很漂亮但实际落地的时候全是细节。我踩过最大的坑是低估了标定的重要性。有一次用自己组的双目相机跑SLAM轨迹总是飘查了半天算法没问题最后发现是双目外参标定不准。重新标定之后轨迹立刻就稳了。所以我的经验是算法跑不通的时候先检查数据质量和标定参数再怀疑算法本身。另一个体会是不要追求完美的SLAM。实际项目中SLAM只是整个系统的一个模块它不需要100%准确只需要满足应用需求就行。扫地机器人不需要厘米级定位AR眼镜不需要全局一致的地图。根据需求选合适的方案比追求最先进的算法更重要。最后说一个小心得多记录、多对比。每次跑实验把配置、参数、结果都记下来。不同参数下的轨迹对比、不同场景下的表现对比这些记录积累多了就能形成直觉。下次遇到问题能更快定位原因。SLAM调参是个经验活记录是最好的老师。
返回列表