小萝卜机器人的例子:

就像这种机器人,它的下面有一组轮子,脑袋上有相机(眼睛),为了让它能够探索一个房间,它需要知道:

1.我在哪——定位

2.周围环境怎么样——建图

定位和建图可以理解成感知的 "内外之分",一方面要明白自身的状态(位置),另一方面要了解周围的环境(地图)。要完成这些工作,我们可以通过在房间铺设导引线,在墙上贴识别二维码,在室外可以给机器人安装定位设备,这些我们都称之为传感器,传感器分为两类:

1.携带于机器人本体上,例如相机,激光传感器等

2.安装于环境中的,例如导引线,识别二维码等。

然而大量利用这些外部传感器很明显是不现实的,抛开成本,光是在环境中铺设这些传感器就很不现实,有些地方不能铺设导轨,有些地方没有信号,相对地, 安装于机器人身上的传感器测到的都是一些间接的物理量,并不能得到直接的位置信息,我们只能通过一些间接的手段,推算出位置。虽然听起来很麻烦,但是它有一个很明显的好处就是对环境条件没有要求,适用于测量未知环境。

SLAM中非常强调未知环境,因此,谈论视觉SLAM时,主要指如何用相机解决定位和构图问题。SLAM中使用的相机是以一定速率拍摄周围的环境,形成一个连续的视频流。普通相机能以每秒钟30张的速度采集图像,按照工作方式不同,可以分为单目相机,双目相机和深度相机。

单目相机:顾名思义,只有一个摄像头,我们通常的照片就是单目摄像机拍摄的图像,以二维的形式反映了三维的世界。显然,这个过程丢掉了深度(距离),比如:

你很难分辨出手掌上的人是真人还是模型。

如果想恢复三维结构,我们必须改变相机的视角,因此必须移动相机,才能估计它的运动,同时估计场景中物体的远近和大小,不妨称之为结构,一方面,我们知道相机往右移动,图像里的东西会向左移动,另一方面,近处的物体移动快,远处的物体运动缓慢。于是,当相机移动时,这些物体在图像上的运动形成了视差。通过视差我们可以判断哪些物体离得远,哪些离得近。

现在我们知道了物体远近,但是它们仍然是相对的值,如果把相机的运动和场景大小同时放大两倍,单目相机看到的图像是一样的。因此,单目SLAM估计的轨迹和地图将与真实的轨迹和地图相差一个因子,也就是尺度。由于单目SLAM无法仅凭图像确定这个真实尺度,所以又称尺度不确定性。

平移之后才可以计算深度,以及无法确定真实尺度,这给单目SLAM的应用带来了很大麻烦。根本原因是通过单张图像无法确定深度

双目相机

由两个单目相机组成,这两个单目相机之间的距离(成为基线)是已知的。通过这个基线来估计每个像素的空间位置——和人眼类似。基线的距离越大,能测量到的就越远。双目相机的距离估计是比较左右眼的图像获得的,并不依赖其他传感设备。因此室内外都可以应用。它的缺点是配置与标定均比较复杂,其深度量程和精度受双目的基线与分辨率所限,而且视差的计算非常消耗计算资源,需要使用 GPU 和 FPGA 设备加速后,才能实时输出整张图像的距离信息,因此计算量是双目的主要问题之一。

深度相机

又称 RGB-D 相机,最大的特点是可以通过红外结构光或 Time-of-Flight(TOF) 原理,像激光传感器那样,通过主动向物体发射光并接收返回的光,测出物体与相机之间的距离。

经典视觉SLAM框架:

整个视觉SLAM流程包括以下步骤。

1.传感器信息读取。在视觉SLAM中主要为相机图像信息的读取和预处理。如果是在机器人中,还可能有码盘、惯性传感器等信息的读取和同步。

2.视觉里程计(Visual Odometry,VO)。视觉里程计的任务是估算相邻图像间相机的运动,以及局部地图的样子。VO又称为前端。

3.后端优化(Optimization)。后端接受不同时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化,得到全局一致的轨迹和地图,由于接在VO之后,又称后端。

4.回环检测(Loop Closing)。判断机器人是否到达过先前的位置。如果检测到回环,它会把信息提供给后端进行处理。

5.建图(Mapping)。根据估计的轨迹,建立与任务要求对应的地图。

关于SLAM问题的数学表述,在后续的博文中会提到。

小试牛刀:

1.安装Linux系统,这个不用多说。

2.编写helloSLAm.cpp。首先建一个文件夹。

