视觉SLAM理论到实践系列(一)——SLAM概述与预备知识

视觉SLAM理论到实践系列

视觉SLAM理论到实践系列(一)——SLAM概述与预备知识

视觉SLAM理论到实践系列(二)——三维物体的刚体运动(1)

视觉SLAM理论到实践系列(二)——三维物体的刚体运动(2)

下面是《视觉SLAM十四讲》学习笔记的系列记录的总链接,本人发表这个系列的文章链接均收录于此

视觉SLAM理论到实践系列文章链接


下面是专栏地址:

视觉SLAM理论到实践专栏



前言

高翔博士的《视觉SLAM14讲》学习笔记的系列记录


视觉SLAM理论到实践系列(一)——SLAM概述与预备知识

SLAM是什么

自主运动的两大基本问题

  • 我在什么地方?——定位

  • 周围环境是什么样子?——建图

  • 定位与建图=内外兼修 定位侧重对自身的了解,建图侧重对外在的了解

相互关联

  • 准确的定位需要精确的地图

  • 精确的地图来自准确的定位

请添加图片描述

传感器

  • 机器人感知外界环境的手段

  • 种类:内质的/外质的

    • 内质:感受机器人本体信息
    • IMU、激光、相机
    • 外质:安装于环境中的
    • 二维码Marker、GPS、导轨、

在这里插入图片描述

环境限制了传感器的形式

  • GPS:需要能接收到卫星信号的环境

  • Marker、导轨:需要环境允许安装

相比之下,激光、相机等携带式传感器更加自由

相机

  • 以一定速率采集图像、形成视频

分类

  • 单目相机 Monocular

  • 双目相机(立体相机) Stereo

  • 深度相机 RGB-D

  • 其他 全景、Event Camera

在这里插入图片描述

相机的特点

  • 以二维投影形式记录了三维世界的信息

  • 该过程丢掉了一个维度:距离

各类相机的区别

  • 单目:无深度 深度需要其他手段估计

在这里插入图片描述

  • 双目:通过视差计算深度

在这里插入图片描述

  • RGB-D:通过物理方法测量深度
    在这里插入图片描述

当相机运动时,可通过视差确定深度

深度即第三维信息,对SLAM来说至关重要

视觉SLAM框架

  • 前端:Visual Odometry

  • 后端:Optimization

  • 回环:Loop Closing

  • 建图:Mapping

在这里插入图片描述

视觉里程计
  • 估计邻近时刻的相机运动

  • 最简化:两个图像的相对运动

在这里插入图片描述

方法

  • 特征点法

  • 直接法

后端
  • 从带有噪声的数据中估计最优轨迹与地图

  • 最大后验概率估计

  • 滤波器

  • 图优化

在这里插入图片描述

回环检测
  • 检测相机是否到达过之前位置

  • 判断与之前位置的差异

  • 计算图像间相似性

  • 词袋模型

在这里插入图片描述

建图
  • 导航、规划、通讯、交互、可视化

  • 度量地图、拓扑地图

  • 稀疏地图、稠密地图

在这里插入图片描述

SLAM问题的数学描述

SLAM问题的数学描述:

在这里插入图片描述

问题:

  • 位置是三维的,如何表述?——第2、3次课
  • 观测模型如何表述?——第4次课
  • 已知u,z时,如何推断x,y?——第5次课以后

实践:Linux下的C++基础

第一章习题

熟悉 Linux (2 分,约 2 小时)

计算机领域的绝⼤多数科研⼈员都在 Linux 下⼯作,不掌握 Linux 会使你在研究道路上寸步难行。

Linux 系统的基本知识亦是学习本课程的先决条件。如果你还未接触过 Linux,请阅读本次习题中提供的

材料(见 books/⽬录下)。我建议阅读《鸟哥的 Linux 私房菜》第 1、2 章了解 Linux 历史,第 5-8 章了解

