Ubuntu 18.04部署LSD-SLAM:直接法SLAM环境配置与编译指南
1. 项目概述:在Ubuntu 18.04上部署LSD-SLAM
如果你正在研究机器人视觉或者三维重建,大概率听说过ORB-SLAM、VINS-Mono这些大名鼎鼎的算法。但今天我想聊的是一个在SLAM(即时定位与地图构建)发展史上有着独特地位的开源项目——LSD-SLAM。它全称是Large-Scale Direct monocular SLAM,由德国慕尼黑工业大学计算机视觉组在2014年提出。与当时主流的基于特征点的方法不同,LSD-SLAM采用了直接法,直接利用图像像素的灰度信息进行位姿估计和稠密地图构建,这为单目相机实现大尺度、半稠密的环境重建提供了可能。
然而,这个经典项目在较新的系统上编译运行,常常会遇到各种依赖和兼容性问题。特别是对于很多实验室和开发者来说,Ubuntu 18.04 LTS(Bionic Beaver)依然是一个稳定且广泛使用的开发平台,许多机器人中间件(如ROS Melodic)也基于此版本。因此,在Ubuntu 18.04上成功搭建并运行LSD-SLAM,就成了一道必须跨过的门槛。这不仅仅是“跑通一个Demo”,更是理解直接法SLAM原理、掌握复杂开源项目环境配置、以及为后续算法研究和二次开发打下基础的关键一步。本文将基于我多次在Ubuntu 18.04上部署LSD-SLAM的经验,为你拆解整个过程,从环境准备、源码编译、到运行调试和问题排查,提供一份可直接“抄作业”的详细指南。
2. 环境准备与核心依赖解析
在Ubuntu 18.04上编译一个像LSD-SLAM这样有一定历史的C++项目,第一步也是最关键的一步,就是搭建一个正确且完整的依赖环境。很多编译失败的问题,根源都在于此。
2.1 系统基础环境确认
首先,确保你的Ubuntu 18.04系统是最新的。打开终端,执行以下命令更新软件源和已安装的包:
sudo apt update sudo apt upgrade -y接下来,安装编译所需的通用工具链,包括构建工具、版本控制工具和必要的开发库:
sudo apt install -y build-essential cmake git pkg-configbuild-essential:包含了GCC/G++编译器、make等核心编译工具。cmake:LSD-SLAM使用CMake作为构建系统,这是必须的。git:用于从GitHub克隆源码。pkg-config:帮助查找库文件和头文件路径的工具。
2.2 核心依赖库的安装与版本选择
LSD-SLAM的核心依赖包括OpenCV、Eigen、SuiteSparse、Pangolin等。在Ubuntu 18.04的官方仓库中,这些库的版本可能不完全匹配LSD-SLAM原始代码的要求,需要特别注意。
1. OpenCV:LSD-SLAM对OpenCV的版本有一定要求,通常需要OpenCV 2.x或3.x。Ubuntu 18.04默认仓库提供的是OpenCV 3.2。这个版本基本兼容,但为了减少潜在问题,我建议安装一个更通用的OpenCV 3.4.x。我们可以通过源码编译安装,但为了快速部署,使用官方仓库版本也是可行的。
sudo apt install -y libopencv-dev安装后,可以通过pkg-config --modversion opencv检查版本,确认是3.2.0。
2. Eigen3:Eigen是一个高性能的C++模板库,用于线性代数运算。LSD-SLAM大量使用了它。Ubuntu 18.04仓库中的Eigen3版本(通常是3.3.4)是合适的。
sudo apt install -y libeigen3-dev3. SuiteSparse:SuiteSparse是一套用于稀疏矩阵计算的库,LSD-SLAM用它来求解大规模线性系统。这是必须的依赖。
sudo apt install -y libsuitesparse-dev4. Pangolin:这是一个轻量级的OpenGL显示/交互库,LSD-SLAM用它来可视化相机轨迹和重建的地图。这是最容易出问题的依赖之一。Ubuntu仓库中的版本可能太旧或缺失。最可靠的方式是从源码编译安装。
# 安装Pangolin的依赖 sudo apt install -y libglew-dev libwayland-dev libxkbcommon-dev wayland-protocols sudo apt install -y ffmpeg libavcodec-dev libavutil-dev libavformat-dev libswscale-dev sudo apt install -y libpng-dev libjpeg-dev # 克隆并编译Pangolin cd ~ git clone https://github.com/stevenlovegrove/Pangolin.git cd Pangolin mkdir build && cd build cmake .. make -j$(nproc) sudo make install注意:编译Pangolin时,如果遇到关于Wayland的错误,可以尝试在CMake时加上
-DBUILD_WAYLAND=OFF来禁用Wayland支持,因为很多问题源于Wayland与X11的兼容性。命令改为:cmake -DBUILD_WAYLAND=OFF ..。
5. 其他可选但推荐的库:
libboost-all-dev:Boost库,一些工具可能用到。libtbb-dev:Intel线程构建块,用于并行计算,可能提升性能。
2.3 创建工作空间与获取源码
不建议在系统目录直接编译。创建一个独立的工作目录是个好习惯。
mkdir -p ~/lsd_slam_ws/src cd ~/lsd_slam_ws/src接下来获取源码。原始的LSD-SLAM仓库(tum-vision/lsd_slam)可能对最新系统支持不佳。我们可以使用一个针对Ubuntu 18.04适配过的分支或复刻版本。根据网络信息,Rick0514/Ubuntu18.04-LSD-SLAM是一个可行的选择。
git clone https://github.com/Rick0514/Ubuntu18.04-LSD-SLAM.git lsd_slam cd lsd_slam这个仓库通常已经包含了lsd_slam_core(核心算法库)、lsd_slam_viewer(可视化工具)等子模块或目录结构。
3. 源码编译与关键配置修改
环境就绪后,就进入了核心的编译环节。LSD-SLAM的CMakeLists.txt可能需要进行一些调整才能适应Ubuntu 18.04的环境。
3.1 编译lsd_slam_core核心库
首先编译最核心的部分。进入lsd_slam_core目录(如果仓库结构如此):
cd ~/lsd_slam_ws/src/lsd_slam/lsd_slam_core mkdir build cd build现在运行CMake生成Makefile。这里有几个关键点:
- 指定Eigen3路径:虽然我们安装了
libeigen3-dev,但有时CMake找不到。可以显式指定。 - 处理OpenCV版本:确保CMake找到的是我们安装的OpenCV 3.2。
一个相对稳健的CMake命令如下:
cmake .. -DCMAKE_BUILD_TYPE=Release -DEIGEN3_INCLUDE_DIR=/usr/include/eigen3-DCMAKE_BUILD_TYPE=Release:指定为发布模式,编译器会进行优化,程序运行更快。-DEIGEN3_INCLUDE_DIR:明确告诉CMake Eigen3头文件的位置。
执行后,仔细观察CMake的输出。重点关注以下几行:
Found OpenCV: ... (found version 3.2.0)确认OpenCV版本。Found Eigen3: ...确认Eigen3找到。Found Pangolin: ...确认Pangolin找到。
如果Pangolin找不到,可能需要设置Pangolin_DIR变量,指向Pangolin安装后的CMake配置文件路径,通常是/usr/local/lib/cmake/Pangolin。
CMake成功后,开始编译:
make -j$(nproc)-j$(nproc)表示使用你电脑所有可用的CPU核心并行编译,能显著加快速度。
3.2 编译lsd_slam_viewer可视化工具
核心库编译成功后,再编译可视化部分。回到源码根目录,进入lsd_slam_viewer:
cd ~/lsd_slam_ws/src/lsd_slam/lsd_slam_viewer mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j$(nproc)可视化工具依赖于核心库和Pangolin。如果CMake报错找不到lsd_slam_core,可能需要检查上一步核心库是否成功编译,并生成了liblsd_slam_core.so之类的库文件。有时需要在CMake时通过-Dlsd_slam_core_DIR指定其路径。
3.3 常见编译错误与修复方案
在Ubuntu 18.04上,你很可能会遇到以下几个经典错误:
错误1:fatal error: Eigen/Core: No such file or directory原因:CMake没有正确找到Eigen3的头文件路径。解决:
- 确保已安装
libeigen3-dev。 - 在CMake命令中显式指定路径:
-DEIGEN3_INCLUDE_DIR=/usr/include/eigen3。 - 如果Eigen安装在非标准路径,需要相应修改。
错误2:error: ‘CV_LOAD_IMAGE_GRAYSCALE’ was not declared in this scope原因:这是OpenCV版本兼容性问题。CV_LOAD_IMAGE_GRAYSCALE是OpenCV 2.x的宏,在OpenCV 3.x和4.x中已被cv::IMREAD_GRAYSCALE取代。解决:需要修改源代码。在报错的文件中(通常是ImageSource.cpp或IOWrapper/OpenCV/ImageSource_OpenCV.cpp),找到使用CV_LOAD_IMAGE_GRAYSCALE的地方,将其替换为cv::IMREAD_GRAYSCALE。同时,需要包含正确的头文件#include <opencv2/imgcodecs.hpp>。这是一个典型的针对新系统适配老代码的修改。
错误3:Pangolin相关链接错误,如undefined reference to ‘pangolin::’原因:链接器找不到Pangolin库。可能因为Pangolin没有正确安装,或者CMake没有找到。解决:
- 确认Pangolin已通过
sudo make install安装到系统目录(/usr/local)。 - 尝试在CMake时清除缓存重新配置:删除
build目录,重新执行cmake。 - 可以尝试手动指定Pangolin路径:
cmake .. -DPangolin_DIR=/usr/local/lib/cmake/Pangolin。
错误4:error: ‘usleep’ was not declared in this scope原因:usleep函数在较新的C++标准或特定系统上需要特定的头文件。解决:在报错的源文件开头添加头文件#include <unistd.h>。
4. 运行测试与数据准备
编译成功后,我们终于可以运行LSD-SLAM了。它需要一个图像序列作为输入。
4.1 获取测试数据集
LSD-SLAM官方提供了一些测试数据集。一个常用的室内场景是desk序列。我们可以从TUM的服务器下载:
cd ~/lsd_slam_ws wget https://vision.in.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_desk.tgz tar -xzvf rgbd_dataset_freiburg1_desk.tgz解压后会得到一个包含rgb/(彩色图像)和depth/(深度图,LSD-SLAM单目版本不需要)的文件夹,以及一个rgb.txt文件,里面记录了图像的时间戳和文件名。
4.2 运行LSD-SLAM
运行LSD-SLAM通常需要启动两个程序:一个是核心的SLAM节点(lsd_slam_core),另一个是可视化界面(lsd_slam_viewer)。它们之间通过ROS或简单的网络接口通信。由于我们可能没有安装ROS,LSD-SLAM自带了一个基于TCP的通信方式。
第一步:启动可视化器在一个终端中,进入lsd_slam_viewer的编译目录并运行:
cd ~/lsd_slam_ws/src/lsd_slam/lsd_slam_viewer/build ./bin/lsd_slam_viewer如果一切正常,会弹出一个黑色的Pangolin窗口。这表明可视化部分启动成功,正在等待SLAM核心发送数据。
第二步:运行SLAM核心并指定数据集打开另一个终端,进入lsd_slam_core的编译目录,运行主程序并指定数据集路径和关联文件:
cd ~/lsd_slam_ws/src/lsd_slam/lsd_slam_core/build ./bin/lsd_slam_dataset ~/lsd_slam_ws/rgbd_dataset_freiburg1_desk/rgb/ ~/lsd_slam_ws/rgbd_dataset_freiburg1_desk/rgb.txt- 第一个参数是图像目录的路径。
- 第二个参数是图像关联文件(
rgb.txt)的路径。
程序开始运行后,你会在终端看到它读取图像、初始化、跟踪位姿的输出信息。同时,在可视化器窗口中,你应该能看到:
- 左侧:当前相机拍摄的图像。
- 右侧:重建出的半稠密点云地图和估计的相机轨迹(通常是一条逐渐增长的线)。
4.3 运行参数解析与调整
lsd_slam_dataset程序可以接受一些命令行参数来调整行为:
-calib [文件]:指定相机标定文件。如果数据集文件夹内有camera.txt,程序会自动读取。如果没有,你需要准备一个。对于TUM数据集,标定参数通常是固定的。你可以创建一个camera.txt文件,内容类似:
Pinhole 525.0 525.0 319.5 239.5 in_width 640 in_height 480这表示焦距(fx, fy)=525,光学中心(cx, cy)在(319.5, 239.5),图像分辨率640x480。
-speed [浮点数]:播放速度因子。1.0表示实时,0.5表示慢速播放,2.0表示快速播放。对于调试,可以从0.5开始。-mode [0/1/2]:运行模式。0=仅从数据集读取,1=处理数据集并输出结果,2=使用外部图像源。
运行命令可以整合为:
./bin/lsd_slam_dataset -calib ~/lsd_slam_ws/rgbd_dataset_freiburg1_desk/camera.txt -speed 0.5 ~/lsd_slam_ws/rgbd_dataset_freiburg1_desk/rgb/ ~/lsd_slam_ws/rgbd_dataset_freiburg1_desk/rgb.txt5. 深度问题排查与性能优化
即使程序成功运行,你可能还会遇到跟踪丢失、地图漂移、重建效果差等问题。这部分分享一些进阶的排查和优化经验。
5.1 运行时常见问题与诊断
问题1:可视化器黑屏或闪退,核心程序报错Failed to connect to viewer诊断:两个进程之间的网络通信失败。LSD-SLAM默认使用本地回环地址(127.0.0.1)和特定端口通信。解决:
- 确保先启动
lsd_slam_viewer,再启动lsd_slam_core。 - 检查是否有防火墙规则阻止了本地进程间通信(在Ubuntu上通常不会)。
- 可以尝试在运行核心程序时指定主机和端口(但需要查看源码是否支持该参数,通常不支持修改)。最根本的解决方法是检查
lsd_slam_core中IOWrapper/目录下的网络通信代码,确认端口号(默认可能是5000)是否被占用。
问题2:跟踪很快丢失,终端大量输出TRACKING LOST诊断:这是直接法SLAM的常见问题。原因可能是:
- 相机运动过快:图像间变化太大,直接法基于灰度不变假设,无法找到正确的像素对应关系。
- 光照变化剧烈:数据集中有光照突变,违反了灰度不变假设。
- 图像模糊:相机对焦不准或运动导致模糊。
- 相机标定参数错误:内参不准确会严重影响位姿估计。解决:
- 使用
-speed 0.2更慢地播放数据集,给算法更多处理时间。 - 检查
camera.txt标定文件,确保参数与数据集匹配。TUM RGB-D数据集的标定参数可以在其官网找到。 - 尝试其他运动更缓慢、光照更稳定的数据集序列。
问题3:重建的地图点云非常稀疏或扭曲诊断:深度滤波器收敛不佳或深度值传播有问题。直接法SLAM的地图是“半稠密”的,只在梯度明显的区域计算深度。如果图像纹理较弱,地图就会稀疏。解决:
- 这是算法本身的特性。可以尝试调整源码中
DepthEstimation.cpp或SlamSystem.cpp中的参数,如深度滤波器的初始化方差、收敛阈值等。但修改这些参数需要你对算法有较深理解。 - 确保输入图像是灰度图。虽然程序通常会自动转换,但最好确认一下。
5.2 关键源码参数调整(进阶)
如果你想深入优化或适应自己的场景,可能需要修改源码。这里列举几个关键文件和作用:
lsd_slam_core/SlamSystem.h/.cpp:整个SLAM系统的总控,可以调整跟踪、建图、回环检测的开关和主要参数。lsd_slam_core/DepthEstimation.cpp:深度估计的核心,修改深度滤波器参数(如MIN_GOODPERGOODBAD_PIXEL)会影响深度点的生成和收敛速度。lsd_slam_core/Tracking/TrackingReference.cpp:跟踪参考帧的管理,影响跟踪的鲁棒性。CMakeLists.txt:可以修改编译优化等级(如-O3)、添加调试信息(-g)或启用SSE等指令集加速。
修改示例:提高跟踪鲁棒性在Tracking/TrackingReference.cpp中,有一个函数负责选择用于跟踪的关键点。你可以尝试降低梯度阈值,让算法在纹理稍弱的区域也能提取到点,但这可能会增加计算量和噪声。修改需谨慎,每次只改一个参数并观察效果。
5.3 使用ROS运行LSD-SLAM(可选扩展)
原始的LSD-SLAM也提供了ROS功能包。如果你在Ubuntu 18.04上安装了ROS Melodic,可以尝试用ROS来运行,这样能更方便地连接真实的相机(如USB摄像头或RGB-D相机如Kinect)。
- 安装ROS Melodic:按照ROS官网指引安装完整版或基础版。
- 创建ROS工作空间并编译:
注意,ROS版本的代码可能需要额外的依赖,如mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src # 假设你把lsd_slam源码放在这里 cp -r ~/lsd_slam_ws/src/lsd_slam ./ cd ~/catkin_ws catkin_make -j$(nproc)ros-melodic-libg2o。编译时可能会遇到更多兼容性问题,需要根据错误信息逐一解决。 - 运行:使用
roslaunch lsd_slam_core live.launch等命令启动。
ROS方式集成度更高,但环境配置更复杂,更适合与真实的机器人系统对接。对于初次接触,建议先从非ROS的数据集版本入手。
6. 项目总结与延伸思考
在Ubuntu 18.04上成功部署LSD-SLAM,就像完成了一次经典的软件考古与工程实践。这个过程里,你不仅是在安装一个程序,更是在梳理一个复杂C++项目的依赖脉络,学习如何解决跨版本的编译兼容性问题,并直观感受直接法SLAM的优缺点。
从我多次部署的经验来看,耐心和系统化排查是关键。不要被一长串的错误信息吓倒,按照“检查依赖->修正源码->调整编译选项”的流程,大部分问题都能解决。那个CV_LOAD_IMAGE_GRAYSCALE错误,几乎是所有在老系统上编译OpenCV 2时代项目的“必修课”。而Pangolin的编译,则是对你系统图形开发库是否完整的一次检验。
运行起来之后,观察LSD-SLAM的重建结果,你会发现它和ORB-SLAM这类特征点法有很大不同。它的地图是半稠密的,带有梯度信息的像素点才有深度值,这导致地图看起来像一幅“素描”。它的优势在于能够直接利用所有像素信息,在纹理丰富的区域理论上更稠密,且对模糊、快速运动有一定容忍度。但劣势也很明显:严重依赖灰度不变假设,对光照变化极其敏感;计算量大;回环检测和全局优化模块相对简单。
因此,把LSD-SLAM在Ubuntu 18.04上跑通,只是一个起点。你可以以此为基地,做很多有趣的事情:
- 代码走读:结合原论文,深入阅读
SlamSystem、SE3Tracker、DepthEstimation等核心模块的代码,理解直接法跟踪、深度滤波器的实现细节。 - 性能分析:使用
gprof或perf工具分析程序热点,看看时间主要消耗在哪个函数(很可能是图像金字塔构建或雅可比矩阵计算)。 - 算法对比:在同一个数据集上,运行LSD-SLAM和ORB-SLAM2(也需要在Ubuntu 18.04上部署),对比它们的轨迹精度、地图效果和运行速度。
- 尝试改进:例如,尝试将原始的梯度点选取策略改为基于FAST或Shi-Tomasi角点,看看能否在保持直接法优势的同时提升跟踪鲁棒性。
最后一个小技巧:建议你将整个成功编译的环境(包括修改后的源码、安装的依赖)通过Dockerfile或虚拟机快照保存下来。LSD-SLAM这样的研究工具,我们可能不会频繁使用,但当下次需要复现实验或进行对比时,一个现成的、可工作的环境能节省大量时间。毕竟,在软件世界里,“它能工作”本身就是一种宝贵的状态。