$mkdir slambook
$cd slambook
$mkdir ch2
 

然后在ch2下写helloSLAM.cpp。

$cd ch2
$vim helloSLAM.cpp
 

将如下代码写入。

#include <iostream>

using namespace std;

int main(int argc,char** argv)
{
cout<<"Hello SLAM"<<endl;
return ;
}
 

先使用g++编译。

$g++ helloSLAM.cpp
 

确保你的机器里有g++。如果没有,请使用以下命令安装。

$sudo apt-get install g++
 

编译成功后,输入:

$./a.out
 

即可运行。

我们可以发现,g++默认把源文件编译成 a.out 。

3.使用cmake

在刚才的目录下新建一个 CMakeLists.txt 文件,输入:

#声明要求的 cmake 最低版本
cmake_minimum_required( VERSION 2.8 ) #声明一个cmake工程
project( HelloSLAM ) #添加一个可执行程序
#语法:add_executable(程序名 源代码文件)
add_executable( helloSLAM helloSLAM.cpp )
 

在当前目录下(slambook/ch2),调用 cmake 对该工程分析:

用 make 对工程进行编译:

$make
 

然后运行:

$./helloSLAM
 

cmake 和 g++都可以对C++文件进行编译,那么它们之间的区别是什么?

通常一个小型C++项目可能含有十几个类,各类之间还存在着复杂的依赖关系。其中一部分要编译成可执行文件,另一部分要编译成库文件。如果仅靠g++命令,需要输入大量的编译指令,整个编译过程会非常繁琐。因此对于C++项目,使用一些工程管理工具会更加高效。也就是cmake。

4.使用库

创建如下文件(slambook/ch2/libHelloSLAM.cpp):

#include <iostream>

using namespace std;

void printHello()
{
cout<<"Hello SLAM"<<endl;
}

这个库提供了一个printHello()函数,调用此函数将打印出一条信息,但是没有main()函数,意味着这个库中没有可执行文件,我们在CMakeLists.txt里加上如下内容:

add_library( hello libHelloSLAM.cpp)
 

这条命令告诉cmake,我们想把这个文件编译成一个叫做“hello”的库,然后和上面一样,编译整个工程:

$cd build
$cmake ..
$make
 

这时,在build文件夹中就会生成一个libhello.a文件,这就是得到的库,

Linux中,库分为静态库和共享库,静态库以.a作为后缀名,共享库以.so结尾,所有库都是一些函数打包后的集合,差别在于静态库每次被调用都会生成一个副本,而共享库只有一个副本,更省空间。如果想生成共享库,那么只需要:

add_library( hello_shared SHARED libHelloSLAM.cpp)
 

此时得到的就是libhello_shared.so了。

为了让别人使用这个库,我们需要提供一个头文件,说明这些库里面都有些什么,因此,对于库的使用者,只要拿到了头文件和库文件,就可以调用这个库了,下面编写libhello的头文件。

slambook/ch2/libHelloSLAM.h

#ifndef LIBHELLOSLAM_H_
#define LIBHELLOSLAM_H_
void printHello();
#endif
 

根据这个文件和我们刚才编译得到的库文件,就可以使用printHello()函数了,下面写一个可执行程序来调用这个简单的函数:

slambook/ch2/useHello.cpp

#include "libHelloSLAM.h"

int main(int argc,char** argv)
{
printHello();
return ;
}

然后,在CMakeLists.txt中添加一个可执行程序的生成命令,链接到刚才使用的库上:

add_executable( useHello useHello.cpp )
target_link_libraries( useHello hello_shared)
 

5.使用IDE

关于kdevelop的安装教程请看:

http://blog.csdn.net/p942005405/article/details/75715288