基础操作。如果你在⽤ Ubuntu,也可以参考 Ubuntu 维基上⾃带的指南:http://wiki.ubuntu.org.cn/Ubuntu

不要把 Linux 想得太困难。现代的 Linux 系统多数具有方便的图形界面,⼗分容易上⼿。最好的学习方式可能是马上安装⼀个 Linux 然后熟悉它的操作界⾯,多数时候和 Windows/mac 差别不⼤。我们在本
书中使⽤ Ubuntu 16.04,读者也可以按个⼈⼜味选择任意适合你的发⾏版,不过最好使⽤ Ubuntu 系列,
这样我和你的操作⽅式会⽐较相似。
等你熟悉 Linux 后,请回答以下问题(如果你已经很熟悉,就跳过上⾯的阅读内容,直接回答即可):

  1. 如何在 Ubuntu 中安装软件(命令⾏界⾯)?它们通常被安装在什么地⽅?
  2. linux 的环境变量是什么?我如何定义新的环境变量?
  3. linux 根⽬录下⾯的⽬录结构是什么样的?⾄少说出 3 个⽬录的⽤途。
  4. 假设我要给 a.sh 加上可执⾏权限,该输⼊什么命令?
  5. 假设我要将 a.sh ⽂件的所有者改成 xiang:xiang,该输⼊什么命令?
解答

(1)安装软件

sudo apt install xxx
# 或者
sudo apt-get install xxx

下载的软件存放位置

/var/cache/apt/archives

安装后软件默认位置

/usr/share

可执行文件位置,不像window一个软件一般都在一个文件夹里,ubuntu 的一个软件一般分开在多个目录,可供终端调用的执行文件一般在 /bin 目录,而且往往是在/usr/bin/目录下

/usr/bin

配置文件位置

/etc

lib文件位置

/usr/lib

(2)linux 的环境变量

参考:环境变量解释以及在Linux下的环境变量设置

在Linux系统,如果你下载并安装应用程序,很有可能在键入它的名称的时候出现 “command not found ” 的提示内容。 如果每次都到安装目录文件夹内,找到可执行文件来进行操作就太繁琐了, 这就需要设置path环境变量了。

Shell定义的环境变量

Shell在开始执行的时候就已经定义了一些与系统工作环境有关的变量,用户还可以重新定义这些变量。常用的shell环境变量有以下几种。

  • HOME:用于保存用户主目录的完全路径名。
  • PATH:用于保存用冒号分隔的目录路径名,shell将按PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。
  • SHELL:当前用户使用的Shell
  • UID:当前用户的UID
  • LOGNAME:当前用户的登录名
  • HOSTNAME:主机名称

上面的环境变量使用下面的命令查看

echo $环境变量名

# 如
echo $HOME
# 或者
echo ${HOME}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

查看环境变量
Linux中set 、env 和 export 都可以查看环境变量。

  • set<命令显示当前shell的变量,包括当前用户的变量,set主要用来设置sh的参数与选项

    在这里插入图片描述

  • env命令显示当前用户的变量,env用来在构建的环境中运行命令

    在这里插入图片描述

  • export命令显示当前导出成用户变量的shell变量

    用 export 命令举例来查看PATH值:

    在这里插入图片描述

export不加参数的时候,显示哪些变量被导出成了用户变量,因为一个shell自己的变量可以通过 export “导出”变成一个用户变量。

Linux下环境变量的设置

如果想将一个路径加入到 $PATH 中,可以有几种方法。比如我想将 /tmp/test 路径加入到 $PATH 变量中:

三种方法

(1)控制台中设置 (只对当前shell有效)

执行命令:

export PATH=$PATH:/tmp/test

(2)修改当前家目录下的 .bashrc 文件 (只对当前用户有效)

先执行 vim ~/.bashrc 命令,在最末尾加入下面内容,然后 source ~/.bashrc,使配置文件生效。

vim ~/.bashrc
# 在最后一行添加
export PATH=$PATH:/tmp/test
# 退出后执行命令
source ~/.bashrc

