Frame是ORBSLAM3的基本单元,具备图像帧的位姿、特征点、描述子、3D空间点等属性。每当新的一帧图像送到系统时,Tracking.cpp中的GrabImage***
函数首先会构造一个图像帧再进入到跟踪线程,在跟踪和优化过程中更新Frame的各属性信息。
本篇对ORBSLAM3在不同传感器模式下的Frame构造进过程进行简介,主要包括特征点提取,去畸变处理,网格化注册等几个主要模块,以及一些成员变量的初始化,对于每个模块的详细过程见该系列的其他博客
函数接口如下,flag
用于区分左右目,0表示提取左目图像,1表示提取右目图像。x0,x1
作用于双鱼眼组合双目模式,记录左右目图像重叠区域的x坐标范围
void ExtractORB(int flag, const cv::Mat &im, const int x0, const int x1);
详细特征提取过程见博客:《ORB-SLAM3之ORB特征提取和BRIEF描述子计算》
主要依托于OpenCV函数单独对特征点去畸变,是否对特征点去畸变取决于数据集和配置文件
cv::undistortPoints(mat,mat, static_cast<Pinhole*>(mpCamera)->toK(),mDistCoef,cv::Mat(),mK);
关于相机模型和畸变模型的详细内容见博客:[[]]
针孔相机双目模式下,在分别提取双目图像特征点后还需要将左右目图像的中的特征点对应起来进行匹配,在得到匹配信息后可以计算得到左右目特征点的视差信息,基于视差信息恢复特征点对应3D空间点的深度。主要包括以下几个步骤:
详细步骤见博客:《ORB-SLAM3之基于SAD滑窗的双目特征匹配》
RGBD图像帧是一组一一对应的彩色图和深度图,可以根据彩色图中特征点的坐标在深度图中寻找对应坐标的深度信息,比较简单。
在特征提取过程中已经计算得到了左右目图像的特征点和对应的描述子,通过暴力匹配可以得到左右目特征点之间的匹配关系,此时因为已经知道左右目相机之间的带有真实尺度的外参,因此可以通过三角化恢复出特征点对应的3D空间点真实的深度信息,即相机坐标系下的z值。
通过三角化恢复3D空间点探究
核心思想是将投影关系转化为一个AX=0
的线性方程组求解问题,通过将A矩阵进行SAD分解得到特征点对应的3D坐标。
假设某个特征点的尺度为s,特征点归一化坐标为x,投影矩阵为T=[K*R | K*t]
,3D点为X,x^为(u,v,1)的反对称矩阵,则有:
`sx = TX` -> `sx x TX = 0` -> `x^TX = 0` ->
|0 -1 v| |r1|
|1 0 -u| |r2| X = 0 ->
|-v u 0| |r3|
|-r2 + vr3 |
|r1 - ur3 | X = 0 , 第3行和前面两行线性相关 ->
|-vr1 + ur2|
|-r2 + vr3| X = 0 , 将想匹配的两个特征点全部带入 ->
|r1 - ur3 |
|-r22 + v2r23|
|r21 - u2r23 | X = 0
|-r12 + v1r13|
|r11 - u1r13 |
最后对系数矩阵进行SVD分解可以得到3D点的坐标,因为这里投影矩阵中的R和t是具备真实尺度的,因此得到的3D空间点坐标也具备真实尺度信息。
特征点的网格化注册目的是加速特征匹配,将图像划分为MxN个网格,根据特征点的坐标和每个网格进行绑定。
在寻找某个特征点的匹配点时,优先在匹配图像的对应网格以及附近的网格进行搜索,减小暴力匹配的范围来提高匹配速度,是一个比较有用的小trick