
1. 为什么要在纯CPU环境下折腾DynaSLAMDynaSLAM这个名字凡是做过动态场景SLAM的人应该都不陌生。它是在ORBSLAM2基础上扩展出来的一个视觉SLAM系统核心卖点就是能处理动态物体——比如街上走动的人、行驶的车辆。传统的ORBSLAM2假设场景是静态的一旦画面里出现大量移动物体特征点匹配就会严重跑偏位姿估计直接崩掉。DynaSLAM通过结合语义分割网络Mask R-CNN和运动一致性检测把动态物体上的特征点剔除掉从而在动态环境中保持稳定。但问题来了官方推荐的配置是带GPU的因为Mask R-CNN推理需要CUDA加速。对于手头只有普通笔记本或者没有独立显卡的开发者来说这就很尴尬。我当初也是因为实验室的服务器排队太紧张索性用自己的台式机i7-8700 32GB内存无独显来搭一套纯CPU版的DynaSLAM跑通之后发现虽然帧率不高但做算法验证和离线数据集测试完全够用。这篇文章就是把我整个配置过程中踩过的坑、绕过的弯、以及最终跑通的完整方案整理出来。适合那些想入门动态SLAM、手头没有GPU、又不想被环境问题卡住的朋友。我会从依赖库的版本选择讲起到ORBSLAM2的编译、DynaSLAM的改造、Mask R-CNN的CPU推理适配最后给出实际跑TUM数据集的测试结果和调优建议。整个过程不需要任何显卡纯CPU就能跑起来。注意纯CPU版的DynaSLAM在推理速度上会比GPU版慢很多如果你的应用场景对实时性要求极高比如无人机避障那还是建议上GPU。但如果是做离线数据集测试、算法原型验证、或者教学演示CPU版完全够用。2. 依赖库的版本陷阱与系统环境准备2.1 操作系统与基础工具链的选择我用的系统是Ubuntu 18.04 LTS为什么不用20.04或者22.04因为DynaSLAM依赖的很多库比如Pangolin、OpenCV 3.x在18.04上兼容性最好官方文档也是基于这个版本写的。如果你用20.04会遇到OpenCV 4.x和ORBSLAM2的兼容问题虽然能改但会多花很多时间。所以我的建议是老老实实用Ubuntu 18.04能省掉至少一半的编译错误。基础工具链的安装很简单sudo apt update sudo apt install -y build-essential cmake git pkg-config sudo apt install -y libglew-dev libboost-all-dev libeigen3-dev这里有个细节libboost-all-dev会装一大堆东西但ORBSLAM2只用到其中几个组件。如果你磁盘空间紧张可以只装libboost-system-dev和libboost-thread-dev。不过现在硬盘都便宜全装也无所谓。2.2 OpenCV的版本抉择3.4还是4.x这是第一个大坑。ORBSLAM2官方要求OpenCV 3.4.x但Ubuntu 18.04默认源里是3.2功能不全。你需要自己编译OpenCV 3.4.16或者3.4.10。我选的是3.4.16因为它是3.4系列的最后一个版本bug最少。编译OpenCV之前先装依赖sudo apt install -y libgtk2.0-dev libavcodec-dev libavformat-dev libswscale-dev sudo apt install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev sudo apt install -y libjasper-dev libdc1394-22-dev注意libjasper-dev在有些源里已经移除了如果装不上可以跳过不影响核心功能。然后下载OpenCV 3.4.16源码编译时一定要关掉CUDA因为我们走纯CPU路线mkdir build cd build cmake -D CMAKE_BUILD_TYPERelease \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D WITH_CUDAOFF \ -D WITH_CUDNNOFF \ -D OPENCV_GENERATE_PKGCONFIGON \ -D WITH_OPENCLOFF \ .. make -j4 sudo make install-D OPENCV_GENERATE_PKGCONFIGON这个选项很关键它会生成opencv.pc文件方便后续用pkg-config查找。编译过程大概需要20-30分钟取决于你的CPU性能。提示如果你之前装过其他版本的OpenCV一定要先卸载干净否则会出现版本冲突。用sudo find / -name opencv*检查一下残留文件。2.3 Pangolin的编译与常见报错Pangolin是ORBSLAM2用来做可视化的库。我推荐用v0.5版本比较稳定。从GitHub克隆下来之后mkdir build cd build cmake .. make -j4 sudo make install常见报错是找不到libpython这是因为Pangolin默认会编译Python绑定。如果你不需要Python接口可以在CMake时加上-D BUILD_PYTHONOFF。另外如果编译时报error: ‘numeric_limits’ is not a member of ‘std’需要在对应的头文件里加上#include limits。这是GCC版本差异导致的Ubuntu 18.04的GCC 7.5比较容易遇到。2.4 Eigen和DBoW2的安装Eigen直接sudo apt install libeigen3-dev就行版本3.3.4足够。DBoW2是ORBSLAM2用来做回环检测的词袋库需要从源码编译。它依赖DLib但DLib的版本不能太新否则会报C标准不兼容。我用的DLib 19.19编译DBoW2时在CMakeLists.txt里把-stdc11改成-stdc14就能顺利通过。3. ORBSLAM2纯CPU编译的完整流程3.1 源码获取与目录结构梳理ORBSLAM2的源码可以从官方仓库克隆但DynaSLAM是基于它修改的所以更推荐直接克隆DynaSLAM的仓库然后单独编译ORBSLAM2部分。目录结构大概是这样的DynaSLAM/ ├── Examples/ ├── include/ ├── src/ ├── Thirdparty/ │ ├── DBoW2/ │ ├── g2o/ │ └── Sophus/ └── Vocabulary/Thirdparty里包含了DBoW2、g2o和Sophus这些都需要单独编译。Vocabulary里是ORB特征词典文件大概100多MB需要提前下载好。3.2 编译Thirdparty中的三个库先编译DBoW2cd Thirdparty/DBoW2 mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease make -j4如果报错找不到DLib需要先安装DLib。g2o的编译类似但要注意它依赖Eigen和Sophus。Sophus是一个header-only的库直接make install就行。这里有个顺序问题必须先编译Sophus再编译g2o否则g2o会找不到Sophus的头文件。我当初就是顺序搞反了卡了半个小时。3.3 主工程的CMake配置与编译回到DynaSLAM根目录创建build文件夹mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease make -j4编译过程中最常见的错误是找不到OpenCV。如果你之前用pkg-config安装了OpenCV 3.4.16需要在CMakeLists.txt里确认find_package(OpenCV 3.4 REQUIRED)能找到正确的路径。可以用pkg-config --modversion opencv检查版本。另一个常见错误是undefined reference to symbol _ZN5boost6system15system_categoryEv这是Boost库链接顺序问题。在CMakeLists.txt里把${Boost_LIBRARIES}放在${OpenCV_LIBS}后面就能解决。编译成功后你会得到lib/libORB_SLAM2.so和一系列可执行文件比如Examples/Monocular/mono_tum。先别急着跑因为DynaSLAM还需要Mask R-CNN的集成。4. Mask R-CNN的CPU推理适配与模型集成4.1 为什么Mask R-CNN是最大的性能瓶颈DynaSLAM的核心创新就是用Mask R-CNN对每一帧图像做语义分割识别出人、车等潜在动态物体。在GPU上这个推理过程大概20-30ms一帧勉强能跟上30fps的摄像头。但在CPU上同样的模型推理一次需要200-500ms直接导致整个SLAM系统卡成幻灯片。我实测过在i7-8700上用TensorFlow CPU版跑Mask R-CNN单帧推理时间平均是320ms。这意味着即使其他环节再快整体帧率也不会超过3fps。对于TUM这种30fps的数据集相当于每10帧才能处理1帧。4.2 模型选型Mask R-CNN还是轻量级替代方案官方DynaSLAM用的是Mask R-CNN基于TensorFlow 1.x。这个版本在CPU上跑起来非常吃力。我尝试过几个替代方案方案推理时间CPU精度集成难度Mask R-CNN (ResNet-101)320ms高中Mask R-CNN (ResNet-50)180ms中高中YOLOv3 分割头90ms中高MobileNetV2 DeepLab60ms中低高最终我选择了Mask R-CNN ResNet-50因为它在精度和速度之间取得了比较好的平衡而且官方代码改动最小。ResNet-101虽然精度更高但CPU上实在太慢除非你只跑离线数据。4.3 TensorFlow CPU版的安装与模型转换DynaSLAM官方用的是TensorFlow 1.12但这个版本在Ubuntu 18.04上需要Python 3.6。我建议用Python 3.6的虚拟环境python3.6 -m venv tf_env source tf_env/bin/activate pip install tensorflow1.12.0 pip install opencv-python3.4.16.59 pip install numpy1.16.0注意numpy版本不能太高否则TensorFlow 1.12会报ImportError。模型文件需要从官方提供的下载链接获取通常是mask_rcnn_coco.h5大概250MB。4.4 将Mask R-CNN嵌入DynaSLAM的代码改造DynaSLAM的代码里有一个MaskRCNN.py脚本负责调用TensorFlow做推理。在CPU模式下需要做几处修改第一把tf.Session()的配置改成CPU模式config tf.ConfigProto( device_count{GPU: 0}, intra_op_parallelism_threads4, inter_op_parallelism_threads4 ) session tf.Session(configconfig)第二把mask_rcnn_coco.h5的加载路径改成绝对路径避免相对路径找不到。第三在visualize.py里把matplotlib的后端改成Agg因为服务器上没有图形界面import matplotlib matplotlib.use(Agg)第四DynaSLAM的C代码通过system()调用Python脚本这个调用是阻塞的。为了不让SLAM主线程卡死我把Python推理放在一个单独的线程里用队列传递图像和分割结果。这样虽然整体帧率还是受限于CPU推理速度但至少不会让SLAM完全停住。5. 跑通TUM数据集的实测记录与调优5.1 数据集准备与配置文件修改TUM数据集的下载很简单我用的rgbd_dataset_freiburg3_walking_xyz这个序列里有两个人一直在走动非常适合测试动态SLAM。下载后解压到Data/目录下。DynaSLAM的配置文件在Examples/RGB-D/下比如TUM3.yaml。需要修改几个参数# 相机内参 Camera.fx: 535.4 Camera.fy: 539.2 Camera.cx: 320.1 Camera.cy: 247.6 # ORB特征点数量 ORBextractor.nFeatures: 1000 ORBextractor.scaleFactor: 1.2 ORBextractor.nLevels: 8 # 是否启用Mask R-CNN UseMaskRCNN: 1ORBextractor.nFeatures从默认的2000降到1000是为了减少CPU负担。实测发现1000个特征点在TUM数据集上已经足够做位姿估计了。5.2 运行命令与参数解释运行RGB-D模式的命令./Examples/RGB-D/rgbd_tum \ Vocabulary/ORBvoc.txt \ Examples/RGB-D/TUM3.yaml \ Data/rgbd_dataset_freiburg3_walking_xyz \ Data/rgbd_dataset_freiburg3_walking_xyz/associations.txt最后一个参数associations.txt是RGB图像和深度图像的时间戳对齐文件TUM数据集里自带。如果你自己采集数据需要自己生成这个文件。运行后Pangolin窗口会显示当前帧的特征点跟踪情况动态物体上的特征点会被标记为红色并剔除。终端会输出每帧的处理时间包括Mask R-CNN推理时间和ORB跟踪时间。5.3 实测性能数据与瓶颈分析我在i7-8700上跑freiburg3_walking_xyz的实测数据环节平均耗时Mask R-CNN推理310msORB特征提取25ms位姿估计15ms局部建图10ms回环检测5ms总计365ms整体帧率约2.7fps对于离线数据集来说这个速度可以接受因为SLAM系统会按照时间戳顺序处理不会丢帧。但如果是实时摄像头输入就会严重滞后。5.4 提升CPU版性能的几个实用技巧第一个技巧降低Mask R-CNN的输入分辨率。官方代码默认把图像缩放到1024x1024我改成512x512后推理时间从310ms降到120ms精度下降不多。修改MaskRCNN.py里的IMAGE_MIN_DIM和IMAGE_MAX_DIM参数即可。第二个技巧跳帧处理。不是每一帧都需要做语义分割可以每3帧做一次中间帧用上一帧的分割结果。这样整体帧率能提升到5-6fps。修改rgbd_tum.cc里的循环逻辑加一个帧计数器。第三个技巧使用OpenMP并行化ORB特征提取。ORBSLAM2本身支持OpenMP在CMakeLists.txt里加上-fopenmp编译选项特征提取时间能从25ms降到15ms。第四个技巧关闭Pangolin可视化。可视化本身会占用不少CPU资源如果你只需要保存轨迹文件可以在代码里把pangolin::FinishFrame()注释掉能省出10%左右的CPU。6. 那些让我熬夜的编译错误与解决思路6.1 OpenCV版本冲突导致的段错误这个错误最隐蔽编译能通过但一运行就Segmentation fault。用gdb调试发现是在cv::Mat的析构函数里崩的。原因是系统里同时存在OpenCV 3.2apt装的和OpenCV 3.4.16手动编译的ORBSLAM2链接到了3.2的库但头文件用的是3.4的ABI不兼容。解决方法卸载apt版的OpenCV确保/usr/local/lib下的OpenCV 3.4.16优先被找到。在/etc/ld.so.conf.d/下新建一个opencv.conf写入/usr/local/lib然后sudo ldconfig。6.2 TensorFlow的CUDA警告与CPU回退即使你装了CPU版的TensorFlow运行时还是会看到一堆CUDA_ERROR的警告。这是因为TensorFlow默认会尝试加载CUDA库找不到就回退到CPU。虽然不影响功能但日志很烦人。可以在Python脚本开头加上import os os.environ[CUDA_VISIBLE_DEVICES] -1这样TensorFlow就不会去探测GPU了。6.3 DBoW2编译时的C标准问题DBoW2的CMakeLists.txt里写的是-stdc11但DLib 19.19需要C14。编译时会报error: ‘make_unique’ is not a member of ‘std’。解决方法把-stdc11改成-stdc14同时确保GCC版本不低于5.0。6.4 Pangolin链接错误的排查路径Pangolin编译成功后ORBSLAM2链接时可能报undefined reference to ‘pangolin::CreateWindowAndBind’。这是因为Pangolin的库路径没被正确找到。在CMakeLists.txt里手动指定set(Pangolin_DIR /usr/local/lib/cmake/Pangolin) find_package(Pangolin REQUIRED) include_directories(${Pangolin_INCLUDE_DIRS}) target_link_libraries(${PROJECT_NAME} ${Pangolin_LIBRARIES})如果还是不行检查/usr/local/lib下有没有libpango*.so文件没有的话说明Pangolin没装好。7. 纯CPU版DynaSLAM的适用边界与后续扩展7.1 什么场景下CPU版够用什么场景下必须上GPU根据我的实测经验纯CPU版DynaSLAM适合以下场景离线数据集测试TUM、KITTI等数据集的离线跑通CPU版完全够用只是慢一点。算法原型验证你想验证一个新的动态特征剔除策略不需要实时性CPU版可以快速迭代。教学演示给学生展示动态SLAM的原理CPU版部署简单不需要昂贵的显卡。但以下场景必须上GPU实时机器人导航需要30fps以上的处理速度CPU版差了一个数量级。大规模建图长时间运行CPU版会积累大量延迟导致轨迹漂移。高分辨率图像4K图像在CPU上推理一次要1秒以上完全不可用。7.2 从CPU版迁移到GPU版的注意事项如果你后续有了GPU想迁移到GPU版需要注意几点第一TensorFlow要换成GPU版CUDA和cuDNN版本要匹配第二Mask R-CNN的模型可以不变但推理速度会提升10倍以上第三ORBSLAM2的CUDA加速是可选的但建议开启能进一步提升特征提取速度。7.3 进一步优化的方向模型量化和剪枝如果你必须在CPU上跑但又想提升速度可以尝试模型量化。把Mask R-CNN的权重从FP32量化到INT8推理速度能提升2-3倍精度损失在可接受范围内。TensorFlow Lite支持这种量化但需要重新转换模型。另一个方向是剪枝去掉Mask R-CNN里冗余的卷积核不过这个操作比较复杂需要重新训练。我在实际使用中的体会是纯CPU版DynaSLAM最大的价值不是性能而是降低了入门门槛。你不需要一块昂贵的显卡就能理解动态SLAM的核心思想跑通完整的流程。等你真正需要实时性能的时候再上GPU也不迟。环境配置这件事最怕的就是一开始就被硬件卡住导致连门都进不去。希望这篇记录能帮你少走一些弯路。