(3)修改/etc/bashrc 文件 (针对所有用户有效)

先执行 sudo vim /etc/profile 命令,在最末尾加入下面内容,然后 source /etc/profile,使配置文件生效。

sudo vim /etc/profile
# 在最后一行添加
export PATH=$PATH:/tmp/test
# 退出后执行命令
source /etc/profile

注:source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。

(3)根目录结构

进入根目录,查看根目录下的文件和文件夹

cd /
ll -h

在这里插入图片描述

用途如下:

/bin:系统命令目录

/sbin:超级命令目录,只能超级管理员可以执行的命令

/boot:系统目录,类似于Windows中的C盘

/dev :设备文件目录,硬盘、光驱、U盘都属于设备文件,/dev/sr0代表光驱设备。注意,次目录下的文件没有办法直接使用,必须先挂载

/etc :非常重要,代表系统的配置文件目录。大部分软件安装完成后,其配置文件都存放在此目录

/home:普通用户的家目录,用户登录后会自动切换到此目录

/root:超级管理员的家目录,超级管理员登录后会自动切换到此目录

/media:挂载目录,早期Linux挂载目录,用于挂载光盘以及软盘

/mnt:挂载目录,用来挂载额外的设备,如 U 盘、移动硬盘和其他操作系统的分区

/opt :第三方软件目录,这个目录是放置和安装其他软件的位置,手工安装的源码包软件都可以安装到这个目录中。不过笔者还是习惯把软件放到 /usr/local/ 目录中,也就是说,/usr/local/ 目录也可以用来安装软件

/usr :系统程序目录,类似Windows中的Program Files

/proc:虚拟文件系统。该目录中的数据并不保存在硬盘上,而是保存到内存中。主要保存系统的内核、进程、外部设备状态和网络状态等。

/tmp :临时文件目录,在该目录下,所有用户都可以访问和写入。建议此目录中不能保存重要数据,最好每次开机都把该目录清理

/var :经常变化的文件目录,网页文件、数据文件、日志文件

(4)添加可执行权限

如果只添加当前用户的可执行权限,则使用命令

chmod +x a.sh
#或者
chmod u+x a.sh

在这里插入图片描述

若要添加属组的可执行权限,则使用命令

chmod g+x a.sh

若要添加其他用户的可执行权限,则使用命令

chmod o+x a.sh

也可以使用命令给所有用户都添加权限

chmod 777 a.sh

(5)改变所有者

先添加用户xiang

sudo useradd xiang

使用命令改变所有者

chown xiang:xiang a.sh

在这里插入图片描述

SLAM 综述文献阅读 (3 分,约 3 小时)

当你对某个研究领域不了解时,最好是从综述⽂献开始了解这个领域的整体⾯貌。SLAM 作为⼀个近

30 年的研究领域,⾄今也存在着⼤量的综述、总结类的⽂章。请阅读本次作业 paper/⽬录下的⽂章 [1–3]

(其中 [3] 是中文文献),了解这个领域的⼤致情况。如果你的时间有限,可以仅阅读每篇⽂章的第⼀章(也

就是引言⼀章),然后回答下列问题:

  1. SLAM 会在哪些场合中⽤到?⾄少列举三个⽅向。

  2. SLAM 中定位与建图是什么关系?为什么在定位的同时需要建图?

  3. SLAM 发展历史如何?我们可以将它划分成哪⼏个阶段?

  4. 列举三篇在 SLAM 领域的经典⽂献

解答

(1)

CMake 练习 (2 分,约 1.5 小时)

cmake 是⼀种常⽤、⽅便的,⽤于组织 Linux 下 C++ 程序的⼯具。有许多库,例如 OpenCV、g2o、

Ceres 等,都用 cmake 组织它们的工程。所以,不管是使用别人的库,还是编写自己的库,都需要掌握

