《视觉SLAM十四讲》学习日志(二)——初识SLAM
小萝卜机器人的例子:
就像这种机器人,它的下面有一组轮子,脑袋上有相机(眼睛),为了让它能够探索一个房间,它需要知道:
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的更多相关文章
- 《SLAM十四讲》个人学习知识点梳理
0.引言 从六月末到八月初大概一个月时间一直在啃SLAM十四讲[1]这本书,这本书把SLAM中涉及的基本知识点都涵盖了,所以在这里做一个复习,对这本书自己学到的东西做一个梳理. 书本地址:http:/ ...
- 高博-《视觉SLAM十四讲》
0 讲座 (1)SLAM定义 对比雷达传感器和视觉传感器的优缺点(主要介绍视觉SLAM) 单目:不知道尺度信息 双目:知道尺度信息,但测量范围根据预定的基线相关 RGBD:知道深度信息,但是深度信息对 ...
- 《视觉SLAM十四讲》第2讲
目录 一 视觉SLAM中的传感器 二 经典视觉SLAM框架 三 SLAM问题的数学表述 注:原创不易,转载请务必注明原作者和出处,感谢支持! 本讲主要内容: (1) 视觉SLAM中的传感器 (2) 经 ...
- 《视觉SLAM十四讲》第1讲
目录 一 视觉SLAM 注:原创不易,转载请务必注明原作者和出处,感谢支持! 一 视觉SLAM 什么是视觉SLAM? SLAM是Simultaneous Localization and Mappin ...
- 视觉slam十四讲第七章课后习题6
版权声明:本文为博主原创文章,转载请注明出处: http://www.cnblogs.com/newneul/p/8545450.html 6.在PnP优化中,将第一个相机的观测也考虑进来,程序应如何 ...
- 视觉slam十四讲第七章课后习题7
版权声明:本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/newneul/p/8544369.html 7.题目要求:在ICP程序中,将空间点也作为优化变量考虑进来 ...
- 浅读《视觉SLAM十四讲:从理论到实践》--操作1--初识SLAM
下载<视觉SLAM十四讲:从理论到实践>源码:https://github.com/gaoxiang12/slambook 第二讲:初识SLAM 2.4.2 Hello SLAM(书本P2 ...
- 视觉SLAM十四讲:从理论到实践 两版 PDF和源码
视觉SLAM十四讲:从理论到实践 第一版电子版PDF 链接:https://pan.baidu.com/s/1SuuSpavo_fj7xqTYtgHBfw提取码:lr4t 源码github链接:htt ...
- SLAM十四讲中Sophus库安装
Sophus截止目前有很多版本,其中大体分为两类,一种是用模板实现的方法,一种是用非模板类实现的,SLAM十四讲中使用的是非模板类库,clone Sophus: git clone http://gi ...
随机推荐
- 调整统计信息JOB采样时间
一.需求说明 Oracle数据库中存在定时JOB,自动执行收集统计信息的程序.但是对于7*24小时系统来说,Oracle配置的定时收集时间不太合理,需要人为调整.本篇博客就是基于这种需求,调整JOB采 ...
- AngularJS视图 ng-view
AngularJS支持通过在单个页面上的多个视图的单页应用.要做到这一点AngularJS提供ng-view 和 ng-template指令,以及 $routeProvider 服务. ng-view ...
- linux gcc安装
2004年4月20日最新版本的GCC编译器3.4.0发布了.目前,GCC可以用来编译C/C++.FORTRAN.java.OBJC.ADA等语言的程序,可根据需要选择安装支持的语言.GCC 3.4.0 ...
- # JDK7+ MethodHandle
简单例子 import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.i ...
- CAS客户端认证流程
CAS登陆流程 Step 1:浏览器向CAS客户端发起登陆请求,CAS客户端生成“登陆URL”,并把浏览器重定向到该URL 登陆URL: https://${cas-server-host}:${ca ...
- nRF24L01无线介绍
CE:RX或TX模式选择 CSN:SPI片选信号 SCK:SPI时钟 MOSI:SPI数据输入 MISO:SPI数据输出 IRQ:可屏蔽中断脚 51测试程序 实测可用! #define TX_ADR_ ...
- Linux下安装php报错:libxml2 not found. Please check your libxml2 installation
ubuntu/debian: apt-get install libxml2-dev centos/redhat: yum install libxml2-devel
- Image Processing and Analysis_8_Edge Detection:Edge Detection Revisited ——2004
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- log:日志处理模块
为了更好的跟踪程序,我们通常都会使用日志,当然在golang中也提供了相应的模块. 基本使用 可以直接通过log来调用格式化输出的方法. package main import "log&q ...
- git 从存储库中删除敏感数据(删除文件历史)
1.如果您的历史记录中还没有包含敏感数据的存储库的本地副本,请将存储库克隆到本地计算机. git clone https://github.com/YOUR-USERNAME/YOUR-REPOSIT ...