The implementation that I describe in this post is once again freely available on github. It is also simpler to understand, and runs at 5fps, which is much faster than my older stereo implementation.

  • https://github.com/avisingh599/mono-vo

输入nput

相机的灰度图像。
We have a stream of gray scale images coming from a camera.

输出

旋转矩阵R和平移矢量t,它们描述了两个帧之间的车辆运动。 在我们的单眼方案中,向量t最多只能计算成比例因子。

过程

第一步:Capture images: It,It+1I_{t}, I_{t+1}It​,It+1​

第二:Undistort, Rectify the above images.不失真,校正以上图像。

第三:Use FAST algorithm to detect features in It, and track those features to It+1使用FAST算法检测ItI_{t}It​中的特征,并将这些特征跟踪到It+1I_{t + 1}It+1​。如果特征数量降至某个阈值以下,则会触发新的检测。

第四:Use Nister’s 5-point alogirthm with RANSAC to compute the essential matrix.使用Nister的5点运算法则和RANSAC来计算基本矩阵。

第五:Estimate R,t from the essential matrix that was computed in the previous step.根据上一步中计算出的基本矩阵估算R,t。

第六:Take scale information from some external source (like a speedometer), and concatenate the translation vectors, and rotation matrices.从某些外部来源(例如速度计)获取尺度比例信息,并连接平移矢量和旋转矩阵。

FAST特征提取

使用OpenCV,检测功能很简单,这是执行此操作的代码。

void featureDetection(Mat img_1, vector<Point2f>& points1) { vector<KeyPoint> keypoints_1;int fast_threshold = 20;bool nonmaxSuppression = true;FAST(img_1, keypoints_1, fast_threshold, nonmaxSuppression);KeyPoint::convert(keypoints_1, points1, vector<int>());
}

设置上面代码中的参数,以便在KITTI数据集中的一张图像上提供约4000个特征。 您可能需要调整这些参数,以便在您自己的数据上获得最佳性能。

请注意,上面的代码还将检测到的特征点的数据类型从KeyPoints转换为Point2f的向量,以便我们可以将其直接传递到特征跟踪步骤,如下所述:Feature Tracking

Feature Tracking_KLT跟踪器

在上一步中检测到的快速拐角将馈送到使用KLT跟踪器的下一步。 KLT跟踪器基本上会环视要跟踪的每个角,并使用此本地信息在下一幅图像中找到该角。

在It + 1中跟踪在It中检测到的角。 设在It中检测到的特征为Ft,在It + 1中对应的特征为Ft + 1。 这是使用KLT跟踪器在OpenCV中进行跟踪的功能:

void featureTracking(Mat img_1, Mat img_2, vector<Point2f>& points1, vector<Point2f>& points2, vector<uchar>& status)  { //this function automatically gets rid of points for which tracking failsvector<float> err;                 Size winSize=Size(21,21);                                                                                              TermCriteria termcrit=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01);calcOpticalFlowPyrLK(img_1, img_2, points1, points2, status, err, winSize, 3, termcrit, 0, 0.001);//getting rid of points for which the KLT tracking failed or those who have gone outside the frameint indexCorrection = 0;for( int i=0; i<status.size(); i++){  Point2f pt = points2.at(i- indexCorrection);if ((status.at(i) == 0)||(pt.x<0)||(pt.y<0))    {if((pt.x<0)||(pt.y<0))   {status.at(i) = 0;}points1.erase (points1.begin() + i - indexCorrection);points2.erase (points2.begin() + i - indexCorrection);indexCorrection++;}}}

特征重检测

请注意,在进行KLT跟踪时,我们最终会丢失一些点(当它们移出汽车的视野时),因此,只要特征总数低于某个阈值(在我的实现中为2000),我们就会触发重新检测 )。

基本矩阵估计

一旦有了点对应关系,便有了几种用于计算基本矩阵的技术。

基本矩阵定义如下:
y1TEy2=0y^T_1Ey_2 = 0y1T​Ey2​=0

此处,y1,y2y_1,y_2y1​,y2​是均匀的标准化图像坐标。

虽然有一个简单的算法需要八点对应关系 ,但五点算法是一种显示出更好结果的较新方法。 由于基本矩阵只有五个自由度,因此它可以解决许多非线性方程,并且需要的点数最少