⼀些 cmake 的基本知识。也许你之前没有听过这个工具,但不要紧,我们准备了阅读材料“books/CmakePractice.pdf”(cmake 实践,由⼀位北大同学撰写)。请阅读此文的第 1 至 6 章,并完成以下工作:

书写⼀个由 cmake 组织的 C++ 工程,要求如下:

  1. include/hello.h 和 src/hello.c 构成了 libhello.so 库。hello.c 中提供⼀个函数 sayHello(),调⽤此函数时往屏幕输出⼀行“Hello SLAM”。我们已经为你准备了 hello.h 和 hello.c 这两个文件,见“code/”目录下。

  2. ⽂件 useHello.c 中含有⼀个 main 函数,它可以编译成⼀个可执行文件,名为“sayhello”。

  3. 默认用 Release 模式编译这个⼯程。

  4. 如果用户使用 sudo make install,那么将 hello.h 放至/usr/local/include/下,将 libhello.so 放至/usr/local/lib/下。

请按照上述要求组织源代码文件,并书写 CMakeLists.txt。

解答

(1)先编译动态库,文件结构如下图所示

在这里插入图片描述

建立src文件夹,将hello.c文件更改后缀为hello.cpp并移入src文件夹内

建立include文件夹,将hello.h文件移入

在根目录下建立CMakeLists.txt文件,其中内容为

