ORB_SLAM2::Initializer 用于单目情况下的初始化。

Initializer 的构造函数中传入第一张影像,这张影像被称作 reference frame(rFrame)。在获得第二张影像时传入第二张影像,这张影像被称作 current frame(cFrame)。这一部分传入的代码可以在ORB_SLAM2::Tracking::MonocularInitialization()中查看,要求 rFrame 与 cFrame 都至少具有 101 个特征点,而且 cFrame 与 rFrame 粗匹配结果不少于 100 个点对。这个粗匹配也很有意思,可以查看ORBmatcher::SearchForInitalization()(粗匹配是对每一个 rFrame 的特征点选定一定大小的窗口,以该特征点在 rFrame 上的坐标为中心,在 cFrame 上提取出覆盖网格内所有的特征点,计算 ORB 描述子的距离,距离够小就说明是匹配点)。

Initializer::Initialize()

在这个函数中完成初始化。首先生成 RANSAC 需要用的最小子集的集合mvSets。随后开两个线程同步进行FindHomographyFindFundamental,这两个函数分别返回SHSF这两个数值用于判定是使用 H 作为初始模型更好,还是用 F 作为初始模型更好。

在用SHSF判定是使用 H 还是 F 之后就是用 H (ReconstructH())或 F (ReconstructF())生成 R、t 和对应的可以三角化的点用于初始地图生成。

ReconstructH() 是使用 Motion and structure from motion in a piecewise planar
environment
生成 8 种可能结果,再使用CheckRT()确定是哪一种最为合适。

Initializer::FindHomography()

每次使用 8 个点通过 SVD 分解计算得到 H21。值得注意的是在进行 Homography 计算之前先进行归一化过程(在函数Normalize()中进行)。

Initializer::Normalize()

归一化过程是将所有的 KeyPoints 进行一次 Affine Transformation,使得变换后的 KeyPoints 均值为原点 \(0\),方差为单位阵 \(I\)。

变换公式为:

\[
x_i^{\prime} = {x_i - \bar{x} \over \sigma} \\
\bar{x} = {\Sigma{x_i} \over N} \\
\sigma = {\Sigma{\left|x_i - \bar{x}\right|} \over N}
\]