五点算法

David Nister An efficient solution to the five-point relative pose problem (2004) ↩

RANSAC

如果我们所有的点对应关系都是完美的,那么我们只需要两个连续帧之间的五个特征对应关系就可以准确地估计运动。

但是,特征跟踪算法并不完美,因此我们有几个错误的对应关系。

在进行模型估计时处理异常值的标准技术是RANSAC。

这是一个迭代算法。 在每次迭代中,它从一组对应关系中随机采样五个点,估计基本矩阵,然后在使用此基本矩阵时检查其他点是否为内点。 该算法在固定次数的迭代后终止,并使用与最大点数一致的基本矩阵。

在OpenCV中再次使用上述内容非常简单,您只需要一行:
E = findEssentialMat(points2, points1, focal, pp, RANSAC, 0.999, 1.0, mask);

Computing R, t from the Essential Matrix

基本矩阵的另一个定义(与前面提到的定义一致)如下:
E=R[t]xE = R [t]_xE=R[t]x​
这里,R是旋转矩阵,而[t] x是与t的叉积的矩阵表示。

取基本矩阵的SVD,然后利用旋转矩阵的约束,我们得到以下信息:
E=UΣVTE=UΣV^TE=UΣVT
[t]x=VWΣVT[t]_x=VWΣV^T[t]x​=VWΣVT
R=UW−1VTR=UW^{−1}V^TR=UW−1VT

Here’s the one-liner that implements it in OpenCV:
recoverPose(E, points2, points1, R, t, focal, pp, mask);

构造轨迹

通过本质矩阵可以得到两帧计算的相对位置关系,因为第二幅图像对应相机矩阵是在假设第一幅图像的相机矩阵为P=[I|0]的情况,因此我们对每次计算的相对量进行累加,设当前相机的旋转矩阵和平移为Rpos,tpos表示。 然后,我们可以使用以下方程式跟踪轨迹:
Rpos=RRposR_{pos}=RR_{pos}Rpos​=RRpos​
tpos=tpos+scale∗tRpost_{pos}=t_{pos}+scale*tR_{pos}tpos​=tpos​+scale∗tRpos​

注意,在连接之前必须从其他来源获取平移向量的ttt的scale比例信息。 在我的实现中,我从KITTI数据集提供的基本事实中提取了此信息。

启发式

如果没有一些启发式方法,大多数Computer Vision算法都是不完整的,Visual Odometry也不例外。 下面说明我们使用的启发式:

主导运动向前

整个视觉里程计算法假设其环境中的大多数点都是刚性的。 但是,如果我们处于车辆静止不动而公交车经过的情况(例如,在路口),则会导致算法认为汽车已经横向行驶,这在物理上是不可能的 。As a result, if we ever find the translation is dominant in a direction other than forward, we simply ignore that motion. 主导运动是向前运动,一些情况下,忽略其他方向的运动。

接下来是什么?

A major limitation of my implementation is that it cannot evaluate relative scale.

我确实尝试实现一些方法,但是遇到了被称为“标度漂移”的问题,即,积累了小误差,从而导致里程计估计错误。 希望我会尽快实现更健壮的相对比例计算管道,并撰写相关文章!

