视觉SLAM十四讲(2):初识SLAM

这一讲主要介绍视觉SLAM的结构,并完成第一个SLAM程序:HelloSLAM。

目录

2.1 小萝卜的例子

单目相机

双目相机

深度相机

2.2 经典视觉SLAM框架

2.3 SLAM问题的数学表述

2.4 编程实践

Hello SLAM

使用cmake

使用库


【高翔】视觉SLAM十四讲

2.1 小萝卜的例子

这一节高翔博士首先介绍了自己组装的“小萝卜”机器人,小萝卜要想具有自主运动的能力,首先要知道自身的姿态,然后是了解外界的环境。这两类问题都需要使用传感器,视觉SLAM中常用的传感器是相机,根据相机的工作工作方式不同,可以分为三类:单目相机(Monocular)、双目相机(Stereo)、深度相机(RGB-D)

单目相机

单目相机结构简单,成本较低。本质上是拍照时的场景在相机的成像平面上留下一个投影,以二维的形式记录了三维的世界。

单目SLAM估计的轨迹和地图,将与真实的轨迹’地图,相差一个因子,也就是所谓的尺度。由于单目SLAM无法仅凭图像确定这个真实尺寸,所以又称为尺度不确定性。 本质原因是通过单张图像无法确定深度,为了得到这个深度,人们开始使用双目相机和深度相机。


双目相机

双目相机由两个单目相机组成,但这两个相机之间的距离(称为基线)是已知的。我们通过这个基线来估计每个像素的空间位置,基线距离越大,能够测量到的就越远,双目与多目的缺点是配置与标定均较为复杂,其深度量程和精度受双目的基线与分辨率的限制,而且视觉计算非常消耗计算资源,需要使用GPU和FPGA设备加速后,才能实时输出整张图像的距离信息。因此在现有的条件下,计算量是双目的主要问题之一。


深度相机

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

目前常用的RGB-D相机还存在测量范围窄、噪声大、视野小、易受日光干扰、无法测量透射材质等诸多问题,在SLAM方面,主要用于室内


2.2 经典视觉SLAM框架

下图为视觉SLAM的经典框架,视觉SLAM流程分为如下步骤:

  1. 传感器信息读取:在视觉SLAM中主要为相机图像信息的读取和预处理。
  2. 前端视觉里程计:其任务为估算相邻图像间相机的运动,以及局部地图的样子。
  3. 后端非线性优化: 后端接受不同时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化,得到全局一致的轨迹和地图。
  4. 回环检测:判断机器人是否到达过先前的位置,如果检测到回环,会把信息提供给后端进行处理。
  5. 建图:根据估计的轨迹,建立与任务要求对应的地图。

关于这几个模块,在后面的张杰会详细介绍,这里先了解即可。


2.3 SLAM问题的数学表述

这里使用数学语言来描述SLAM的过程,SLAM过程可总结为两个方程:

                                                                                   x_k = f(x_{k-1},u_k,w_k)

上式为运动方程,其中x_{k-1}k-1时刻的位置,u_k为传感器的读书,w_k为过程中加入的噪声,方程含义为:根据机器人上一时刻的位置和传感器当前的输入来判断下一时刻机器人的位置。与运动方程相对应,还有一个观测方程:

                                                                                     z_{k,j} =h(y_{i},x_k,v_{k,j})

其中v_{k,j}是观测噪声,y_i为机器人在x_k位置上看到的路标,方程描述的是:根据机器人在x_k位置上看到的路标时,产生的观测数据

这两个方程描述了最基本的SLAM问题:当知道运动测量的读数u,以及传感器的读数z时,如何求解定位问题(估计x)和建图问题(估计y),这样就把SLAM问题建模成了一个状态估计问题?


2.4 编程实践

Hello SLAM

像任何教科书一样,这里从最基本的程序开始,这里使用的是C++代码,这个程序很简单,不多解释了:

#include <iostream>
using namespace std;int main(int argc, char **argv) {cout << "Hello SLAM!" << endl;return 0;
}

在终端执行以下命令来编译,生成一个可执行文件:

g++ hellSLAM.cpp

使用cmake

生面的程序只有一个文件,使用g++可能比较方便,但是当文件越来越多时,就不那么方便了,因为这时输入的编译命令会越来越长。目前,工程上cmake是使用最广泛的,可以很方便的生成一个makefile文件,然后再使用make命令来编译整个工程。我们先创建一个CMakeLists.txt文件,内容如下:

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

