1. 为什么 ORB-SLAM2 的编译安装值得单独写一篇ORB-SLAM2 是视觉 SLAM 领域里被引用最多、被复现最多的开源系统之一支持单目、双目和 RGB-D 三种传感器模式能做实时定位与稀疏建图。很多人第一次接触它都是被论文里的轨迹图和回环效果吸引然后兴冲冲地 clone 源码结果在编译这一步就被按在地上摩擦——报错信息一屏接一屏从 Eigen 版本冲突到 Pangolin 找不到 OpenGL再到 OpenCV 的 contrib 模块缺失几乎每一步都能卡住半天。我前后在不同机器上装过不下十次 ORB-SLAM2从早期的 Ubuntu 16.04 到现在的 22.04从纯 CPU 环境到带 CUDA 的机器踩过的坑基本能凑成一本小册子。这篇内容就是把这些经验整理出来面向的是刚入门视觉 SLAM、准备跑通第一个完整系统的同学也适合那些装过一次但被环境问题劝退、想重新梳理一遍依赖关系的人。核心目标只有一个让你在一台干净的 Ubuntu 机器上把 ORB-SLAM2 从源码编译到能跑通示例数据集并且理解每一步为什么这么做。需要提前说明的是ORB-SLAM2 本身是一个依赖敏感型项目它对第三方库的版本、编译选项、路径配置都有比较明确的要求。官方 README 写得不算详细很多细节要靠社区 issue 和实际试错才能补全。所以这篇不会只给你一串命令而是会把每个依赖的作用、版本选择的理由、常见报错的根因都讲清楚这样你换一台机器或者换一个 Ubuntu 版本时也能自己判断该怎么调整。2. 依赖全景每个库到底在系统里扮演什么角色2.1 核心依赖清单与版本约束ORB-SLAM2 的依赖可以分成三类数学运算类、图像处理类、可视化类。理解这个分类后面排查问题会快很多。依赖库作用推荐版本是否必须Eigen3矩阵运算、李群李代数3.3 及以上必须OpenCV图像读取、特征提取辅助3.4.x 或 4.x必须Pangolin轨迹与点云可视化0.6 及以上必须DBoW2词袋模型回环检测源码内置必须g2o图优化后端源码内置必须SophusSE3/SO3 表示源码内置必须这里有个容易误解的点DBoW2、g2o、Sophus 这三个库是 ORB-SLAM2 源码里自带的 Thirdparty 目录不需要你单独去装。很多人看到编译报错说找不到 g2o就跑去 apt 装一个系统级的 g2o结果反而因为版本不匹配导致更奇怪的链接错误。正确的做法是让项目用它自带的版本除非你明确知道自己在做什么。Eigen 和 OpenCV 是系统级依赖需要提前装好。Pangolin 比较特殊它既是系统级依赖又和 ORB-SLAM2 的可视化模块强耦合版本差异会直接影响编译能否通过。2.2 为什么 Eigen 版本不能太老Eigen 在 ORB-SLAM2 里主要承担两件事一是所有矩阵和向量的底层运算二是通过 Eigen 的几何模块做旋转矩阵、四元数、变换矩阵之间的转换。ORB-SLAM2 的代码里大量使用了Eigen::Isometry3d、Eigen::Quaterniond这类类型还用到了一些在 Eigen 3.3 之后才稳定的 API。如果你系统里默认装的是 Eigen 3.2编译时可能会遇到类似 no member named exp in namespace Eigen 或者模板推导失败的错误。这不是代码写错了而是老版本 Eigen 的几何模块接口不完整。Ubuntu 18.04 默认源里的 Eigen 是 3.3.4基本够用16.04 默认是 3.2.92就偏老了建议手动升级到 3.3 以上。判断当前 Eigen 版本很简单pkg-config --modversion eigen3如果输出低于 3.3就考虑从源码装一个新版本装到/usr/local下避免覆盖系统包管理器管理的文件。2.3 OpenCV 的版本选择与 contrib 问题OpenCV 在 ORB-SLAM2 里负责图像读写、部分特征相关操作以及可视化窗口的绘制。官方代码对 OpenCV 3 和 OpenCV 4 都做了兼容但兼容并不等于零问题。OpenCV 4 相比 3.x 移除了一些旧 C 风格 APIORB-SLAM2 的主干代码已经适配了这些变化但如果你用的是某些较老的 fork 或者自己改过代码就可能遇到CV_LOAD_IMAGE_UNCHANGED这类宏找不到的问题。这个宏在 OpenCV 4 里被cv::IMREAD_UNCHANGED取代了。另一个高频坑是 contrib 模块。ORB-SLAM2 本身不直接依赖 contrib但如果你后续想跑一些扩展功能或者你的 OpenCV 是从源码编译的、没带 contrib某些间接依赖可能会报错。稳妥起见如果你要自己编译 OpenCV建议把 contrib 一起编进去。不过对于大多数只想跑通 ORB-SLAM2 示例的人来说直接用系统源里的 OpenCV 是最省事的sudo apt install libopencv-devUbuntu 20.04 源里是 OpenCV 4.222.04 源里是 4.5都能正常编译 ORB-SLAM2。2.4 Pangolin最容易出问题的可视化依赖Pangolin 是一个轻量级的 OpenGL 可视化库ORB-SLAM2 用它来显示当前帧、地图点和相机轨迹。它本身依赖 OpenGL、GLEW、GLUT 这些图形库所以安装 Pangolin 之前要先把图形相关的开发包补齐。Pangolin 的版本差异对 ORB-SLAM2 影响很大。0.5 版本和 0.6 版本的 API 有变化ORB-SLAM2 较新的代码适配的是 0.6 及以上。如果你装的是老版本 Pangolin编译时会在Viewer相关文件里报一堆函数签名不匹配的错误。我的建议是直接从源码编译 Pangolin 的最新稳定版装到/usr/local下。这样版本可控出问题也好排查。具体步骤后面会展开。3. 从零开始的完整编译链路3.1 系统基础环境准备假设你用的是一台刚装好的 Ubuntu 20.04 或 22.04先更新一下包列表然后把编译工具链和基础依赖装上sudo apt update sudo apt install -y build-essential cmake git pkg-config sudo apt install -y libglew-dev libgl1-mesa-dev libglu1-mesa-dev sudo apt install -y libboost-all-dev libssl-dev这里每一项都有用。build-essential提供 gcc、g、makecmake是 ORB-SLAM2 的构建系统libglew-dev和 Mesa 相关包是 Pangolin 的图形依赖libboost-all-dev在某些 Ubuntu 版本上是 Pangolin 的间接依赖libssl-dev则是为了应对一些网络相关库的编译需求。装完这些先确认 gcc 和 cmake 版本gcc --version cmake --versiongcc 7 以上、cmake 3.10 以上基本都没问题。如果 cmake 太老ORB-SLAM2 的 CMakeLists 里用到的某些特性可能不支持。3.2 Eigen 与 OpenCV 的安装确认先检查系统里有没有 Eigenls /usr/include/eigen3如果没有这个目录就装一个sudo apt install libeigen3-dev装完后 Eigen 的头文件在/usr/include/eigen3但 ORB-SLAM2 的 CMakeLists 里通常是用find_package(Eigen3 REQUIRED)来找的所以只要 pkg-config 能识别到就行。OpenCV 同样先确认pkg-config --modversion opencv4如果输出 4.x 的版本号说明已经装好了。如果提示找不到就装libopencv-dev。注意有些系统里 pkg-config 的名字是opencv而不是opencv4两个都试一下。提示如果你之前手动编译过 OpenCV 并装到了/usr/local可能会出现系统源版本和手动版本共存的情况。这时候 pkg-config 找到的可能是其中一个而 CMake 找到的可能是另一个导致链接时符号冲突。排查方法是看pkg-config --cflags --libs opencv4输出的路径确认它和你预期的一致。3.3 Pangolin 源码编译的细节Pangolin 我建议单独建一个目录来编译方便管理cd ~ git clone https://github.com/stevenlovegrove/Pangolin.git cd Pangolin git checkout v0.8 mkdir build cd build cmake .. make -j4 sudo make install这里选 v0.8 是因为它在 API 稳定性和 ORB-SLAM2 兼容性之间平衡得比较好。如果你用最新的 master偶尔会遇到一些新引入的 API 变化导致 ORB-SLAM2 编译失败。make -j4里的 4 是并行编译的线程数根据你机器的 CPU 核心数调整。核心多就写大一点但不要超过实际核心数太多否则内存可能不够。编译 Pangolin 时最常见的报错是找不到 OpenGL 相关的头文件比如GL/gl.h。这通常是因为libgl1-mesa-dev没装或者装了但路径不对。用dpkg -L libgl1-mesa-dev | grep gl.h确认一下头文件位置。另一个坑是 Pangolin 编译到一半报 Python 相关错误。如果你不需要 Pangolin 的 Python 绑定可以在 cmake 时加-DBUILD_PANGOLIN_PYTHONOFF关掉它能省不少事。3.4 ORB-SLAM2 本体的编译与常见报错依赖都齐了之后编译 ORB-SLAM2 本体cd ~ git clone https://github.com/raulmur/ORB_SLAM2.git cd ORB_SLAM2 chmod x build.sh ./build.shbuild.sh里做的事情是按顺序编译 Thirdparty 里的 DBoW2、g2o然后再编译 ORB-SLAM2 本体。这个顺序不能乱因为本体依赖前面两个库生成的静态库。如果一切顺利最后会在lib目录下生成libORB_SLAM2.so在Examples目录下生成各个可执行文件。但现实往往不会这么顺利下面列几个我遇到频率最高的报错和处理方式。报错一usleep未声明error: usleep was not declared in this scope这是较新 gcc 对 POSIX 标准收紧导致的。usleep在unistd.h里但有些文件没有显式包含。解决办法是在报错的文件顶部加上#include unistd.h。ORB-SLAM2 的 issue 区有专门的补丁也可以直接找现成的修改版。报错二OpenCV 相关符号找不到undefined reference to cv::imread(...)这通常是 CMake 找到的 OpenCV 版本和实际链接的版本不一致。检查CMakeLists.txt里find_package(OpenCV REQUIRED)的输出确认它找到的路径。如果系统里有多个 OpenCV可以手动指定OpenCV_DIR。报错三Pangolin 链接失败undefined reference to pangolin::...先确认 Pangolin 装到了/usr/local然后检查/usr/local/lib是否在链接器搜索路径里。有时候需要手动加-L/usr/local/lib或者运行sudo ldconfig刷新动态库缓存。报错四内存不足导致编译中断g2o 的某些模板文件编译时非常吃内存如果机器内存小于 8Gmake -j4可能会被 OOM killer 杀掉。解决办法是减少并行数用make -j1或者make -j2慢慢编。4. 跑通第一个示例从 TUM 数据集开始4.1 数据集下载与目录组织编译成功后最直接的验证方式是跑 TUM RGB-D 数据集。ORB-SLAM2 官方推荐的是fr1/desk这个序列场景是一个办公桌纹理丰富适合特征法 SLAM。数据集可以从 TUM 的公开页面下载下载后解压到一个目录比如~/data/tum/rgbd_dataset_freiburg1_desk。这个目录里应该包含rgb/、depth/、rgb.txt、depth.txt、associations.txt这些文件。ORB-SLAM2 的示例命令需要三个参数词袋文件路径、数据集配置文件路径、数据集目录路径。词袋文件在Vocabulary/ORBvoc.txt配置文件在Examples/RGB-D/TUM1.yaml。4.2 运行命令与参数含义./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM1.yaml ~/data/tum/rgbd_dataset_freiburg1_desk ~/data/tum/rgbd_dataset_freiburg1_desk/associations.txt四个参数分别是词袋、相机配置、数据集根目录、关联文件。关联文件的作用是把 RGB 图像和深度图像按时间戳配对ORB-SLAM2 需要成对的 RGB-D 帧才能工作。第一次运行时加载词袋文件会花几秒到十几秒这是正常的因为 ORBvoc.txt 是一个比较大的文本文件需要构建搜索树。加载完成后会弹出一个可视化窗口显示当前帧、地图点和轨迹。4.3 运行时的常见异常与处理异常一窗口一闪而过或者直接段错误最常见的原因是 Pangolin 的 OpenGL 上下文创建失败。如果你是在没有图形界面的服务器上跑或者通过远程终端跑就可能遇到这个问题。解决办法是要么在有显示器的机器上跑要么配置虚拟显示。异常二轨迹漂移严重或者跟丢这不一定是代码问题可能是数据集配置文件里的相机内参和实际数据不匹配。TUM 的 fr1 序列对应的是 TUM1.yamlfr2 对应 TUM2.yamlfr3 对应 TUM3.yaml用错了内参会导致尺度或投影异常。异常三运行速度很慢ORB-SLAM2 在 CPU 上跑如果机器性能一般帧率可能只有几帧。这是正常的它不是为实时高帧率设计的。如果想加速可以关掉可视化或者减少提取的特征点数但这会影响精度。5. 那些官方文档不会告诉你的实操经验5.1 关于 build.sh 的隐藏问题build.sh里默认用的是make -j也就是不限制并行数直接用所有核心。在核心多的机器上这可能导致内存瞬间打满。我一般会手动改成make -j4或者根据内存情况调整。另外build.sh在编译 Thirdparty 时如果中途失败下次重新运行可能会因为残留的 CMake 缓存而继续报错。这时候需要进到对应的 build 目录把CMakeCache.txt和CMakeFiles删掉再重来。5.2 多版本 OpenCV 共存时的处理有些同学机器上既有系统源的 OpenCV又有自己编译的 OpenCV这时候 CMake 找到哪个是不确定的。可以在 ORB-SLAM2 的CMakeLists.txt里显式指定set(OpenCV_DIR /usr/local/lib/cmake/opencv4) find_package(OpenCV REQUIRED)这样能强制使用指定版本的 OpenCV避免链接到错误的库。5.3 编译成功但运行时报共享库找不到error while loading shared libraries: libORB_SLAM2.so: cannot open shared object file这是因为libORB_SLAM2.so在 ORB-SLAM2 的lib目录下但系统链接器不知道这个路径。解决办法有两个一是把lib目录加到LD_LIBRARY_PATH二是在/etc/ld.so.conf.d/下加一个配置文件然后运行sudo ldconfig。我倾向于后者因为一次配置永久生效。5.4 关于编译时间的心理预期在一台 4 核 8G 的机器上从零开始编译 Pangolin 加 ORB-SLAM2大概需要 20 到 40 分钟。g2o 的编译尤其慢因为它有大量模板实例化。如果你看到 g2o 编译卡在某个文件很久不要慌它可能只是在慢慢展开模板。6. 编译之后的下一步验证与扩展编译安装只是第一步真正要确认系统能工作还是要跑通数据集并观察轨迹是否合理。我一般会跑两个序列一个 fr1 的一个 fr2 的确认不同内参配置下都能正常工作。如果两个都跑通了说明环境基本没问题。后续如果想做二次开发比如换特征点、改后端优化策略建议先在编译层面保持一个干净可复现的环境把每次修改都记录清楚。ORB-SLAM2 的代码结构不算特别复杂但模块之间耦合比较紧改一处可能影响多处有个稳定的基线环境会省很多事。另外如果你打算在 ROS 下用 ORB-SLAM2编译方式会略有不同需要额外处理 ROS 的 catkin 构建系统和消息依赖。那部分内容展开又是一大篇这里先不铺开但思路是一样的先把依赖关系理清楚再动手编译遇到报错先看根因而不是盲目搜解决方案。我在实际使用中最大的体会是ORB-SLAM2 的编译问题百分之八十都出在依赖版本和路径上剩下百分之二十是编译器标准收紧导致的代码兼容问题。把这两类问题理解透换任何机器都能快速搞定。