1. 从零到一:为什么你的ORB-SLAM3编译总失败?
搞视觉SLAM的,谁没在环境配置上栽过跟头?尤其是ORB-SLAM3,这个集成了视觉、视觉惯导、多地图系统的“全家桶”,功能强大,但依赖复杂,堪称新手劝退器。网上的教程五花八门,有的基于Ubuntu 18.04,有的依赖库版本过时,照着做十有八九会在编译的某个环节卡住,报出一堆看不懂的链接错误或找不到包的提示。2023年了,Ubuntu 22.04 LTS已经成为主流,一些依赖库的API也发生了变化,老教程很多已经不再适用。这篇内容,就是基于最新的Ubuntu 22.04系统,带你走通一遍完整的ORB-SLAM3配置与安装流程,我会把每一步的原理、可能遇到的坑以及我自己的解决方案都讲清楚。目标很简单:让你在干净的Ubuntu 22.04系统上,成功编译并运行ORB-SLAM3的示例,为后续自己的研究和开发铺平道路。
2. 环境基石:系统准备与核心依赖库部署
在动手编译任何大型C++项目之前,搭建一个稳定、兼容的底层环境是重中之重。ORB-SLAM3严重依赖一系列开源库,我们必须先为它们打好地基。
2.1 操作系统与编译器选择
我强烈推荐使用Ubuntu 22.04 LTS作为你的开发环境。LTS意味着长期支持,软件源稳定,社区资源丰富。ORB-SLAM3的代码对C++标准有要求,我们需要较新版本的编译器。
打开终端,首先更新系统软件源并升级现有软件包,这是一个好习惯,能避免很多因版本过旧导致的依赖冲突。
sudo apt update sudo apt upgrade -y接下来,安装编译ORB-SLAM3所必需的构建工具和C++编译器。我们选择GCC 11和G++ 11,它们完全支持C++17标准,并且是Ubuntu 22.04的默认版本,兼容性最好。
sudo apt install -y build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev sudo apt install -y gcc-11 g++-11安装完成后,可以通过gcc-11 --version和g++-11 --version确认版本。为了让系统默认使用我们安装的版本,可以配置一下替代方案(如果你系统里有多个版本的话):
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 110 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 1102.2 Pangolin:不可或缺的轻量级可视化工具
Pangolin是ORB-SLAM3用于显示相机轨迹、地图点、关键帧的图形界面。它非常轻量,封装了OpenGL的复杂操作,是SLAM研究中的标配可视化工具。我们将从源码编译安装,以确保获得最新且兼容的版本。
首先,安装Pangolin所需的一系列依赖。这些依赖包括窗口系统、OpenGL、字体渲染等底层库。
sudo apt install -y libglew-dev libboost-dev libboost-thread-dev libboost-filesystem-dev libeigen3-dev注意:这里安装的是
libeigen3-dev。Eigen是一个高性能的C++模板库,用于线性代数运算,ORB-SLAM3内部大量使用它进行矩阵、向量计算。通常系统源的Eigen版本足够新(Ubuntu 22.04是3.4版本),可以直接使用,无需单独编译。
然后,我们克隆Pangolin的官方仓库。我推荐使用v0.8这个稳定版本分支,主分支有时会有一些实验性改动。
cd ~ git clone https://github.com/stevenlovegrove/Pangolin.git cd Pangolin git checkout v0.8开始编译安装。这里使用CMake的“out-of-source”构建方式,即在单独的build目录中编译,保持源码目录干净。
mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j$(nproc) sudo make install-j$(nproc)参数会让make使用你电脑所有的CPU核心进行并行编译,能显著加快速度。sudo make install会将编译好的库文件和头文件安装到系统默认路径(通常是/usr/local/lib和/usr/local/include),这样其他项目就能直接找到它。
2.3 OpenCV:计算机视觉的“标准答案”
OpenCV是ORB-SLAM3处理图像、提取ORB特征、进行几何计算的核心。ORB-SLAM3需要OpenCV 3.2以上版本。Ubuntu 22.04的软件源提供了OpenCV 4.5.4,这是一个非常稳定且功能完善的版本,我们直接安装即可,省去漫长的源码编译时间。
sudo apt install -y libopencv-dev安装完成后,可以验证一下版本和安装是否成功:
pkg-config --modversion opencv4如果显示4.5.4或类似版本号,说明安装成功。ORB-SLAM3的CMakeLists.txt能够很好地适配OpenCV 4,所以不用担心兼容性问题。
2.4 Eigen3:线性代数的“瑞士军刀”
如前所述,Eigen已经通过libeigen3-dev安装。但我们需要确认它的位置,以便ORB-SLAM3能找到。Eigen是一个纯头文件库,没有.so动态库文件,因此安装后只需确保头文件路径正确。
# 查找Eigen头文件位置 sudo updatedb locate eigen3 | grep /usr/include通常路径是/usr/include/eigen3。在后续编译ORB-SLAM3时,CMake会自动通过find_package(Eigen3 REQUIRED)找到它。
3. ORB-SLAM3本体:获取、编译与基础测试
当所有依赖就位后,我们就可以请出今天的主角了。编译过程本身不复杂,但细节决定成败。
3.1 克隆代码与准备第三方库
ORB-SLAM3官方仓库包含了一个重要的子模块(submodule)——DBoW2和g2o。DBoW2用于词袋模型回环检测,g2o是用于图优化的后端库。我们必须递归克隆,确保这些子模块代码一并下载。
cd ~ git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git ORB_SLAM3 cd ORB_SLAM3 git submodule update --init --recursive这一步非常关键!如果你只克隆了主仓库而没有初始化子模块,编译时一定会报错,提示找不到DBoW2或g2o的头文件。我见过太多人在这里卡住。
3.2 编译配置与参数解读
进入ORB-SLAM3目录,创建并进入构建目录。
mkdir build && cd build接下来是配置CMake。这里有几个关键参数需要理解:
cmake .. -DCMAKE_BUILD_TYPE=Release -DPANGOLIN_VIEWER_DEFAULT=ON-DCMAKE_BUILD_TYPE=Release:指定编译为发布版本。与Debug版本相比,Release版本编译器会进行大量优化(如-O3),去除调试信息,生成的二进制文件运行速度更快,但不利于调试。对于首次安装和测试,用Release就行。-DPANGOLIN_VIEWER_DEFAULT=ON:这是一个重要的选项。ORB-SLAM3支持多种可视化工具,如Pangolin、OpenCV的简单窗口等。这个选项将Pangolin设置为默认的可视化器。如果你不开启,运行时可能需要额外参数指定,对于新手容易造成困惑。
执行cmake ..后,终端会输出一大段信息,仔细查看是否有Found Pangolin、Found OpenCV、Found Eigen3等字样,并确认它们都指向正确的版本。如果某个库显示NOT FOUND,就需要回头检查该库的安装。
3.3 编译过程与常见错误排查
配置成功后,开始编译。
make -j$(nproc)这是最考验耐心的阶段。如果一切顺利,几分钟后你会在build目录下看到生成的可执行文件,例如mono_euroc、stereo_euroc、mono_inertial_euroc等,分别对应单目、双目、单目惯导等不同传感器配置的示例程序。
但更可能的情况是,你会遇到编译错误。下面是我总结的几个高频错误及解决方案:
错误1:fatal error: Eigen/Core: No such file or directory
这通常是因为CMake没有正确找到Eigen。虽然我们安装了libeigen3-dev,但有时Eigen的头文件路径比较特殊。解决方法是手动指定Eigen3的路径。首先找到Eigen3的配置文件:
sudo find /usr -name "Eigen3Config.cmake" -o -name "eigen3-config.cmake" 2>/dev/null假设找到的路径是/usr/lib/cmake/eigen3/Eigen3Config.cmake。那么在运行CMake时,可以显式指定:
cmake .. -DCMAKE_BUILD_TYPE=Release -DPANGOLIN_VIEWER_DEFAULT=ON -DEigen3_DIR=/usr/lib/cmake/eigen3/错误2:链接错误,提示undefined reference topangolin::或DBoW2::等
这是典型的链接阶段错误,意味着编译器找到了头文件(编译通过),但链接器找不到对应的库文件实现。可能的原因和解决步骤:
- 库未安装或安装失败:回顾Pangolin的
sudo make install是否成功执行。可以检查/usr/local/lib下是否有libpangolin.so文件。 - 库路径未加入链接器搜索范围:系统默认的库搜索路径可能不包含
/usr/local/lib。编辑/etc/ld.so.conf文件或在/etc/ld.so.conf.d/目录下创建一个新文件(如local.conf),里面加入一行/usr/local/lib,然后执行sudo ldconfig更新缓存。 - CMake未正确找到库:有时CMake的
find_package会找到错误版本或找不到。可以尝试在ORB-SLAM3的CMakeLists.txt中(位于项目根目录),在find_package(Pangolin REQUIRED)前面,手动设置库路径(不推荐新手直接修改,可作为最后手段)。
错误3:OpenCV 4.x+ requires enabled C++11 support
这个错误在较新的OpenCV版本中可能出现。解决方法是在ORB-SLAM3的CMakeLists.txt中,明确设置C++标准。找到CMakeLists.txt中设置编译标志的地方,添加:
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON)或者,更简单的方法是在CMake命令中指定:
cmake .. -DCMAKE_BUILD_TYPE=Release -DPANGOLIN_VIEWER_DEFAULT=ON -DCMAKE_CXX_STANDARD=113.4 运行第一个示例:EuRoC MAV数据集
编译成功后,我们需要数据来测试。ORB-SLAM3官方示例使用著名的EuRoC MAV数据集。这是一个在室内环境下,由微型飞行器采集的包含双目图像和IMU数据的数据集。
- 下载数据集:从 EuRoC官网 下载一个轻量级序列,例如
MH_01_easy.zip。 - 解压并组织:将下载的zip文件解压,你会得到一个类似
MH_01_easy的文件夹,里面包含mav0子文件夹。 - 准备词汇表:ORB-SLAM3需要预先训练好的词袋模型(Vocabulary)来进行回环检测和重定位。在ORB_SLAM3源码目录下,有一个
Vocabulary文件夹,里面有一个文本文件ORBvoc.txt。这就是我们需要的词汇表文件。确保你后续运行程序时,能正确指定这个文件的路径。 - 运行单目示例:假设你的数据集路径是
~/Datasets/EuRoC/MH_01_easy/mav0,词汇表路径是~/ORB_SLAM3/Vocabulary/ORBvoc.txt,ORB-SLAM3的配置文件路径是~/ORB_SLAM3/Examples/Monocular/EuRoC.yaml。那么运行命令如下:
cd ~/ORB_SLAM3/build ./mono_euroc \ ../../Vocabulary/ORBvoc.txt \ ../../Examples/Monocular/EuRoC.yaml \ /home/你的用户名/Datasets/EuRoC/MH_01_easy/mav0 \ ../../Examples/Monocular/EuRoC_TimeStamps/MH01.txt命令解释:
./mono_euroc: 运行单目EuRoC示例程序。- 第一个参数:词袋文件路径。
- 第二个参数:相机配置文件路径,里面包含了相机内参、畸变系数、ORB特征提取参数等。
- 第三个参数:数据集序列的根目录路径(即包含
cam0,imu0等文件夹的mav0目录的上一级)。 - 第四个参数:时间戳文件路径,该文件告诉程序按什么顺序读取图像。
如果一切配置正确,你将看到一个Pangolin窗口弹出,显示相机实时跟踪的画面、地图点云和估计的轨迹。终端也会输出跟踪状态、帧率等信息。看到这个画面,恭喜你,ORB-SLAM3已经成功在你的系统上跑起来了!
4. 进阶配置与深度集成指南
成功运行示例只是第一步。要想把ORB-SLAM3用在自己的项目或机器人上,还需要了解一些进阶配置和集成技巧。
4.1 理解关键配置文件
ORB-SLAM3的行为很大程度上由YAML配置文件决定。以EuRoC.yaml为例,我们看几个关键部分:
%YAML:1.0 # 相机参数 Camera.type: "PinHole" Camera.fx: 458.654 Camera.fy: 457.296 Camera.cx: 367.215 Camera.cy: 248.375 Camera.k1: -0.28340811 Camera.k2: 0.07395907 Camera.p1: 0.00019359 Camera.p2: 1.76187114e-05 # ORB特征参数 ORBextractor.nFeatures: 1200 ORBextractor.scaleFactor: 1.2 ORBextractor.nLevels: 8 ORBextractor.iniThFAST: 20 ORBextractor.minThFAST: 7 # 相机帧率 Camera.fps: 20.0 # 其他系统参数 Viewer.KeyFrameSize: 0.05 Viewer.KeyFrameLineWidth: 1 Viewer.GraphLineWidth: 0.9- 相机参数:
fx, fy, cx, cy, k1, k2, p1, p2这是相机的内参和畸变系数。这是最重要的部分!你必须使用自己相机的标定结果替换这些值,否则SLAM系统无法正确理解图像几何,必然导致跟踪失败。可以使用OpenCV的calibrateCamera或Kalibr等工具进行相机标定。 - ORB特征参数:
nFeatures: 每帧图像提取的最大ORB特征点数。越多则匹配越鲁棒,但计算量越大。对于VGA分辨率(640x480),1200是个合理的值;对于高清图像,可能需要增加到2000-3000。scaleFactor: 图像金字塔的尺度因子,用于提取尺度不变特征。1.2是常用值。nLevels: 图像金字塔层数。8层是一个较好的平衡。iniThFAST和minThFAST: FAST角点检测的阈值。初始阈值高,如果找不到足够角点,则使用更低的最小阈值。调整它们可以控制特征点的数量和分布。
- Viewer参数:控制Pangolin窗口中关键帧、地图点等元素的显示大小和线宽,按个人喜好调整即可。
4.2 如何接入自己的相机或视频流
ORB-SLAM3的示例都是从图片序列或数据集读取数据。要接入USB摄像头或ROS话题,需要修改代码。这里以接入OpenCV的VideoCapture为例,提供一个最简单的思路:
- 在
Examples/Monocular/mono_euroc.cc附近,创建一个新的主程序文件,例如my_mono_camera.cc。 - 复制
mono_euroc.cc的框架,但将读取图片序列的循环,替换为从cv::VideoCapture读取帧的循环。 - 关键步骤是时间戳。SLAM系统需要每一帧图像对应的时间戳(以秒为单位,double类型)。对于实时视频,可以使用
std::chrono::system_clock来生成。 - 确保在创建SLAM系统对象时,传入正确的配置文件路径(包含你的相机内参!)。
这是一个高度简化的示例片段:
#include <opencv2/videoio.hpp> #include <chrono> // ... 省略SLAM系统初始化代码 (ORB_SLAM3::System SLAM(...)) cv::VideoCapture cap(0); // 打开默认摄像头 if(!cap.isOpened()) { cerr << "Failed to open camera!" << endl; return -1; } cv::Mat im; auto start_time = std::chrono::system_clock::now(); while(true) { cap >> im; if(im.empty()) break; auto now = std::chrono::system_clock::now(); std::chrono::duration<double> timestamp = now - start_time; // 将图像传给SLAM系统 SLAM.TrackMonocular(im, timestamp.count()); // 处理可视化、退出等 // ... }注意:这只是一个概念性示例。实际集成需要考虑图像去畸变(使用配置文件中的畸变系数)、分辨率缩放、线程同步、系统初始化和退出逻辑等复杂问题。对于严肃的项目,建议仔细研究
Examples目录下的源码结构。
4.3 与ROS(机器人操作系统)集成
ORB-SLAM3官方提供了ROS接口包,位于ORB_SLAM3/Examples/ROS/ORB_SLAM3。这允许你轻松地将ORB-SLAM3作为一个ROS节点运行,订阅/camera/image_raw等图像话题,并发布/orb_slam3/camera_pose等位姿话题。
集成步骤大致如下:
- 安装ROS:确保你安装了ROS Noetic(对应Ubuntu 20.04)或ROS 2 Humble(对应Ubuntu 22.04)。ORB-SLAM3的ROS包主要针对ROS 1设计。
- 设置ROS工作空间:
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src - 复制ROS包并编译:
编译过程可能会报错,常见问题是找不到cp -r ~/ORB_SLAM3/Examples/ROS/ORB_SLAM3 ~/catkin_ws/src/ cd ~/catkin_ws catkin_make -j$(nproc)Pangolin、OpenCV或Eigen3。你需要确保ROS环境能找到这些库。一个可靠的方法是在ROS包的CMakeLists.txt中,通过find_package和include_directories、target_link_libraries显式指定路径。 - 配置启动文件:ROS包提供了
.launch文件,你需要在其中指定词汇表文件路径、配置文件路径、相机话题名等参数。 - 运行:
source devel/setup.bash后,使用roslaunch启动相应的launch文件。
ROS集成会引入额外的复杂性,但它是将ORB-SLAM3应用到真实机器人上的标准方式,可以方便地与激光雷达、IMU、控制节点等进行数据交换和系统集成。
5. 性能调优、问题诊断与实战心得
即使程序能跑起来,你可能还会遇到跟踪不稳定、容易丢失、精度不高或者速度慢的问题。这一部分分享一些调优和诊断的经验。
5.1 提升跟踪稳定性和速度
- 特征点数量与质量:配置文件中的
ORBextractor.nFeatures是首要调节参数。在计算资源允许的范围内,适当增加特征点数(如从1200到2000)可以提升在纹理稀疏区域的跟踪鲁棒性。同时,确保图像对比度足够,过于模糊或过曝/欠曝的图像会导致特征提取失败。 - 图像金字塔:
scaleFactor和nLevels决定了特征点的尺度不变性。对于相机运动剧烈、尺度变化大的场景(如无人机快速升降),可以适当增加nLevels(例如到10)或减小scaleFactor(例如到1.1),让系统能在更多尺度上找到匹配,但会增加计算量。 - 初始化策略:ORB-SLAM3的单目模式需要一段初始化过程来估计初始地图和尺度。这段时期相机需要做明显的平移运动(不能是纯旋转),并且场景要有足够的视差和纹理。如果初始化总是失败,尝试在更有纹理的区域,以“左右平移”的方式移动相机开始。
- 使用IMU(如果可用):ORB-SLAM3最大的亮点之一是其出色的视觉惯性融合能力。如果你的设备有IMU,强烈建议使用
mono_inertial或stereo_inertial模式。IMU提供的短期高精度姿态和尺度信息,能极大提升系统的鲁棒性、精度,并解决单目视觉的尺度模糊问题。配置文件中需要正确设置IMU的参数(噪声密度、随机游走等),这些通常需要根据IMU的 datasheet 来设置或通过工具标定。
5.2 常见运行问题诊断
问题:跟踪状态频繁在OK和LOST之间切换。
- 可能原因1:相机运动过快。ORB特征匹配基于描述子,在相邻帧间运动过大时,匹配会失败。尝试降低相机运动速度。
- 可能原因2:图像模糊。检查相机是否失焦,或者快门速度是否过慢导致运动模糊。可以考虑在图像预处理中加入去模糊或使用全局快门相机。
- 可能原因3:场景纹理缺失或重复。如白墙、长走廊。ORB特征在缺乏角点或纹理高度重复的区域难以进行唯一匹配。这是视觉SLAM的固有难题,可以考虑加入其他传感器(如IMU、激光雷达)或使用基于直接法或深度学习的特征。
- 诊断方法:运行程序时,观察Pangolin窗口。如果跟踪正常,你应该能看到稳定的绿色地图点(当前帧观察到的)和红色的关键帧。如果跟踪丢失,地图点会消失。可以尝试开启
Viewer中显示特征点的选项,看看每帧实际提取到了多少特征点。
问题:轨迹漂移严重,回环检测没有生效。
- 可能原因1:词袋模型文件路径错误或损坏。确保
ORBvoc.txt路径正确,并且文件完整(文件很大,约50MB+)。 - 可能原因2:回环检测阈值设置。在系统头文件
ORB_SLAM3/include/LoopClosing.h或相关配置中,有关于回环相似度分数的阈值。如果场景外观变化很大(光照剧烈变化、季节变化),可能需要调整这些阈值,但需谨慎,避免误检。 - 可能原因3:运行时间不够长。回环检测需要积累一定数量的关键帧后才开始工作,并且需要回到之前去过的地方。运行一个闭环的序列才能看到效果。
5.3 个人实战心得与避坑总结
- 环境隔离是美德:强烈建议使用Docker或虚拟环境来配置ORB-SLAM3。这样你可以创建一个纯净、可复现的环境,避免与系统其他软件的依赖冲突。编译成功后,将整个容器或环境镜像保存下来,以后换电脑或重装系统可以瞬间恢复。
- 版本管理:ORB-SLAM3及其依赖库都在持续更新。记录下你成功编译时使用的各库的git commit hash或版本号(如Pangolin v0.8, OpenCV 4.5.4)。未来更新代码后如果出现问题,可以快速回退到稳定版本。
- 调试利器:GDB和日志:当程序崩溃或出现诡异行为时,不要慌。用
gdb启动可执行文件,发生崩溃时可以打印堆栈信息,定位问题代码。同时,ORB-SLAM3内部有丰富的日志输出,可以通过修改include/System.h中的VERBOSE宏定义来开启不同级别的调试信息。 - 从数据集开始,再到真实世界:不要一开始就用自己的摄像头。先用EuRoC、KITTI等标准数据集验证你的安装是否正确,感受不同参数下的效果。这能帮你建立一个性能基准,并排除硬件和数据采集带来的问题。
- 理解原理比跑通代码更重要:ORB-SLAM3是一个复杂的系统。花时间阅读其论文,了解各个模块(跟踪、局部建图、回环检测、地图融合)是如何协同工作的。这样当出现问题时,你才能有的放矢地去调整参数或修改代码,而不是盲目试错。
配置ORB-SLAM3就像拼装一台精密仪器,每一步的严谨都能为后续的研究开发节省大量时间。希望这篇详细的指南能帮你跨过环境配置这道坎,把精力真正投入到SLAM算法的学习和创新中去。