[翻译]Monocular Visual Odometry using OpenCV相关推荐

  1. SVO(SVO: fast semi-direct monocular visual odometry)

    SVO(SVO: fast semi-direct monocular visual odometry)翻译 文章目录 SVO(SVO: fast semi-direct monocular visu ...

  2. SVO: Fast Semi-Direct Monocular Visual Odometry

    论文翻译 论文讲解1 论文讲解2 一.符号规定 在论文的第三部分,为了方便后面的叙述,将用到的大部分符号都做了一定的规定. 首先,论文采用的是图片的灰度值,所以将第k时刻的图片的灰度值记为Ik,这个I ...

  3. PL-SVO: Semi-Direct Monocular Visual Odometry by Combining Points and Line Segments

    一.系统总览 这篇论文主要是在半直接法SVO的基础上,将线特征融合了进去,其基本的流程框架还是沿用了SVO的设计.如果直接使用线特征参与位姿的计算,后续的运算开销会很大,所以在后面的论文中都是使用了一 ...

  4. 【论文阅读】DPLVO: Direct Point-Line Monocular Visual Odometry

    一.公式及符号约定 这篇文章与之前看的EDPLVO是同一个作者,EDPLVO是在这篇文章的基础上改进的,符号约定方面,DPLVO同样采用R和t表示旋转矩阵和平移向量,使用Π表示投影函数,利用R和t以及 ...

  5. 计算机视觉与深度学习 | 开源SLAM、视觉里程计综述(SLAM、Visual Odometry)

    视觉里程计综述 引言 Visual Odometry or VSLAM OF-VO:Robust and Efficient Stereo Visual Odometry Using Points a ...

  6. svo: semi-direct visual odometry 半直接视觉里程计 fast角点匹配 光流匹配 单应变换求位姿 直接法求解位姿 高斯均匀分布混合深度滤波

    svo: semi-direct visual odometry 半直接视觉里程计 本博文github地址 svo代码注释 SVO代码分析 较细致 svo: semi-direct visual od ...

  7. 学习笔记之——Semi-direct Visual Odometry (SVO)

    本博文为本人学习SVO的学习笔记,本博文大部分内容来源于网络各种参考资料,本博文仅为本人学习记录用. 目录 原理 Tracking(位姿估计线程) 第一步:图像对齐 第二步:特征对齐 第三步:位姿结构 ...

  8. Visual Odometry Revisited: What Should Be Learnt?(2020.2)

    代码:https://github.com/Huangying-Zhan/DF-VO 文章:https://arxiv.org/abs/1909.09803 摘要 本文利用几何关系和深度学习提出单目视 ...

  9. 论文阅读——《Online Photometric Calibration of Auto Exposure Video for Realtime Visual Odometry and SLAM》

    论文阅读--<Online Photometric Calibration of Auto Exposure Video for Realtime Visual Odometry and SLA ...

  10. 视觉里程计 | OF-VO:Robust and Efficient Stereo Visual Odometry Using Points and Feature Optical Flow

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 代码执行环境:Windows 8 ...

最新文章

  1. BCH代币化方案讨论大爆发,你的观点是什么?
  2. Android Stadio 导入moudle 不显示
  3. 解决img标签间距问题
  4. linux软中断的实现
  5. 在WinCE 6.0系统下实现USB功能定制
  6. 机器学习实战-逻辑回归-19
  7. vue封装axios接口
  8. C# 读取机器CPU信息,硬盘信息,网卡信息(转载)
  9. Week 1 Team Homework #3 from Z.XML-软件工程在北航
  10. 超分辨率在移动实时音视频的应用实践
  11. asp.net mvc redis同步mysql_Mysql和Redis数据同步策略 - 元思 - 博客园
  12. SpringBoot使用RestTemplate 摘要认证
  13. MySQL中的float和decimal类型有什么区别
  14. 科学计算机怎么用10次方,一个数怎么用计算器开10次方
  15. VTK学习之一(基本介绍、一个简单的VTK例子)
  16. 定积分分部积分典型例题_定积分证明题方法总结六篇
  17. gitlab无法推送
  18. 2022芒果TV算法赛_用户下一个观看视频预测_baseline_CF召回YoutubeDNN
  19. js字符串时间格式与中国标准时间格式相互转换
  20. 计算机如何将两个磁盘合在一起,如何把两个磁盘合并在一起?

热门文章

  1. 阅读笔记——《R数据可视化手册》肖楠等;主要ggplot2
  2. 带ant 的收发器_ANT无线收发器nRF24AP1及其应用
  3. 实习踩坑之路:ElasticSearch双写数据不同步?不实时?怎么优化?
  4. 实习踩坑之路:Date、LocalDate和LocalDateTime的区别
  5. 备案号链接工信部_网站主页底部网站备案号的悬挂和链接的工作通知
  6. java多数据源事务处理_springboot整合多数据源解决分布式事务
  7. linux racoon代码,源代码安装IPsec-Tools-0.7.2
  8. 5天学python_人生苦短,我将学习Python基本句子(第5天),我学,基础,篇,语句,Day5...
  9. java 读取wav采样数据_读取wav文件中的音频数据操作
  10. java 默认为空的注解,错误注解的字段设置一个默认的空值