# 指定CMAKE版本
cmake_minimum_required(VERSION 3.0)
# 指定工程名
project(test)
# 指定头文件的路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 指定cpp文件的路径
file(GLOB SRC ${PROJECT_SOURCE_DIR}/src/*.cpp)
# 设置库文件的输出路径
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib_shared)
# 添加动态库文件
add_library(hello SHARED ${SRC})

写好CMakeLists.txt文件后,建立build文件夹并进入,输入命令

mkdir build
cd build
cmake ..
make

在这里插入图片描述

即可完成动态库的编译,且libhello.so文件被输出到lib_shared文件夹中

(2)编译可执行文件

由于编译的原因,要将useHello.c后缀改为useHello.cpp,才能顺利编译,否则会出现如下报错

在这里插入图片描述

编写CMakeLists.txt文件如下所示

在这里插入图片描述

# 指定CMAKE版本
cmake_minimum_required(VERSION 3.0)
# 指定工程名
project(test)
# 指定编译模式为Release
SET(CMAKE_BUILD_TYPE "Release")
# 指定头文件的路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 指定动态库的位置
link_directories(${PROJECT_SOURCE_DIR}/lib_shared)
# 指定输出路径,不设置的话默认输出到build文件夹中
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_executable(sayhello useHello.cpp)
target_link_libraries(sayhello hello)

这里的默认编译模式设置为Release模式

编写好CMakeLists.txt文件后,进行编译

编译完成后进入bin目录,执行sayhello文件

在这里插入图片描述

或者直接使用如下的方法,即嵌套式的CMakeLists.txt

最开始的文件结构如下所示

.
├── bin
│   ├── CMakeLists.txt
├── build
├── CMakeLists.txt
├── include
│   └── hello.h
├── lib
├── src
│   ├── CMakeLists.txt
│   └── hello.cpp
└── useHello.cpp

其中src目录下为源文件,include下为头文件,useHello.cpp为主函数所在的文件,lib文件夹用来装编译好的库文件,bin文件夹用来装编译好的二进制执行文件

根目录下的CMakeLists.txt

# 指定CMAKE版本
cmake_minimum_required(VERSION 3.0)
# 指定工程名
project(hello)
# 指定编译的模式
IF(NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE Release)
ENDIF()
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
# 定义路径的变量
set(LIB_PATH ${PROJECT_SOURCE_DIR}/lib)
set(HEAD_PATH ${PROJECT_SOURCE_DIR}/include)
set(EXEC_PATH ${PROJECT_SOURCE_DIR}/bin)
# 定义库名称
set(HELLO_LIB hello)
# 添加子目录
add_subdirectory(src)
add_subdirectory(bin)	# 注意后编译的文件夹写在后面
# 或者写成add_subdirectory(src bin)

src目录下的CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(HELLOLIB)
# 指定源文件路径
file(GLOB SRC_LIST ./*.cpp)
# 头文件路径
include_directories(${HEAD_PATH})
# 库文件的输出路径
set(LIBRARY_OUTPUT_PATH ${LIB_PATH})
# 生成共享库
add_library(${HELLO_LIB} SHARED ${SRC_LIST})
SET_TARGET_PROPERTIES(${HELLO_LIB} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
# 生成静态库
add_library(${HELLO_LIB}_static STATIC ${SRC_LIST})
SET_TARGET_PROPERTIES(${HELLO_LIB}_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)

bin目录下路的CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
# 定义工程名
project(HELLOBIN)
# 头文件路径
include_directories(${HEAD_PATH})
# 链接的库文件路径
link_directories(${LIB_PATH})
# 二进制文件输出路径
set(EXECUTABLE_OUTPUT_PATH ${EXEC_PATH})
# 生成二进制文件
add_executable(sayhello ../useHello.cpp)
# 链接动态库
target_link_libraries(sayhello hello)

然后进入build文件夹进行编译

cd build
cmake ..
make

最终的文件结构如下所示

.
├── bin
│   ├── CMakeLists.txt
│   └── sayhello
├── build
├── CMakeLists.txt
├── include
│   └── hello.h
├── lib
│   ├── libhello.so
│   └── libhello_static.a
├── src
│   ├── CMakeLists.txt
│   └── hello.cpp
└── useHello.cpp

5 directories, 9 files

(3)如果⽤户使⽤ sudo make install,那么将 hello.h 放⾄/usr/local/include/下,将 libhello.so fang放至/usr/local/lib/下。

使用sudo make install

在这里插入图片描述

这里主目录的CMakeLists.txt如下所示

# 指定CMAKE版本
cmake_minimum_required(VERSION 3.0)
# 指定工程名
project(hello)
# 指定编译的模式
IF(NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE Release)
ENDIF()
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})


# 定义路径的变量
set(LIB_PATH ${PROJECT_SOURCE_DIR}/lib)
set(HEAD_PATH ${PROJECT_SOURCE_DIR}/include)
set(EXEC_PATH ${PROJECT_SOURCE_DIR}/bin)
# 定义库名称
set(HELLO_LIB hello)
# 添加子目录
add_subdirectory(src)
add_subdirectory(bin)	# 注意后编译的文件夹写在后面

# 设定安装路径
set(CMAKE_INSTALL_PREFIX /usr/local)
# 动态库文件输出到 ${CMAKE_INSTALL_PREFIX}/lib 即 /usr/local/lib 目录下
INSTALL(TARGETS hello LIBRARY 
    DESTINATION lib
)
# 头文件输出到 ${CMAKE_INSTALL_PREFIX}/include 即 /usr/local/include 目录下
INSTALL(DIRECTORY include/ 
    DESTINATION include
)

在这里插入图片描述
在这里插入图片描述

出现报错
fatal error: iostream: No such file or directory
    2 | #include <iostream>

在这里插入图片描述

原因在于iostream是cpp的库,把文件名改为cpp结尾即可

在这里插入图片描述

理解 ORB-SLAM2 框架 (3 分,约 2 小时)

ORB-SLAM2[4] 是⼀个⾮常经典的视觉 SLAM 开源方案,它可以作为你学习 SLAM 的范本。但是现在我们还没有讲解很多关于视觉 SLAM 的知识,所以仅从代码工程角度上来了解 ORB-SLAM2。请按照提示完成以下工作。

  1. 从 github.com 下载 ORB-SLAM2 的代码。地址在:https://github.com/raulmur/ORB_SLAM2.

提示:在安装 git 之后,可以⽤ git clone https://github.com/raulmur/ORB_SLAM2 命令下载ORB-SLAM2。下载完成后,请给出终端截图。

  1. 此时我们不着急直接运⾏ ORB-SLAM2,让我们⾸先来看它的代码结构。ORB-SLAM2 是⼀个cmake ⼯程,所以可以从 CMakeLists.txt 上⾯来了解它的组织⽅式。阅读 ORB-SLAM2 代码⽬录下的 CMakeLists.txt,回答问题:

    (a) ORB-SLAM2 将编译出什么结果?有几个库文件和可执行文件?

    (b) ORB-SLAM2 中的 include, src, Examples 三个文件夹中都含有什么内容?

    (c) ORB-SLAM2 中的可执行文件链接到了哪些库?它们的名字是什么?

    你会发现 ORB-SLAM2 从代码组织方式来看并不复杂。实际上⼤部分中⼩型库都不会很复杂,而更大的库可能在 CMakeLists.txt 中有各种各样的兼容性检查,确保它们在各个平台上都能顺利运行。

现在你已经了解了 ORB-SLAM2 的代码结构了。抛开代码内容来说,至少你已经知道如何编译,使用这个库了。ORB-SLAM2 可以在数据集上运行,也可以在实际的摄像头上运行。下面的作业将指导你用自己的笔记本摄像头来运行 ORB-SLAM2。

解答

(1)下载完成后如下所示

在这里插入图片描述

(2)

(a)编译输出一个动态库文件libORB_SLAM2.so,其中包含了如下所示的源文件

src/System.cc
src/Tracking.cc
src/LocalMapping.cc
src/LoopClosing.cc
src/ORBextractor.cc
src/ORBmatcher.cc
src/FrameDrawer.cc
src/Converter.cc
src/MapPoint.cc
src/KeyFrame.cc
src/Map.cc
src/MapDrawer.cc
src/Optimizer.cc
src/PnPsolver.cc
src/Frame.cc
src/KeyFrameDatabase.cc
src/Sim3Solver.cc
src/Initializer.cc
src/Viewer.cc

还输出了一些示例的可执行文件

  • rgbd_tum,其位于Examples/RGB-D,其由Examples/RGB-D/rgbd_tum.cc编译而来

  • stereo_kitti,其位于/Examples/Stereo文件夹中,由Examples/Stereo/stereo_kitti.cc编译得来

  • tereo_euroc,由Examples/Stereo/stereo_euroc.cc编译得来

  • mono_tum,其位于/Examples/Monocular文件夹中,由/Examples/Monocular/mono_tum.cc编译得来

  • mono_kitti,由Examples/Monocular/mono_kitti.cc编译得来

  • mono_euroc,由Examples/Monocular/mono_euroc.cc编译得来

(b)Include文件夹中包含了头文件的源文件

src中包含了各种库文件的源文件

Examples文件夹中包含了示例文件的主函数文件,可以被编译成可执行文件

(c)链接到的库名如下所示

libORB_SLAM2.so
OpenCV_LIBS
EIGEN3_LIBS
Pangolin_LIBRARIES
libDBoW2.so
libg2o.so

* 使用摄像头或视频运行 ORB-SLAM2(3 分,约 1 小时)

请注意本题为附加题。

了解⼀样东西最快的⽅式是自己上手使用它,不要担心弄坏你的笔记本,⼤部分时候它都是你可靠的伙伴。这个作业中,我将指导你用自己的笔记本摄像头读取到的图像,来运行 ORB-SLAM2,看看它能不能实际工作。你也可以外接⼀个 usb 摄像头,这会让你的手更加灵活⼀些(不用费力端着笔记本到处跑)。或者,如果你的电脑碰巧没有摄像头/摄像头故障了/你正在用虚拟机,那我们也可以在事先录制好的⼀段视频中运行ORB-SLAM2(见 code/myvideo.mp4,这是我在特蕾西亚草坪散步的时候用手机拍摄的小视频)。

由于我们还没有讲过任何关于 OpenCV 或者图像⽅⾯的问题,所以本节我给你写好了⼀个 myslam.cpp文件(如果你使用录制视频,请⽤ myvideo.cpp)。这个文件会打开你自带的摄像头(或视频),读取图像,并交给 ORB-SLAM2 处理。由于你现在已经了解 cmake 原理了,所以我要请你自己来思考如何将这个文件与 ORB-SLAM2 结合起来。相信我,这件事并不难。myslam.cpp 和 myvideo.cpp ⽂件见本次作业的code/文件夹下。

下面是本题的提示:

  1. 为了实际运⾏ ORB-SLAM2,你需要安装它的依赖项,并通过它本⾝的编译。它的依赖项见它⾃⼰的 github 主页,请按照主页上的提⽰安装好 ORB-SLAM2 的依赖项。具体来说,对于 pangolin(⼀个 GUI 库),你需要下载并安装它,它同样是个 cmake ⼯程,所以我不必谈怎么编译安装的细节了。对于 opencv 和 eigen3,你可以简单的用一行命令来解决:
sudo apt-get install libopencv-dev libeigen3-dev libqt4-dev qt4-qmake libqglviewer-dev libsuitesparse-dev

libcxsparse3.1.2 libcholmod-dev

其中⼀部分是 g2o 的依赖项,现阶段不用太在意它的具体内容。至此,你应该可以顺利编译 ORB-SLAM2 了,请给出它编译完成的截图。

  1. 注意到,ORB-SLAM2 提供了若⼲数据集中的运行示例,这可以作为我们运行自己摄像头程序的参考,因为它们很相似。对于数据集上的示例,ORB-SLAM2 会⾸先读取数据集中的图像,再放到SLAM 中处理。那么对于我们⾃⼰的摄像头,同样可以这样处理。所以最⽅便的⽅案是直接将我们的程序作为⼀个新的可执⾏程序,加⼊到 ORB-SLAM2 ⼯程中。那么请问,如何将 myslam.cpp或myvideo.cpp 加⼊到 ORB-SLAM2 ⼯程中?请给出你的 CMakeLists.txt 修改⽅案。

  2. 现在你的程序应该可以编译出结果了。但是我们现在还没有谈相机标定,所以你还没办法标定你的摄像头。但没有关系,我们也可以⽤⼀个不那么好的标定参数,先来试⼀试效果(所幸 ORB-SLAM2对标定参数不太敏感)。我为你提供了一个myslam.yaml(myvideo.yaml),这个文件是我们假想的标定参数。现在,用这个文件让 ORB-SLAM2 运行起来,看看 ORB-SLAM2 的实际效果吧。请给出运行截图,并谈谈你在运行过程中的体会。

注意,本题只需你能运行 ORB-SLAM2 即可,并不是说“成功地运行SLAM”。要顺利运行 SLAM 还需要⼀些经验和技巧,希望你能在动手过程中有所体会。作为建议,请尽量在光照充足、纹理丰富的场合下运行程序。如果默认参数不合适,你也可以尝试换⼀换参数。

解答

(1)ORB-SLAM2编译完成如下所示

在这里插入图片描述

(2)在CMakeLists.txt中加入如下所示的代码

# Build gx examples
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/gx)
add_executable(myvideo gx/myvideo.cpp)
target_link_libraries(myvideo ${PROJECT_NAME})

在这里插入图片描述

加入后编译如下所示

在这里插入图片描述

编译完成

在这里插入图片描述

(3)运行生成的二进制文件myvideo

在这里插入图片描述

运行结果如下所示
在这里插入图片描述

在这里插入图片描述

这里的源码中需要修改一下ORBvoc.txt的路径

string vocFile = "./Vocabulary/ORBvoc.txt";
// 修改为
string vocFile = "../Vocabulary/ORBvoc.txt";

运行过程中出现的红点即为检测到的目标点,

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值