这篇博客主要讲述一个简单的视觉里程计(Visual Odometry)的实现。整个流程较为简单,后续在此基础上对效率精度进一步提高。
什么是视觉里程计?
首先我们看一看维基百科的介绍https://en.wikipedia.org/wiki/Visual_odometry在机器人和计算机视觉问题中,视觉里程计就是一个通过分析处理相关图像序列来确定机器人的位置和姿态。
我们知道在汽车中有一个里程计,记录着汽车行驶的距离,可能的计算方式就是通过计算车轮滚动的次数乘以轮子的周长,但是里程计会遇到精度的问题,例如轮子打滑,随着时间的增加,误差会变得越来越大。另外在我们机器人和视觉领域,不仅仅要知道行驶的距离,而且要知道机器人行驶的整个轨迹(机器人每个时刻的位置和姿态)我们记着在时间 t 时刻机器人的位置和姿态信息是( xt,yt,zt,ψt,χt,ϕt ),其中 xt,yt,zt 表示机器人在世界坐标系中的位置信息, ψt,χt,ϕt 表示机器人的姿态,分布表示为roll( ψt ), pitch( χt ),yaw( ϕt )
确定机器人轨迹的方法有很多,我们这里主要讲述的是视觉里程计,正如维基百科所述,我们将一个摄像头(或多个摄像头)刚性连接到一个移动的物体上(如机器人),通过摄像头采集的视频流来确定相机的6自由度,如果使用1个摄像头,则称为单目视觉里程计,如果使用两个(或者更多)摄像机,则称为立体视觉里程计。
单目或立体视觉里程计
主要阐述两者之间的优缺点,立体视觉里程计的优点在于可以估算出精确的轨迹,单目估计的轨迹存在一个比例因子,所以对于单目VO,我们可以说的是机器人在X方向上移动了一个单位,但是对于立体VO,我们可以说机器人在X方向上移动了1米。另外对于立体VO计算的轨迹通常更精确(因为提供了更多的数据),但是在有些情况下,如相机与观测物体的距离相距太远(与立体VO中的两个相机之间的距离进行对比),这样立体VO就退化为单目VO,另外考虑设备的装配,单目更有一些优势,比如在一些非常小的机器人上,(如:robobees)
基本算法过程
主要阐述简单的算法过程,基于OpenCV3.0进行简单实现,后期进行扩展,对效率及精度进行一步步优化。
输入
- 通过摄像头获取的视频流(主要为灰度图像,stereo VO中图像既可以是彩色的,也可以是灰度的 ),记录摄像头在 t和t+1 时刻获得的图像为 It 和 It+1, 相机的内参,通过相机标定获得,可以通过matlab或者opencv计算为固定量
输出
- 计算每一帧相机的位置+姿态
基本过程
- 获得图像 It,It+1
- 对获得图像进行畸变处理
- 通过FAST算法对图像 It 进行特征检测,通过KLT算法跟踪这些特征到图像 It+1 中,如果跟踪特征有所丢失,特征数小于某个阈值,则重新进行特征检测
- 通过带RANSAC的5点算法来估计两幅图像的本质矩阵
- 通过计算的本质矩阵进行估计 R,t
- 对尺度信息进行估计,最终确定旋转矩阵和平移向量
接下来就对上述过程进行简单实现。