归一化的原因是计算出的 H 会依赖于特征点的位置,所以先归一化再计算。(MVG Page 104

归一化的过程可以使用一个矩阵 \(T\) 表示:

\[
x^{\prime} = Tx = \begin{bmatrix} {1 \over \sigma_x} & 0 & \bar{x}{1 \over \sigma_x} \\ 0 & {1 \over \sigma_y} & \bar{y}{1 \over \sigma_y} \\ 0 & 0 & 1 \end{bmatrix} x
\]

后面的计算过程如下:

\[
x_2^{\prime} = H_{21}^{\prime}x_1^{\prime}
\]

\[
Tx_2 = H_{21}^{\prime}Tx_1
\]

\[
x_2 = T^{-1}H_{21}^{\prime}Tx_1
\]

\[
H_{21} = T^{-1}H_{21}^{\prime}T
\]

Initializer::ComputeH21()

在归一化之后,使用归一化的坐标计算 Homography。

没啥好讲,就是 Direct Linear Transformation,参考 MVG Page 88

Initializer::CheckHomography()

用 H21 和 H12 分别将 rFrame(1) 中的特征点和 cFrame(2) 转换到另一张影像中,计算匹配点的距离误差,距离误差转换为卡方距离,卡方距离小于 5.991 说明显著性为 5%,应该认为它们匹配成功,否则不成功将这一对匹配标记为 false。注意这里有两个自由度。

https://en.wikipedia.org/wiki/Chi-squared_distribution#Table_of_.CF.872_values_vs_p-values

匹配成功能就能将于显著性相关的数值加入到评分中,评分越高说明由这八个点计算出的 Homography 越正确。即由CheckHomography()返回的评分currentScore,取 RANSAC 中评分最高的 Homography 作为最终选定的 Homography。

这个 score 会被传入Initialize()函数中的 SH,用作计算 SH/(SH+SF),判断是使用 Homography 还是 Fundamental。

Initializer::ReconstructH()

用函数FindHomography()中 RANSAC 计算得到的 Homography 分解,分解能够得到 8 种可能的 \(R, t\) 结果,用CheckRT()判断选择哪一种结果。

好像这有点错了吧,应该用所有的 inlier 匹配计算 Homography,再用这个更靠谱的 Homography 分解计算 \(R, t\)。

函数ReconstructH()最后也输出三角化成功的三维点。

Initializer::FindFundamental()

FindFundamental()的计算过程与 FindHomography 类似,都是需要进行归一化操作

函数ComputeF21()用八点法计算 Fundamental,计算得到的实际 Fundamental 通过设置最小特征值为 0 投影到 Fundamental 空间,作为输出。

函数CheckFundamental()是将点与线的距离作为误差,计算卡方距离,注意这里有一个自由度,所以显著性检验使用的卡方距离为 3.84。

都差不多,没啥好说的。

Initializer::CheckRT()

这个函数挺重要的,因为分解 H 和 F 都会有很多可能的结果,使用这个函数能够分辨出什么结果是靠谱的。

函数CheckRT()接受 \(R, t\) ,一组成功的匹配。最后给出的结果是这组匹配中有多少匹配是能够在这组 \(R, t\) 下正确三角化的(即 \(Z\) 都大于0),并且输出这些三角化之后的三维点。

如果三角化生成的三维点 \(Z\) 小于等于0,且三角化的“前方交会角”(余弦是 cosParallax)不会太小,那么这个三维点三角化错误,舍弃。

通过了 \(Z\) 的检验,之后将这个三维点分别投影到两张影像上,计算投影的像素误差,误差大于2倍中误差,舍弃。

总结

ORB 里面对通过“最大值”确定的结果都非常小心。一般要求这个“最大值” outstanding,如 ORBmatcher 的构造函数中就有会传入一个 (0,1) 的数值给成员变量 mfNNratio,只有最小距离小于次小距离的 mfNNratio 倍才能算是匹配成功,不允许出现相似的匹配,而取好那么一点点的匹配作为匹配结果。

Initializer::ReconstructH()中最后 8 个可能结果中,最好模型 inlier 数要大于次好模型 inlier 的 1/0.75 倍。

ORB_SLAM2 源码阅读 ORB_SLAM2::Initializer的更多相关文章

  1. ORB_SLAM2 源码阅读 ORB_SLAM2::Initializer::ComputeF21 (OpenCV 细节)

    ORB_SLAM2 计算 F21 的代码是这样的. cv::Mat Initializer::ComputeF21(const vector<cv::Point2f> &vP1,c ...

  2. ORB_SLAM2 源码阅读 ORB_SLAM2::ORBextractor

    整体架构 构造函数进行初始化,传入设定几个重要的成员变量.nfeatures(特征点的个数).nlevels(构造金字塔的层数).scaleFactor(金字塔中相邻层图像的比例系数).iniThFA ...

  3. 应用监控CAT之cat-client源码阅读(一)

    CAT 由大众点评开发的,基于 Java 的实时应用监控平台,包括实时应用监控,业务监控.对于及时发现线上问题非常有用.(不知道大家有没有在用) 应用自然是最初级的,用完之后,还想了解下其背后的原理, ...

  4. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  5. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  6. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  7. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  8. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  9. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

随机推荐

  1. ACM数论之旅1---素数(万事开头难(>_<))

    前言:好多学ACM的人都在问我数论的知识(其实我本人分不清数学和数论有什么区别,反正以后有关数学的知识我都扔进数论分类里面好了) 于是我就准备写一个长篇集,把我知道的数论知识和ACM模板都发上来(而且 ...

  2. Webpack简易入门教程

    <!-- 其实网上关于webpack的教程已经很多了,但是本人在学习过程中发现很多教程有错误,或者写的很不全面,结果做的过程出现各种各样的问题,对新手不但不友好还会让人浪费很多不必要的时间.所以 ...

  3. 【jQuery插件】pagepiling滚屏插件使用

    pagePiling.js 这款 jQuery 插件可以帮助前端开发人员轻松实现全屏滚动效果. 支持所有的主流浏览器,包括IE8+,支持移动设备.下面详细讲解下pagePiling.js的使用步骤. ...

  4. jQuery--Excel插件js-xlsx

    参考博客:http://www.jianshu.com/p/74d405940305 github地址:SheetJS / js-xlsx js引入 <script type="tex ...

  5. 2018 焦作icpc现场赛总结

    Day 0 没有直达焦作的飞机,所以选择了先到新郑机场,再转乘城际列车.城际列车猜是专门给学生开通的吧,每天只有来和回一共两趟(所以机票选择的余地也不多).买的时候只有无座票了,本来以为会一直站着,但 ...

  6. 将javaweb项目部署到阿里云服务器

    主要步骤:1. 购买阿里云服务器2. 远程连接3. 在云服务器上配javaweb环境:jdk,tomcat,MySQL4. 将项目的war文件放到Tomcat下关于云服务器ECS:如果还想在买服务器之 ...

  7. BZOJ5298 CQOI2018交错序列(动态规划+矩阵快速幂)

    显然答案为Σkb·(n-k)a·C(n-k+1,k).并且可以发现ΣC(n-k,k)=fibn.但这实际上没有任何卵用. 纯组合看起来不太行得通,换个思路,考虑一个显然的dp,即设f[i][j][0/ ...

  8. 【题解】CF#896 D-Nephren Runs a Cinema

    容易发现这些 vip 用户并没什么用,所以考虑枚举手持50元与100元的人共有多少个.设手持50元的人 \(a\) 个,手持100元的人 \(a - k\) 个,那么一共是 \(2*a - k\) 个 ...

  9. PHP-从零开始使用Solr搜索引擎服务(下)

    前言: 原文地址: http://www.cnblogs.com/JimmyBright/p/7156085.html 前面在配置完成Solr服务之后,在浏览器上可以打开Solr的管理界面,这个界面几 ...

  10. 【bzoj1187】 HNOI2007—神奇游乐园

    http://www.lydsy.com/JudgeOnline/problem.php?id=1187 (题目链接) 题意 一个$n*m$的矩阵,其中每一个位置有一个权值,求一条回路使得经过的位置的 ...