《视觉SLAM十四讲》学习日志(二)——初识SLAM的更多相关文章

  1. 《SLAM十四讲》个人学习知识点梳理

    0.引言 从六月末到八月初大概一个月时间一直在啃SLAM十四讲[1]这本书,这本书把SLAM中涉及的基本知识点都涵盖了,所以在这里做一个复习,对这本书自己学到的东西做一个梳理. 书本地址:http:/ ...

  2. 高博-《视觉SLAM十四讲》

    0 讲座 (1)SLAM定义 对比雷达传感器和视觉传感器的优缺点(主要介绍视觉SLAM) 单目:不知道尺度信息 双目:知道尺度信息,但测量范围根据预定的基线相关 RGBD:知道深度信息,但是深度信息对 ...

  3. 《视觉SLAM十四讲》第2讲

    目录 一 视觉SLAM中的传感器 二 经典视觉SLAM框架 三 SLAM问题的数学表述 注:原创不易,转载请务必注明原作者和出处,感谢支持! 本讲主要内容: (1) 视觉SLAM中的传感器 (2) 经 ...

  4. 《视觉SLAM十四讲》第1讲

    目录 一 视觉SLAM 注:原创不易,转载请务必注明原作者和出处,感谢支持! 一 视觉SLAM 什么是视觉SLAM? SLAM是Simultaneous Localization and Mappin ...

  5. 视觉slam十四讲第七章课后习题6

    版权声明:本文为博主原创文章,转载请注明出处: http://www.cnblogs.com/newneul/p/8545450.html 6.在PnP优化中,将第一个相机的观测也考虑进来,程序应如何 ...

  6. 视觉slam十四讲第七章课后习题7

    版权声明:本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/newneul/p/8544369.html  7.题目要求:在ICP程序中,将空间点也作为优化变量考虑进来 ...

  7. 浅读《视觉SLAM十四讲:从理论到实践》--操作1--初识SLAM

    下载<视觉SLAM十四讲:从理论到实践>源码:https://github.com/gaoxiang12/slambook 第二讲:初识SLAM 2.4.2 Hello SLAM(书本P2 ...

  8. 视觉SLAM十四讲:从理论到实践 两版 PDF和源码

    视觉SLAM十四讲:从理论到实践 第一版电子版PDF 链接:https://pan.baidu.com/s/1SuuSpavo_fj7xqTYtgHBfw提取码:lr4t 源码github链接:htt ...

  9. SLAM十四讲中Sophus库安装

    Sophus截止目前有很多版本,其中大体分为两类,一种是用模板实现的方法,一种是用非模板类实现的,SLAM十四讲中使用的是非模板类库,clone Sophus: git clone http://gi ...

随机推荐

  1. 时间格式_java

    @Test public void testDate(){ Date date=new Date(); System.out.println(date); /*日期格式*/ DateFormat df ...

  2. Spring基础篇——DI/IOC和AOP原理初识

    DI(Dependency Injection),依赖注入,和我们常听说的另一个概念 IOC(控制反转)其实归根结底实现的功能是相同的,只是同样的功能站在不同的角度来阐述罢了.这里博主就不去过多的辨析 ...

  3. internal关键字

    internal修饰符可以用于类型或成员,使用该修饰符声明的类型或成员只能在同一程集内访问,接口的成员不能使用internal修饰符. 就是使用internal的类只能在同一个项目中使用,不能在别的项 ...

  4. .NetCore如何使用ImageSharp进行图片的生成

    ImageSharp是对NetCore平台扩展的一个图像处理方案,以往网上的案例多以生成文字及画出简单图形.验证码等方式进行探讨和实践. 今天我分享一下所在公司项目的实际应用案例,导出微信二维码图片, ...

  5. ARM微控制器与嵌入式系统

    个牛人在ARM实现嵌入式系统的过程 第一章  概览 1.1课程概览 认识ARM嵌入式系统(什么是ARM?什么是嵌入式系统?) 备战智能车 在科技活动中玩起来 积累计算机.电路基础知识 1.2如何学好嵌 ...

  6. 2、Java基础:概念

    1.面向对象和面向过程的区别 面向过程 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机.嵌入式开发.Linux/Unix等一般采用面向过程开发,性能是最重要的因素 ...

  7. vscode 使用ESLint 自动检查,保存时自动格式化

    1:全局安装eslint `npm install -g eslint`2: 打开vscode 点击 “文件”----->“首选项”---->“设置”,在右侧“用户设置/settings. ...

  8. KVM之配置桥接网卡

    配置桥接网卡 添加桥接网卡br0,注释掉已有的eth0配置 [root@ubuntu01 ~]# vi /etc/network/interfaces # This file describes th ...

  9. win10开机后将存在多个系统选择,改为直接进入系统无需选择

    win10系统安装后,可能出现每次开机都要选择操作系统,比较麻烦,所以就来设置下如何直接进入系统,无须选择 1.我的电脑右键“属性”—“高级系统设置”—“系统属性” 2.设置“启动和故障恢复”如下 选 ...

  10. Mysql实现数据库主从复制架构

    MySQL复制 (1)扩展方式: Scale Up ,Scale Out (2)MySQL的扩展 读写分离 复制:每个节点都有相同的数据集 向外扩展 二进制日志 单向 (3)复制的功用: 数据分布 负 ...