1. 为什么值得花时间啃下这个视觉SLAM demo如果你正在做机器人、自动驾驶或者AR相关的开发,大概率绕不开一个词:视觉SLAM。而ORB-SLAM2,就是这个领域里被引用最多、工程完成度最高的开源方案之一。它用单目、双目或RGB-D相机就能实时算出相机在未知环境里的运动轨迹,同时构建出稀疏的三维点云地图。听起来很玄,但说白了就是:让机器长眼睛,知道自己在哪、周围长什么样。我第一次接触这个项目是在一个室内移动机器人的预研任务里。当时的需求很朴素——让小车在没有GPS的楼道里跑一圈,回来能把走过的路线画出来。试过轮式里程计,跑十米就飘得没法看;试过激光雷达,成本直接劝退。最后落到视觉方案上,ORB-SLAM2是绕不过去的选择。但它的复现过程,说实话,比想象中要折腾。依赖版本、编译报错、数据集格式、运行参数,每一步都有坑。这篇内容就是把我自己从零复现ORB-SLAM2 demo的完整过程拆开来讲。适合谁看:有C++和Linux基础、想入门视觉SLAM的开发者;正在做机器人定位建图、需要快速验证方案的工程师;以及被编译错误折磨到想放弃、需要一份靠谱排错指南的人。我会把每一步为什么这么做、参数怎么来的、遇到问题怎么排查都讲清楚,让你能直接抄作业,也能理解背后的逻辑。2. 复现前的整体思路与环境选型2.1 为什么选ORB-SLAM2而不是其他方案视觉SLAM的开源方案不少,比如LSD-SLAM、DSO、VINS-Mono等。我最终选ORB-SLAM2,核心原因有三个。第一是功能完整。它同时支持单目、双目和RGB-D三种模式,单目能跑但尺度不确定,双目和RGB-D直接给出真实尺度的轨迹,对机器人应用更友好。第二是工程成熟。代码结构清晰,模块划分明确,追踪、局部建图、回环检测、重定位这几个线程各司其职,读代码能学到完整的SLAM系统设计。第三是社区资料多。遇到问题基本能搜到答案,不像一些小众方案卡住了只能自己啃。当然它也有局限。ORB-SLAM2是稀疏点云地图,不能直接拿来做导航避障的栅格地图;对纯旋转运动比较敏感,容易丢跟踪。但作为入门和方案验证,它是最合适的起点。2.2 环境选型的几个关键决策复现ORB-SLAM2,环境选型直接决定你后面会不会被依赖问题搞崩溃。我踩过的坑主要集中在三个地方:操作系统版本、OpenCV版本、Pangolin版本。操作系统我最终锁定在Ubuntu 18.04。原因很实际:ORB-SLAM2官方测试环境就是16.04和18.04,20.04之后一些依赖库的默认版本变了,编译会出各种奇怪问题。如果你用20.04或22.04,不是不能跑,但需要额外处理C++标准、OpenCV兼容等问题,对新手不友好。OpenCV我选的是3.4.5版本。ORB-SLAM2的代码里用到了不少OpenCV 3.x的API,直接上OpenCV 4会有一批函数签名不匹配的报错。3.4.x是3系列的稳定版,兼容性最好。Pangolin选的是0.6版本,它负责可视化界面,0.6对C++11的支持比较稳,再新的版本有些API改动会导致编译失败。提示:如果你已经在用Ubuntu 20.04以上,不想重装系统,可以考虑用Docker容器跑一个18.04的环境,这样能避开系统级依赖冲突,也是我现在做复现实验的常用做法。2.3 依赖清单与版本对照把依赖和版本一次性列清楚,省得你来回试。依赖项推荐版本作用备注Ubuntu18.04 LTS操作系统16.04也可,20.04需额外处理CMake3.10以上构建工具系统自带即可GCC/G++7.5编译器支持C++11OpenCV3.4.5图像处理必须3.x,4.x会报错Eigen33.3.4以上矩阵运算头文件库,安装简单Pangolin0.6可视化负责轨迹和点云显示DBoW2内置回环检测随源码一起编译g2o内置图优化随源码一起编译这张表建议存下来,装环境的时候对着勾。Eigen3和Pangolin是最容易出问题的两个,后面会单独讲。3. 核心细节解析与实操要点3.1 源码结构拆解:每个文件夹在干什么拿到ORB-SLAM2源码后,先别急着编译,花十分钟把目录结构看明白,后面排错会快很多。src目录是核心,里面几个文件对应SLAM的不同模块。Tracking.cpp负责帧间追踪,是前端;LocalMapping.cpp做局部地图优化,是后端的一部分;LoopClosing.cpp处理回环检测,防止长时间运行后轨迹漂移;System.cpp是整个系统的入口,把各个线程串起来。ORBextractor.cpp是ORB特征提取,这是整个系统的眼睛,特征点提得准不准直接影响跟踪效果。include目录放头文件,和src一一对应。Examples目录是各种运行示例,单目、双目、RGB-D各有对应的可执行文件入口。Vocabulary目录里是ORB词典文件,回环检测靠它判断两帧是不是到了同一个地方,这个文件比较大,几十兆,但必须要有。Thirdparty目录里打包了DBoW2和g2o两个第三方库,不用单独装,编译时会一起构建。这点很省心,也是ORB-SLAM2工程做得好的地方。3.2 编译过程中的关键参数与常见报错编译命令本身很简单,进到源码根目录执行:chmod +x build.sh ./build.sh但这个脚本背后做的事不少:先编译Thirdparty里的DBoW2和g2o,再编译主工程。我建议第一次编译时不要用build.sh,而是手动一步步来,这样出错能定位到具体环节。cd Thirdparty/DBoW2 mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j4 cd ../../g2o mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j4 cd ../.. mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j4-DCMAKE_BUILD_TYPE=Release这个参数很关键。不加的话默认是Debug模式,运行速度会慢好几倍,SLAM对实时性要求高,必须用Release。常见的编译报错我整理了几个高频的。OpenCV版本不匹配是最常见的,报错信息里会出现CV_LOAD_IMAGE_UNCHANGED这类宏找不到,这是因为OpenCV 4把这些宏改了。解决办法是装OpenCV 3.4.5,或者手动改代码里的宏定义。Eigen对齐问题也常遇到,报错涉及EIGEN_MAKE_ALIGNED_OPERATOR_NEW,这是Eigen对内存对齐的要求,在涉及Eigen数据结构的类里加上这个宏就行。注意:编译时如果内存不够,make -j4可能因为并行编译把内存吃满导致进程被杀。内存小于8G的机器建议用make -j2甚至make单线程,慢一点但稳。3.3 数据集准备与格式说明ORB-SLAM2官方推荐用TUM和KITTI数据集测试。TUM是室内RGB-D数据集,KITTI是车载双目数据集。我建议先用TUM的RGB-D数据跑通,因为室内场景小、运动慢,容易成功。TUM数据集下载后是一个压缩包,解压出来是rgb和depth两个文件夹,加上一个associations.txt文件。这个txt文件很关键,它把彩色图和深度图按时间戳对齐,格式是每行两列:时间戳、文件路径。如果这个文件不对,程序会报找不到图像或者时间戳对不上。运行RGB-D的命令格式是这样的:./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM1.yaml /path/to/dataset /path/to/associations.txt四个参数分别是:词典路径、配置文件路径、数据集路径、关联文件路径。配置文件里放的是相机内参和ORB提取参数,TUM1.yaml对应的是TUM数据集的相机参数,直接用官方给的就行。4. 实操过程与核心环节实现4.1 从零搭建环境的完整步骤我把整个环境搭建过程按顺序列出来,你照着做基本不会漏。第一步,装基础工具。sudo apt-get install build-essential cmake git pkg-config,这几个是编译必备。第二步,装Eigen3。sudo apt-get install libeigen3-dev,这个最简单,apt直接搞定。装完可以用ls /usr/include/eigen3确认一下。第三步,装Pangolin。这个需要从源码编译,因为它不在apt源里。先装它的依赖:sudo apt-get install libglew-dev libboost-dev libboost-thread-dev,然后下载Pangolin 0.6源码,进目录执行:mkdir build && cd build cmake .. make -j4 sudo make install第四步,装OpenCV 3.4.5。这个是最耗时的,从源码编译大概要半小时到一小时。先装依赖:sudo apt-get install libgtk2.0-dev libavcodec-dev libavformat-dev libswscale-dev,然后下载OpenCV 3.4.5源码,cmake配置时关掉不需要的模块加快编译:cmake -DCMAKE_BUILD_TYPE=Release -DWITH_CUDA=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF .. make -j4 sudo make install第五步,编译ORB-SLAM2。按前面说的手动分步编译。第六步,下载数据集,运行测试。4.2 配置文件参数逐项解读TUM1.yaml这个配置文件里的参数,决定了系统能不能正常跟踪。我挑几个关键的说。Camera.fx、Camera.fy、Camera.cx、Camera.cy是相机内参,分别是焦距和光心在像素坐标系下的位置。这些值来自相机标定,用官方数据集的话直接用给定值,自己采数据的话需要用标定工具算。ORBextractor.nFeatures是每帧提取的特征点数量,默认1000。这个值越大跟踪越稳,但计算量也越大。室内场景1000够用,室外大场景可以调到1500到2000。ORBextractor.scaleFactor是图像金字塔的缩放因子,默认1.2。它决定了特征提取在不同尺度上的密度,1.2是经验值,改小会增加计算量,改大会降低尺度不变性。ORBextractor.nLevels是金字塔层数,默认8。层数越多能应对的尺度变化越大,但提取时间也越长。ThDepth是深度阈值,默认40。意思是深度值超过这个阈值的点被认为是远点,不参与某些计算。这个值要根据实际场景的深度范围调整。4.3 运行过程与结果观察跑起来之后,你会看到两个窗口。一个是Pangolin的可视化窗口,显示当前帧的特征点、地图点和相机轨迹;另一个是OpenCV的图像窗口,显示原始图像和提取的特征点。刚开始几帧,系统在初始化,轨迹可能不动或者跳变,这是正常的。等初始化完成后,相机移动,轨迹就会跟着画出来。如果轨迹平滑、特征点稳定跟踪,说明跑通了。我实测TUM的fr1/xyz序列,在普通笔记本上(i7处理器,无独显)能跑到接近实时,帧率大概20到30帧。如果卡顿,可以降低nFeatures或者减少nLevels。提示:运行前把可视化窗口关掉能提升不少速度,方法是把配置文件里的System::Shutdown()相关显示参数关掉,或者直接改代码注释掉可视化部分。做纯算法验证时我经常这么干。5. 常见问题与排查技巧实录5.1 编译与运行问题速查表问题现象可能原因解决方法编译报OpenCV宏未定义OpenCV版本为4.x换3.4.5或改代码宏Eigen对齐报错类中缺少对齐宏加EIGEN_MAKE_ALIGNED_OPERATOR_NEWPangolin链接失败Pangolin版本不匹配用0.6版本重装运行报找不到词典词典路径错误确认ORBvoc.txt路径跟踪丢失频繁特征点太少或运动太快增加nFeatures,放慢运动轨迹尺度不对单目模式固有缺陷换双目或RGB-D模式程序启动即崩溃配置文件参数错误检查内参和关联文件可视化窗口黑屏显卡驱动或OpenGL问题更新驱动,检查GLEW这张表建议打印出来贴显示器边上,遇到问题先对号入座。5.2 几个我踩过的深坑第一个坑是词典加载慢。ORBvoc.txt有几十兆,每次启动都要加载,第一次跑的时候我以为程序卡死了,等了快一分钟才出来。后来发现这是正常的,词典加载就是慢。如果想加速,可以把词典转成二进制格式,加载能快不少,但需要额外写转换代码。第二个坑是时间戳对齐。TUM数据集的associations.txt如果自己生成,时间戳匹配的容差设得太小会导致很多帧被丢弃,设得太大又会匹配到错误的深度图。官方给的关联文件是调好的,直接用就行,别自己折腾。第三个坑是内存泄漏。长时间运行ORB-SLAM2,内存会慢慢涨。这是因为它维护的地图点越来越多,回环检测的数据库也越来越大。做长时间测试时要注意监控内存,必要时定期重启或者限制地图规模。第四个坑是纯旋转运动。拿着相机原地转圈,跟踪很容易丢。这是因为纯旋转时三角化不出深度,特征点无法定位。解决方法是运动时带一点平移,或者用RGB-D模式,深度直接由传感器给出。5.3 提升跟踪稳定性的实操技巧想让ORB-SLAM2跑得更稳,有几个参数和操作上的技巧。光照要均匀。ORB特征是灰度特征,光照剧烈变化会导致特征匹配失败。室内测试时把灯都打开,避免逆光和强阴影。运动要平缓。快速甩动相机,帧间位移太大,特征点匹配不上。手持测试时慢一点、稳一点,或者用云台。纹理要丰富。对着白墙跑,提取不到特征点,系统直接丢失。测试场景里最好有桌椅、书架、海报这些有纹理的物体。分辨率别太高。图像太大处理不过来,帧率掉得厉害。640x480对室内场景够用,需要更高精度再上1280x720。定期重定位。如果跟踪丢了,把相机对准之前走过的、有特征的地方,系统会自动重定位,恢复跟踪。这个功能很实用,别一丢就重启。6. 复现之后的扩展方向跑通demo只是第一步。基于这个基础,可以往几个方向继续深入。换自己的相机。用USB摄像头或者RGB-D相机采数据,自己做标定,把内参填进配置文件,就能跑自己的场景。标定可以用ROS的camera_calibration工具,或者OpenCV的标定例程。改造成ROS节点。ORB-SLAM2本身不是ROS节点,但社区有ROS版本的封装。改成ROS节点后,可以和机器人其他模块通信,把轨迹和地图发布出去。接入导航栈。稀疏点云不能直接导航,但可以把轨迹和关键帧位姿转成栅格地图,再喂给导航模块。这一步需要额外写转换代码,但思路是通的。对比其他方案。跑通ORB-SLAM2后,可以试试VINS-Mono或者ORB-SLAM3,对比不同方案在同样数据上的表现,理解各自的优劣。我自己在实际操作中的体会是,复现SLAM系统最耗时的不是写代码,而是和环境、依赖、参数搏斗。把环境搭稳、把参数理解透,后面的事情就顺了。第一次跑通看到轨迹画出来的那一刻,前面折腾的时间都值了。
1. 为什么值得花时间啃下这个视觉SLAM demo如果你正在做机器人、自动驾驶或者AR相关的开发,大概率绕不开一个词:视觉SLAM。而ORB-SLAM2,就是这个领域里被引用最多、工程完成度最高的开源方案之一。它用单目、双目或RGB-D相机就能实时算出相机在未知环境里的运动轨迹,同时构建出稀疏的三维点云地图。听起来很玄,但说白了就是:让机器长眼睛,知道自己在哪、周围长什么样。我第一次接触这个项目是在一个室内移动机器人的预研任务里。当时的需求很朴素——让小车在没有GPS的楼道里跑一圈,回来能把走过的路线画出来。试过轮式里程计,跑十米就飘得没法看;试过激光雷达,成本直接劝退。最后落到视觉方案上,ORB-SLAM2是绕不过去的选择。但它的复现过程,说实话,比想象中要折腾。依赖版本、编译报错、数据集格式、运行参数,每一步都有坑。这篇内容就是把我自己从零复现ORB-SLAM2 demo的完整过程拆开来讲。适合谁看:有C++和Linux基础、想入门视觉SLAM的开发者;正在做机器人定位建图、需要快速验证方案的工程师;以及被编译错误折磨到想放弃、需要一份靠谱排错指南的人。我会把每一步为什么这么做、参数怎么来的、遇到问题怎么排查都讲清楚,让你能直接抄作业,也能理解背后的逻辑。2. 复现前的整体思路与环境选型2.1 为什么选ORB-SLAM2而不是其他方案视觉SLAM的开源方案不少,比如LSD-SLAM、DSO、VINS-Mono等。我最终选ORB-SLAM2,核心原因有三个。第一是功能完整。它同时支持单目、双目和RGB-D三种模式,单目能跑但尺度不确定,双目和RGB-D直接给出真实尺度的轨迹,对机器人应用更友好。第二是工程成熟。代码结构清晰,模块划分明确,追踪、局部建图、回环检测、重定位这几个线程各司其职,读代码能学到完整的SLAM系统设计。第三是社区资料多。遇到问题基本能搜到答案,不像一些小众方案卡住了只能自己啃。当然它也有局限。ORB-SLAM2是稀疏点云地图,不能直接拿来做导航避障的栅格地图;对纯旋转运动比较敏感,容易丢跟踪。但作为入门和方案验证,它是最合适的起点。2.2 环境选型的几个关键决策复现ORB-SLAM2,环境选型直接决定你后面会不会被依赖问题搞崩溃。我踩过的坑主要集中在三个地方:操作系统版本、OpenCV版本、Pangolin版本。操作系统我最终锁定在Ubuntu 18.04。原因很实际:ORB-SLAM2官方测试环境就是16.04和18.04,20.04之后一些依赖库的默认版本变了,编译会出各种奇怪问题。如果你用20.04或22.04,不是不能跑,但需要额外处理C++标准、OpenCV兼容等问题,对新手不友好。OpenCV我选的是3.4.5版本。ORB-SLAM2的代码里用到了不少OpenCV 3.x的API,直接上OpenCV 4会有一批函数签名不匹配的报错。3.4.x是3系列的稳定版,兼容性最好。Pangolin选的是0.6版本,它负责可视化界面,0.6对C++11的支持比较稳,再新的版本有些API改动会导致编译失败。提示:如果你已经在用Ubuntu 20.04以上,不想重装系统,可以考虑用Docker容器跑一个18.04的环境,这样能避开系统级依赖冲突,也是我现在做复现实验的常用做法。2.3 依赖清单与版本对照把依赖和版本一次性列清楚,省得你来回试。依赖项推荐版本作用备注Ubuntu18.04 LTS操作系统16.04也可,20.04需额外处理CMake3.10以上构建工具系统自带即可GCC/G++7.5编译器支持C++11OpenCV3.4.5图像处理必须3.x,4.x会报错Eigen33.3.4以上矩阵运算头文件库,安装简单Pangolin0.6可视化负责轨迹和点云显示DBoW2内置回环检测随源码一起编译g2o内置图优化随源码一起编译这张表建议存下来,装环境的时候对着勾。Eigen3和Pangolin是最容易出问题的两个,后面会单独讲。3. 核心细节解析与实操要点3.1 源码结构拆解:每个文件夹在干什么拿到ORB-SLAM2源码后,先别急着编译,花十分钟把目录结构看明白,后面排错会快很多。src目录是核心,里面几个文件对应SLAM的不同模块。Tracking.cpp负责帧间追踪,是前端;LocalMapping.cpp做局部地图优化,是后端的一部分;LoopClosing.cpp处理回环检测,防止长时间运行后轨迹漂移;System.cpp是整个系统的入口,把各个线程串起来。ORBextractor.cpp是ORB特征提取,这是整个系统的眼睛,特征点提得准不准直接影响跟踪效果。include目录放头文件,和src一一对应。Examples目录是各种运行示例,单目、双目、RGB-D各有对应的可执行文件入口。Vocabulary目录里是ORB词典文件,回环检测靠它判断两帧是不是到了同一个地方,这个文件比较大,几十兆,但必须要有。Thirdparty目录里打包了DBoW2和g2o两个第三方库,不用单独装,编译时会一起构建。这点很省心,也是ORB-SLAM2工程做得好的地方。3.2 编译过程中的关键参数与常见报错编译命令本身很简单,进到源码根目录执行:chmod +x build.sh ./build.sh但这个脚本背后做的事不少:先编译Thirdparty里的DBoW2和g2o,再编译主工程。我建议第一次编译时不要用build.sh,而是手动一步步来,这样出错能定位到具体环节。cd Thirdparty/DBoW2 mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j4 cd ../../g2o mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j4 cd ../.. mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j4-DCMAKE_BUILD_TYPE=Release这个参数很关键。不加的话默认是Debug模式,运行速度会慢好几倍,SLAM对实时性要求高,必须用Release。常见的编译报错我整理了几个高频的。OpenCV版本不匹配是最常见的,报错信息里会出现CV_LOAD_IMAGE_UNCHANGED这类宏找不到,这是因为OpenCV 4把这些宏改了。解决办法是装OpenCV 3.4.5,或者手动改代码里的宏定义。Eigen对齐问题也常遇到,报错涉及EIGEN_MAKE_ALIGNED_OPERATOR_NEW,这是Eigen对内存对齐的要求,在涉及Eigen数据结构的类里加上这个宏就行。注意:编译时如果内存不够,make -j4可能因为并行编译把内存吃满导致进程被杀。内存小于8G的机器建议用make -j2甚至make单线程,慢一点但稳。3.3 数据集准备与格式说明ORB-SLAM2官方推荐用TUM和KITTI数据集测试。TUM是室内RGB-D数据集,KITTI是车载双目数据集。我建议先用TUM的RGB-D数据跑通,因为室内场景小、运动慢,容易成功。TUM数据集下载后是一个压缩包,解压出来是rgb和depth两个文件夹,加上一个associations.txt文件。这个txt文件很关键,它把彩色图和深度图按时间戳对齐,格式是每行两列:时间戳、文件路径。如果这个文件不对,程序会报找不到图像或者时间戳对不上。运行RGB-D的命令格式是这样的:./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM1.yaml /path/to/dataset /path/to/associations.txt四个参数分别是:词典路径、配置文件路径、数据集路径、关联文件路径。配置文件里放的是相机内参和ORB提取参数,TUM1.yaml对应的是TUM数据集的相机参数,直接用官方给的就行。4. 实操过程与核心环节实现4.1 从零搭建环境的完整步骤我把整个环境搭建过程按顺序列出来,你照着做基本不会漏。第一步,装基础工具。sudo apt-get install build-essential cmake git pkg-config,这几个是编译必备。第二步,装Eigen3。sudo apt-get install libeigen3-dev,这个最简单,apt直接搞定。装完可以用ls /usr/include/eigen3确认一下。第三步,装Pangolin。这个需要从源码编译,因为它不在apt源里。先装它的依赖:sudo apt-get install libglew-dev libboost-dev libboost-thread-dev,然后下载Pangolin 0.6源码,进目录执行:mkdir build && cd build cmake .. make -j4 sudo make install第四步,装OpenCV 3.4.5。这个是最耗时的,从源码编译大概要半小时到一小时。先装依赖:sudo apt-get install libgtk2.0-dev libavcodec-dev libavformat-dev libswscale-dev,然后下载OpenCV 3.4.5源码,cmake配置时关掉不需要的模块加快编译:cmake -DCMAKE_BUILD_TYPE=Release -DWITH_CUDA=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF .. make -j4 sudo make install第五步,编译ORB-SLAM2。按前面说的手动分步编译。第六步,下载数据集,运行测试。4.2 配置文件参数逐项解读TUM1.yaml这个配置文件里的参数,决定了系统能不能正常跟踪。我挑几个关键的说。Camera.fx、Camera.fy、Camera.cx、Camera.cy是相机内参,分别是焦距和光心在像素坐标系下的位置。这些值来自相机标定,用官方数据集的话直接用给定值,自己采数据的话需要用标定工具算。ORBextractor.nFeatures是每帧提取的特征点数量,默认1000。这个值越大跟踪越稳,但计算量也越大。室内场景1000够用,室外大场景可以调到1500到2000。ORBextractor.scaleFactor是图像金字塔的缩放因子,默认1.2。它决定了特征提取在不同尺度上的密度,1.2是经验值,改小会增加计算量,改大会降低尺度不变性。ORBextractor.nLevels是金字塔层数,默认8。层数越多能应对的尺度变化越大,但提取时间也越长。ThDepth是深度阈值,默认40。意思是深度值超过这个阈值的点被认为是远点,不参与某些计算。这个值要根据实际场景的深度范围调整。4.3 运行过程与结果观察跑起来之后,你会看到两个窗口。一个是Pangolin的可视化窗口,显示当前帧的特征点、地图点和相机轨迹;另一个是OpenCV的图像窗口,显示原始图像和提取的特征点。刚开始几帧,系统在初始化,轨迹可能不动或者跳变,这是正常的。等初始化完成后,相机移动,轨迹就会跟着画出来。如果轨迹平滑、特征点稳定跟踪,说明跑通了。我实测TUM的fr1/xyz序列,在普通笔记本上(i7处理器,无独显)能跑到接近实时,帧率大概20到30帧。如果卡顿,可以降低nFeatures或者减少nLevels。提示:运行前把可视化窗口关掉能提升不少速度,方法是把配置文件里的System::Shutdown()相关显示参数关掉,或者直接改代码注释掉可视化部分。做纯算法验证时我经常这么干。5. 常见问题与排查技巧实录5.1 编译与运行问题速查表问题现象可能原因解决方法编译报OpenCV宏未定义OpenCV版本为4.x换3.4.5或改代码宏Eigen对齐报错类中缺少对齐宏加EIGEN_MAKE_ALIGNED_OPERATOR_NEWPangolin链接失败Pangolin版本不匹配用0.6版本重装运行报找不到词典词典路径错误确认ORBvoc.txt路径跟踪丢失频繁特征点太少或运动太快增加nFeatures,放慢运动轨迹尺度不对单目模式固有缺陷换双目或RGB-D模式程序启动即崩溃配置文件参数错误检查内参和关联文件可视化窗口黑屏显卡驱动或OpenGL问题更新驱动,检查GLEW这张表建议打印出来贴显示器边上,遇到问题先对号入座。5.2 几个我踩过的深坑第一个坑是词典加载慢。ORBvoc.txt有几十兆,每次启动都要加载,第一次跑的时候我以为程序卡死了,等了快一分钟才出来。后来发现这是正常的,词典加载就是慢。如果想加速,可以把词典转成二进制格式,加载能快不少,但需要额外写转换代码。第二个坑是时间戳对齐。TUM数据集的associations.txt如果自己生成,时间戳匹配的容差设得太小会导致很多帧被丢弃,设得太大又会匹配到错误的深度图。官方给的关联文件是调好的,直接用就行,别自己折腾。第三个坑是内存泄漏。长时间运行ORB-SLAM2,内存会慢慢涨。这是因为它维护的地图点越来越多,回环检测的数据库也越来越大。做长时间测试时要注意监控内存,必要时定期重启或者限制地图规模。第四个坑是纯旋转运动。拿着相机原地转圈,跟踪很容易丢。这是因为纯旋转时三角化不出深度,特征点无法定位。解决方法是运动时带一点平移,或者用RGB-D模式,深度直接由传感器给出。5.3 提升跟踪稳定性的实操技巧想让ORB-SLAM2跑得更稳,有几个参数和操作上的技巧。光照要均匀。ORB特征是灰度特征,光照剧烈变化会导致特征匹配失败。室内测试时把灯都打开,避免逆光和强阴影。运动要平缓。快速甩动相机,帧间位移太大,特征点匹配不上。手持测试时慢一点、稳一点,或者用云台。纹理要丰富。对着白墙跑,提取不到特征点,系统直接丢失。测试场景里最好有桌椅、书架、海报这些有纹理的物体。分辨率别太高。图像太大处理不过来,帧率掉得厉害。640x480对室内场景够用,需要更高精度再上1280x720。定期重定位。如果跟踪丢了,把相机对准之前走过的、有特征的地方,系统会自动重定位,恢复跟踪。这个功能很实用,别一丢就重启。6. 复现之后的扩展方向跑通demo只是第一步。基于这个基础,可以往几个方向继续深入。换自己的相机。用USB摄像头或者RGB-D相机采数据,自己做标定,把内参填进配置文件,就能跑自己的场景。标定可以用ROS的camera_calibration工具,或者OpenCV的标定例程。改造成ROS节点。ORB-SLAM2本身不是ROS节点,但社区有ROS版本的封装。改成ROS节点后,可以和机器人其他模块通信,把轨迹和地图发布出去。接入导航栈。稀疏点云不能直接导航,但可以把轨迹和关键帧位姿转成栅格地图,再喂给导航模块。这一步需要额外写转换代码,但思路是通的。对比其他方案。跑通ORB-SLAM2后,可以试试VINS-Mono或者ORB-SLAM3,对比不同方案在同样数据上的表现,理解各自的优劣。我自己在实际操作中的体会是,复现SLAM系统最耗时的不是写代码,而是和环境、依赖、参数搏斗。把环境搭稳、把参数理解透,后面的事情就顺了。第一次跑通看到轨迹画出来的那一刻,前面折腾的时间都值了。