在终端使用如下命令调用camke对该工程进行cmake编译,下面的点表示在当前目录下进行cmake。

cmake .

现在可以使用make编译,会看到生成可执行程序helloSLAM

make

使用库

下面演示如何生成一个库,源文件如下:

//这是一个库文件
#include <iostream>
using namespace std;void printHello() {cout << "Hello SLAM" << endl;
}

在CMakeLists.txt文件中添加如下内容,生成hello库,然后和上面一样,使用cmake编译工程,不过这时生成的是静态库libhello.a。

# 添加hello库
add_library(hello libHelloSLAM.cpp)

下面我们生成动态库libhello_shared.so。

# 共享库
add_library(hello_shared SHARED libHelloSLAM.cpp)

库文件只是编译好的二进制文件,如果想使用它,还需要对应的头文件,头文件如下:

#ifndef LIBHELLOSLAM_H_
#define LIBHELLOSLAM_H_
// 上面的宏定义是为了防止重复引用这个头文件而引起的重定义错误// 打印一句hello的函数
void printHello();#endif

最后写一个新文件来使用这个库:

#include "libHelloSLAM.h"// 使用 libHelloSLAM.h 中的 printHello() 函数
int main(int argc, char **argv) {printHello();return 0;
}

在CMakeLists.txt文件中添加以下内容,链接刚才生成的动态库:

# 添加可执行程序调用hello库中函数
add_executable(useHello useHello.cpp)
# 将库文件链接到可执行程序上
target_link_libraries(useHello hello_shared)

最后,再编译即可生成可执行文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439709.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CodeForces - 467C】George and Job(dp,思维)

题干&#xff1a; The new ITone 6 has been released recently and George got really keen to buy it. Unfortunately, he didnt have enough money, so George was going to work as a programmer. Now he faced the following problem at the work. Given a sequence of …

一步步编写操作系统 44 用c语言编写内核1

先来个简单的&#xff0c;欢迎我们神秘嘉宾——main.c。这是我们第一个c语言代码。 1 int main(void) { 2 while(1); 3 return 0; 4 }它没法再简单啦&#xff0c;简单的程序似乎能帮助咱们更容易的理解所学的知识&#xff0c;哈哈&#xff0c;我说的是似乎&#xff0c;其实&…

从零实现一个3D目标检测算法(1):3D目标检测概述

本文是根据github上的开源项目&#xff1a;https://github.com/open-mmlab/OpenPCDet整理而来&#xff0c;在此表示感谢&#xff0c;强烈推荐大家去关注。使用的预训练模型也为此项目中提供的模型&#xff0c;不过此项目已更新为v0.2版&#xff0c;与本文中代码略有不同。 本文…

【Codeforces - 900C】Remove Extra One(思维,STLset,tricks)

题干&#xff1a; You are given a permutation p of length n. Remove one element from permutation to make the number of records the maximum possible. We remind that in a sequence of numbers a1, a2, ..., ak the element ai is a record if for every integer…

一步步编写操作系统 45 用c语言编写内核2

在linux下用于链接的程序是ld&#xff0c;链接有一个好处&#xff0c;可以指定最终生成的可执行文件的起始虚拟地址。它是用-Ttext参数来指定的&#xff0c;所以咱们可以执行以下命令完成链接&#xff1a; ld kernel/main.o -Ttext 0xc0001500 -e main -o kernel/kernel.bin …

【Codeforces - 977F】Consecutive Subsequence(STLmap,输出路径,dp)

题干&#xff1a; You are given an integer array of length nn. You have to choose some subsequence of this array of maximum length such that this subsequence forms a increasing sequence of consecutive integers. In other words the required sequence should …

使用OpenCV库快速求解相机内参

本文主要介绍如何使用OpenCV库函数求解相机内参。具体可查阅官网&#xff1a;https://docs.opencv.org/master/dc/dbb/tutorial_py_calibration.html。 关于相机内参的求解还有很多其它的工具&#xff0c;如使用MATLAB求解会更方便&#xff0c;直接调用MATLAB中的APP即可。 1.背…

一步步编写操作系统 46 用c语言编写内核3

再把上节代码贴出来&#xff0c; 1 //int main(void) { 2 int _start(void) { 3 while(1); 4 return 0; 5 }有没有同学想过&#xff0c;这里写一个_start函数&#xff0c;让其调用main函数如何&#xff1f;其实这是可以的&#xff0c;main函数并不是第一个函数&#xff0c;它实…

