视觉slam14讲之VO框架的搭建

   视觉里程计VO的搭建基本都会有以下几个问题:怎么管理地图点,如何处理误匹配,如何选择关键帧。。。由简到繁进行。
1. 视觉里程计分单目,双目,RGB-D三大类。单目视觉相对复杂,RGB-D最简单,没有初始化,也没有尺度问题。

2. 编写小规模的库时,往往建立一些文件夹,把源代码,头文件,文档,测试数据,配置文件,日志等分类存放。当一个库内容很多时,往往还会把代码分解各个独立的小模块,便于测试。OpenCV或g2o的组织方式就可以参考借鉴。小型程序揉在一起也没什么。我建立如下文件夹来组织代码文件:
视觉slam14讲之VO框架的搭建

3. 构造基本的数据结构
a. 帧:帧是相机采集到的图像单位。它主要包含一个图像(RGB-D情形下是一对图像)。此外,还有特征点,位姿,内参等信息。视觉slam中谈论关键帧,由于相机采集的数据很多,存储所有的数据显然不实际,通常选取我们认为重要的帧保存起来,并认为相机轨迹可以用这些关键帧来描述。然而关键帧的选择方法基本基于工程经验,很少有理论上的指导。
b. 路标:路标点即图像中的特征点。在相机运动后,可以估计它们的3D位置。通常,会把路标点放在一个地图当中,并讲新来的帧与地图中的路标点进行匹配,估计相机位姿。
c.帧的位姿与路标的位置估计相当于一个局部的SLAM问题,基本还需一些工具,让程序写起来更流畅。引出配置文件:程序中使用各种各样的参数,比如相机的内参,特征点的数量,匹配时选择的比例,等等。框架往往就是这样产生的,外部定义配置文件,程序运行时读取该配置文件中的参数值。修改也只需修改配置文件,而无需在程序中一个个修改。
d. 坐标变换:程序需要经常在坐标系间进行坐标变换,例如:世界坐标到相机坐标,相机坐标到归一化相机坐标,归一化相机坐标到像素坐标,等等。定义一个类把这些操作都放到一个将更方便。

4. 基本思想,该程序偏向算法而非软件工程,故不讨论复杂的类继承关系,接口,模板等,而更关注与算法的正确实现,以及是否便于拓展。VO开始写5个类:Frame为帧,Camera为相机模型,MapPoint为特征点/路标点,Map管理特征点,Config提供配置参数。
视觉slam14讲之VO框架的搭建
这个是简化的UML图。

5. 几个类的功能
a. Camera类存储相机的内参和外参,并完成相机坐标系,像素坐标系和世界坐标系之间的坐标变换。
b. Frame类,它作为基本数据单元,在许多地方会用到,目前提供基本的数据存储和接口。ID,时间戳,位姿,相机,图像这几个是一个帧中最重要的信息。几个重要的方法: 创建Frame,寻找给定点对应的深度,获取相机光心,判断某个点是否在视野内。
c. MapPoint类表示路标点。讲估计它的世界坐标,并会拿当前帧提取到的特征点与地图中的路标点匹配,来估计相机的运动,还需要存储它对应的描述子。额外:记录一个点被观测到的次数和被匹配的次数。
d. Map类管理所有的路标点,并负责添加新路标,删除不好的路标等工作。VO的匹配过称只要与Map打交道即可。Map类中存储了各个关键帧和路标点,即需要随机访问,又需要随时插入和删除,因此使用散列(Hash)来进行存储。
e. Config类负责参数文件的读取,并在程序的任意地方都可以随时提供参数的值。故可以把Config写成单例模式(Singleton),它只有一个全局对象,当我们设置参数文件时,创建该对象并读取参数文件,随后就可以在任意地方访问参数值,最后在程序结束时自动销毁。