0 背景简介
ORB-SLAM是西班牙Zaragoza大学的Raul Mur-Artal编写的视觉SLAM系统。他的论文“ORB-SLAM: a versatile andaccurate monocular SLAM system”发表在2015年的IEEE Trans. on Robotics上。开源代码包括前期的ORB-SLAM和后期的ORB-SLAM2。第一个版本主要用于单目SLAM,而第二个版本支持单目、双目和RGBD三种接口。
特点
ORB-SLAM是一个完整的SLAM系统,包括视觉里程计、跟踪、回环检测。它是一种完全基于稀疏特征点的单目SLAM系统,其核心是使用ORB(Orinted FAST and BRIEF)作为整个视觉SLAM中的核心特征。具体体现在几个方面:
提取和跟踪的特征点使用ORB。ORB特征的提取过程非常快,适合用于实时性强的系统。
回环检测使用词袋模型,其字典是一个大型的ORB字典。
接口丰富,支持单目、双目、RGBD多种传感器输入,编译时ROS可选,使得其应用十分轻便。代价是为了支持各种接 口,代码逻辑稍为复杂。
在PC机以30ms/帧的速度进行实时计算,但在嵌入式平台上表现不佳。
原理
ORB-SLAM整体流程如下图所示。
它主要有三个线程组成:跟踪、Local Mapping(又称小图)、Loop Closing(又称大图)。
跟踪
跟踪线程相当于一个视觉里程计,流程如下:
首先,对原始图像提取ORB特征并计算描述子。
根据特征描述,在图像间进行特征匹配。
根据匹配特征点估计相机运动。
根据关键帧判别准则,判断当前帧是否为关键帧。
相比于多数视觉SLAM中利用帧间运动大小来取关键帧的做法,ORB_SLAM的关键帧判别准则较为复杂。
1 实验目的
(1)配置ORB-SLAM环境并在真实环境运行
(2)了解工程实现的流程和框架
(3)熟悉在Ubuntu和ROS系统下的开发
2 实验环境
2.1 硬件
(1)惠普笔记本电脑,配置如下:
处理器:Intel® Core™ i5-7300HQ CPU @ 2.50GHz × 4
内存:8 GB
(2)传感器为罗技(Logitech)C170 网络摄像头,参数如下:
像素:130万;捕获幅面:1024*768;接口:USB 2.0
2.2 软件
(1)操作系统:Ubuntu 14.04
(2)软件平台:ROS indigo
3 实验步骤
3.1 首先安装必要的依赖
(1)更新apt库,更新软件列表
$ sudo apt-get update
(2)安装git,用于从Github上克隆项目到本地
$ sudo apt-get install git
(3)安装cmake,用于程序的编译
$ sudo apt-get install cmake
(4)安装Pangolin 作为可视化和用户界面
a. 安装依赖项
$ sudo apt-get install libglew-dev libpython2.7-dev
b. 从Github将项目下载到本地
$ git clone https://github.com/stevenlovegrove/Pangolin.git
c. 编译安装
$ cd Pangolin$ mkdir bu ild$ cd build$ cmake ..$ make –j$ sudo make install
(5)安装OpenCV ,用于处理图像和特征
要求版本最低为2.4.3,并在OpenCV 2.4.11和OpenCV 3.2上做了测试。
注意:这里的版本问题非常重要,不同的版本号可能会不兼容,会出现各种错误,只能重新编译,对没有经验的开发者还会花费大量的时间寻找错误和解决问题。
在本次实验中,我首次使用的OpenCV 3.2,但是最后出现了错误,改用OpenCV 2.4.11后成功。
a. 安装依赖项
[compiler]
sudo apt-get install build-essential
[required]
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
[optional]
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
b. 在OpenCV官网(http://opencv.org)下载OpenCV 2.4.11的source版本,然后解压到本地
c. 编译安装
$ cd ~/opencv$ mkdir build$ cd build$ cmake -D CMAKE_BUILD_TYPE=Release –D CMAKE_INSTALL_PREFIX=/usr/local ..$ make –j8$ sudo make install
编译过程会花费较长时间,电脑CPU性能较低的建议不要使用make -j
,容易卡死;CPU性能较高的可以使用make -jx
,x代表线程,可加速编译。
(6)安装Eigen3,它是一个开源线性库,可进行矩阵运算
$ sudo apt-get install libengen3-dev
(7)安装DBoW2和g2o
DBoW2是DBow库的改进版本,DBow库是一个开源的C++库,用于索引图像并将其转换为单词表示形式。
g2o是一个开源的C ++框架,用于优化基于图的非线性误差函数。
这两个库在ORB-SLAM2项目的第三方文件夹中,在此不单独编译,后续统一编译。
(8)安装ORB-SLAM2
a. 克隆仓库
$ git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2
b. 编译ORB-SLAM2,第三方库中的DBoW2和g2o,并解压ORB词典
$ cd ORB_SLAM2$ chmod +x build.sh$ ./build.sh
3.2 单目例子
有TUM、KITTI、EuRoC三种数据集,本实验使用TUM数据集,从http://vision.in.tum.de/data/datasets/rgbd-dataset/download下载序列并解压缩。
$ ./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/TUMX.yaml PATH_TO_SEQUENCE_FOLDER
其中PATH_TO_SEQUENCE_FOLDER
为数据集的存储路径,并将tumx.yaml
与下载的数据集对应,比如TUM1.yaml,TUM2.yaml 和TUM3.yaml 分别对应 freiburg1, freiburg2 和 freiburg3。
运行效果图如下所示,图中左侧窗口中的蓝色小方块为提取的图像ORB特征,右侧窗口显示了环境的稀疏地图和相机的运动轨迹。
公开数据集可以提供大量的数据,弥补数据的不足,即使没有RGB-D相机,也可以借助公开数据集的数据进行试验,当然工欲善其事必先利其器,不管做科研还是工程,硬件设备都是必须的;此外公开数据集还可作为算法性能对比的评价标准。
3.3 ROS例子
为了能够在线实时地运行ORB-SLAM2,需要借助ROS。关于ROS的安装,官网(http://wiki.ros.org/indigo/Installation/Ubuntu)有详细的安装教程,在此不再赘述。
本实验在上篇博客——摄像头图像信息的读取和显示的基础上进行开发,实现了摄像头数据的读取和显示,采集的图像数据可作为ORB-SLAM2系统的输入。
上篇博客创建了工作空间catkin_ws
,将ORB-SLAM2项目移动到其子文件夹src
下。
(1)将包含Examples/ROS/ORB_SLAM2
的路径添加到ROS_PACKAGE_PATH
环境变量中。打开.bashrc
文件并在最后添加以下行。
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:PATH/ORB_SLAM2/Examples/ROS
其中PATH为ORB-SLAM2项目所在路径,我的路径为/home/wb/catkin_ws/src
。此外,还要在./bashrc
文件写入
source /home/wb/catkin_ws/devel/setup.sh
最后在终端执行命令
source ./bashrc
(2)编译ROS下的ORB-SLAM2
ORB-SLAM默认订阅的话题为/camera/image_raw
,而usb_cam
节点发布的话题为/usb_cam/image_raw
,因此需要在ros_mono.cc
中修改订阅的话题,这点要特别注意。因为源文件的更改必须要重新编译,这非常耗时。
$ chmod +x build_ros.sh$ ./build_ros.sh
(3)运行单目节点
运行单目节点前要先将摄像头接入电脑,然后启动usb_cam
节点。
$ roslaunch usb_cam usb_cam-test.launc$ rosrun ORB_SLAM2 Mono PATH_TO_VOCABULARY PATH_TO_SETTINGS_FILE
4 实验结果
启动单目节点后,首先要进行初始化,将相机左右平移直到图像提取出ORB特征点。然后手持相机在实验室空间中运动,ORB-SLAM2系统会以每秒30帧的速度对输入图像进行ORB特征提取,经过一系列运算,最后输出相机的运动轨迹和周围环境的稀疏地图。
注意
为了能够顺利地进行初始化,必须选择纹理丰富的场景,并使相机有一定的平移。
不能快速移动,最好保持匀速运动,保持当前帧与上一帧有足够数量的匹配的特征点,否则会跟踪失败。
跟踪失败后,应回到之前经过的场景,进行重定位。
电脑性能不能太低,保持电量充足。
我手持相机在实验室自己的工位附近运动了一段时间,最后运行效果图如下所示。
图中左侧窗口中的绿色小方块为提取的图像ORB特征,右侧窗口中的绿线代表相机的运动轨迹,蓝色方框代表相机运动过程中的空间位置(即关键帧),黑点和红点代表环境的稀疏地图(黑色代表历史路标,红色表示当前路标)。
5 总结
到这里,我可以编译运行诸如此类的开源项目了,虽然经历了各种报错的折磨,但是熟悉了Linux系统和ROS系统的操作、cmake、shell、OpenCV等等,为了能够自己进行开发,还需要更深入的学习。
作为初学者,从开源项目入手,学习其理论和工程实现,是入门的捷径,深入之后在其基础上做一定的改进。
然而工程实现只是科研的一部分,作为研究生,更重要的是抓住SLAM中的一个小问题,看看能否对现有的算法进行改进或者比较。所以还是要从论文出发,寻找灵感,去实现,并验证效果。
接下来还要很长的路要走,科研之路才刚刚开始。