从零实现一个3D目标检测算法(2):点云数据预处理

在上一篇文章《从零实现一个3D目标检测算法&#xff08;1&#xff09;&#xff1a;3D目标检测概述》对3D目标检测研究现状和PointPillars模型进行了介绍&#xff0c;在本文中我们开始写代码一步步实现PointPillars&#xff0c;这里我们先实现如何对点云数据进行预处理。 在图像…

【CodeForces - 129C】Statues(思维,bfs)

题干&#xff1a; In this task Anna and Maria play a game with a very unpleasant rival. Anna and Maria are in the opposite squares of a chessboard (8  8): Anna is in the upper right corner, and Maria is in the lower left one. Apart from them, the board h…

一步步编写操作系统 47 48 二进制程序运行方式

操作系统并不是在功能上给予用户的支持&#xff0c;这种支持是体现在机制上。也就是说&#xff0c;单纯的操作系统&#xff0c;用户拿它什么都做不了&#xff0c;用户需要的是某种功能。而操作系统仅仅是个提供支持的平台。 虽然我们是模仿linux来写一个黑屏白字的系统&#x…

百度顶会论文复现(1):课程概述

最近百度推出了一款重磅课程《全球顶会论文作者&#xff0c;28天免费手把手带你复现顶会论文》。这个课程真的是很硬核的课程&#xff0c;这里简单记录下自己的学习过程。 文章目录1. 课程设计思路和安排2. 课程大纲1. 课程设计思路和安排 课程设计思路如下&#xff0c;共分为…

【Codeforces - 127D】Password(思维,二分+字符串Hash)

题干&#xff1a; Asterix, Obelix and their temporary buddies Suffix and Prefix has finally found the Harmony temple. However, its doors were firmly locked and even Obelix had no luck opening them. A little later they found a string s, carved on a rock be…

百度顶会论文复现(2):GAN综述

本节课主要是对GAN的发展进行了介绍&#xff0c;包括基本原理&#xff0c;训练方法&#xff0c;存在问题&#xff0c;改进以及应用场景等。实践作业则为手写数字生成。课程地址为&#xff1a;https://aistudio.baidu.com/aistudio/education/preview/493290。 文章目录1.什么是…

一步步编写操作系统 48 二进制程序的加载方式

接上节&#xff0c;程序头可以自定义&#xff0c;只要我们按照自己定义的格式去解析就行。也许我光这么一说&#xff0c;很多同学还是不能彻底明白如何自定义文件头&#xff0c;因为大多数同学都是用高级语言来写程序&#xff0c;即使用了偏底层的c语言&#xff0c;不同平台的c…

【Codeforces - 864D】Make a Permutation!(贪心,字典序)

题干&#xff1a; Ivan has an array consisting of n elements. Each of the elements is an integer from 1 to n. Recently Ivan learned about permutations and their lexicographical order. Now he wants to change (replace) minimum number of elements in his arra…

百度顶会论文复现(3):视频分类综述

本节课主要是对视频分类的发展进行了介绍&#xff0c;包括任务与背景&#xff0c;分类方法&#xff0c;前沿进展等。课程地址为&#xff1a;https://aistudio.baidu.com/aistudio/course/introduce/1340?directly1&shared1。 文章目录1. 任务与背景2. 视频分类方法2.1 双流…

一步步编写操作系统 46 linux的elf可执行文件格式1

ELF文件格式依然是分为文件头和文件体两部分&#xff0c;只是该文件头相对稍显复杂&#xff0c;类似层次化结构&#xff0c;先用个ELF header从“全局上”给出程序文件的组织结构&#xff0c;概要出程序中其它头表的位置大小等信息&#xff0c;如程序头表的大小及位置、节头表的…

百度顶会论文复现(4):飞桨API详解

本节课主要是对飞桨常用API进行了介绍&#xff0c;课程地址为&#xff1a;https://aistudio.baidu.com/aistudio/education/group/info/1340。 文章目录1.飞桨API官网2. API使用介绍3. 飞桨模型操作1.飞桨API官网 官网地址为&#xff1a;https://www.paddlepaddle.org.cn/docu…

【Codeforces - 977D】Divide by three, multiply by two(思维构造)

题干&#xff1a; Polycarp likes to play with numbers. He takes some integer number xx, writes it down on the board, and then performs with it n−1n−1 operations of the two kinds: divide the number xx by 33 (xx must be divisible by 33);multiply the numbe…