通俗易懂理解ORBSLAM2跟踪模块
一、通俗易懂理解Tracking类==匹配&&定位(切题 Done)
1.参考资料:
[1] 计算机视觉Life ORB-SLAM2源码讲解专题四:单目Tracking线程源码
2.主要函数:
帧间跟踪
(1)正常模式:
TrackWithMotionModel()
(2)出现意外:
TrackReferenceKeyFrame()
(3)实在不行,垂死挣扎:
Relocalization()
局部地图跟踪
TrackLocalMap()
关键帧判断和产生
NeedNewKeyFrame()
CreateNewKeyFrame()
3.问题:
问题
EPNP的使用原则好像只有重定位才用到。
比如匀速运动模型或者是参考关键帧模型,都不用,因为他们的匹配点比较好。
纯跟踪是什么意思? 地图更不更新是什么意思? 为什么有一个产生地图点的事。
纯视觉里程计,没有产生关键帧,所以没有局部建图,所以没有新的地图点产生。只有匹配地图点使得某帧对应的地图点不为NULL。
关键帧确定的原则是什么:
当前帧对应的地图点被观测的数量小于最新关键帧对应的地图点被观测的数量的90%并且当前帧对应的地图点被观测的数量小于15
词袋匹配具体利用词袋后,然后怎么做?****跟踪中他们的共性是什么
先缩小范围(词袋、重投影),再计算描述子距离,得到最佳匹配,再用旋转直方图进行剔除误匹配。
跟踪局部地图,出了提升位姿的准确性,对地图点有什么影响呢,增加地图点?局部地图的局部关键帧选择,重复了怎么办???
不增加地图点。只有匹配地图点使得某帧对应的地图点不为NULL。有一个判重按钮。
Tracking线程的局部地图跟踪是什么
Tracking线程的局部地图跟踪,首先每次更新当前帧的局部关键帧,再由局部关键帧得到局部地图点。而当前帧的局部关键帧是:(1)和当前帧共视(有共同地图点)的关键帧,(2)以及(1)中每个关键帧的最强共视关键帧10帧,(3)还有(1)中的的孩子和父亲关键帧统统拉入伙。然后通过局部关键帧得到局部地图点,用于Tracking线程的位姿跟踪。
二、通俗易懂理解匀速运动模型TrackWithMotionModel()
题目:基于匀速运动模型实现的是什么呢:减小匹配的搜索范围,加速特征点的匹配。然后进行位姿优化。单目追踪过程中地图点从哪里来?为什么不PNP呢?如何进行pose only BA?
参考:
思路:
1.思路:
1.使用匀速运动模型进行特征点匹配?
将上一帧的每个非NULL地图点投影到当前帧进行特征点匹配,在地图点的投影点附近进行找到特征点集合,然后从中找到描述子间距离最小的特征点,将该地图点作为该特征点对应的地图点,然后把他们的旋转角度差存入旋转直方图,用于去除错误的匹配。
匹配步骤:缩小范围(重投影);利用描述子距离寻找最佳匹配点;利用旋转直方图去除误匹配
匹配点数量大于阈值进行pose only BA.
2.单目追踪过程中地图点从哪里来,即单目地图点补充?
单目初始化+局部地图中地图点创建。
3.为什么不PNP呢?
[1]匀速运动模型进行特征点匹配,如果有足够数量的匹配,直接pose only BA, PnP没有必要了,PnP还得RANSAC,得到的结果也不一定使得所有匹配点重投影误差最小,还不如直接Pose Only BA.
[2]如果相机的运动问题使得匀速运动模型不成立,那么怎么办?得到的匹配点就不是很多,比如重定位模式下,这时候需要PnP为Pose Only BA 提供初始值了。
4.如何进行pose only BA?一元边?
一元边:就一个优化变量
进行4次优化
[1]每次优化10次,误差太大(基于卡方分布的自由度得到的,比如自由度为2, 服从高斯分布,误差小于1个像素,这个事发生的概率超过95%对应有一个值),设为外点,不优化
[2]前2次需要鲁棒核函数,其他不需要,因为误差已经明显下降了
[3]返回内点数量
2.图解(请用纸):
Tracking_TrackWithMotionModel3.公式推导(请用纸):
要点程序:
其他:
=========================================================================
题目:匀速运动模型的速度怎么得到的呢?
参考:
思路:
1.思路:
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
mVelocity = mCurrentFrame.mTcw * LastTwc; // 其实就是 Tcl
mCurrentFrame.SetPose(mVelocity * mLastFrame.mTcw);
其他:
=========================================================================
题目:上一帧的地图点是怎么得到的呢?初始化成功之后,什么情况下进行三角化呢?
参考:
思路:
1.思路:
上一帧的地图点是怎么得到的呢?通过特征点匹配得到的。
初始化成功之后,什么情况下进行三角化呢?对于单目而言,那就只有在local mapping创建地图点环节。
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
其他:
=========================================================================
题目:普通帧的地图点是什么时候产生的呢?
参考:
思路:
1.思路:
对单目而言,没有。
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
其他:
=========================================================================
题目:特征点匹配为什么有一个比例呢?什么时候需要加比例,什么时候需要减小比例呢?
参考:
思路:
1.思路:
描述子最优距离和描述子次优距离,有的时候需要判断2者差别明显,匹配才是比较可信的。
[1]匀速运动模型=>重投影搜索,只有最优
ORBmatcher::SearchByProjection
[2]追踪参考帧,重定位=>词袋搜索,最优和次优,比例:0.7
ORBmatcher::SearchByBoW
[3]初始化=>小窗口搜索,最优和次优,比例比较高,0.9
ORBmatcher::SearchForInitialization
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
其他:
=========================================================================
题目:void Tracking::UpdateLastFrame()
参考:
思路:
1.思路:
上一帧的参考关键帧就是最近的关键帧
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
其他:
三、通俗易懂理解跟踪参考帧模型TrackReferenceKeyFrame
题目:追踪参考关键帧,这个参考关键帧是什么?如何得到当前帧的参考关键帧?
参考:
思路:
1.思路:
local mapping中当前关键帧的参考关键帧:和当前帧共视程度最高的关键帧
tracking中的参考关键帧是最新的关键帧
2.图解(请用纸):
TrackReferenceKeyFrame
3.公式推导(请用纸):
要点程序:
其他:
四、通俗易懂理解重定位Tracking::Relocalization()
题目:重定位模式下的候选关键帧是什么,是一个还是多个呢?理论上是多个。
参考:KeyFrameDatabase、Map、Optimizer类 要点() 这里结果get候选关键帧集合
思路:
1.思路:
重定位的时候,通过检测当前帧和那个关键帧最接近,来确定当前的位置和姿态
主要就是利用词袋数据,在已有的关键帧中查找和当前帧最接近的关键帧集合。
主要过程:
// 得到和当前帧有共同单词的关键帧集合,得到共同单词数最多的数量
// 将大于共同单词数阈值的关键帧放入一个集合
// 对于集合中的每一个,找他的最强共视关键帧10帧,
// 得到该组中的累计得分和得分最高的关键帧(这个组的代表)
// 累计得分大于阈值的组并把该组的代表放入候选关键帧集合中
lAccScoreAndMatch.push_back(make_pair(accScore, pBestKF));
2.图解(请用纸):
KeyFrameDatabase_DetectRelocalizationCandidates3.公式推导(请用纸):
要点程序:
其他:
=========================================================================
题目:重定位的过程是怎么样的?
参考:
思路:
1.思路:
垂死挣扎!
2.图解(请用纸):
Tracking_Relocalization3.公式推导(请用纸):
要点程序:
其他:
=========================================================================
题目:词袋匹配和重投影匹配中的地图点是什么回事?能再好好看看基于词袋的特征点匹配,给出具体清晰的流程?
参考:
思路:
1.思路:
有关键帧的地图点和当前帧的地图点,当前帧的地图点初始化都是NULL,如果当前帧和关键帧特征匹配上的话,那么他们的地图点是同一个,将关键帧对应的地图点赋值给普通帧的地图点。
2.图解(请用纸):
匹配步骤:缩小范围(词袋);利用描述子距离寻找最佳匹配点和次佳匹配点;利用旋转直方图去除误匹配
3.公式推导(请用纸):
要点程序:
其他:
五、通俗易懂理解局部地图跟踪TrackLocalMap:
=========================================================================
题目:如何追踪局部地图
参考:
思路:
1.思路:
// (1)更新局部关键帧 mvpLocalKeyFrames 和局部地图点 mvpLocalMapPoints
UpdateLocalMap();
Tracking线程的局部地图跟踪,首先每次更新当前帧的局部关键帧,再由局部关键帧得到局部地图点。而当前帧的局部关键帧是:(1)和当前帧共视(有共同地图点)的关键帧,(2)以及(1)中每个关键帧的最强共视关键帧10帧,(3)还有(1)中的的孩子和父亲关键帧统统拉入伙。然后通过局部关键帧得到局部地图点,用于Tracking线程的位姿跟踪。
// (2)在局部地图中查找与当前帧匹配的MapPoints
SearchLocalPoints();
// (3)位姿优化
Optimizer::PoseOptimization(&mCurrentFrame);
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
其他:
=========================================================================
题目:如何进行当前帧和局部地图点的匹配?
参考:
思路:
1.思路:
(1)遍历当前帧的所有地图点,对isBad的地图点进行置为NULL。
(2)对于局部地图点,判断局部地图点是否在视野中,并进行统计数量。
(3)对视野范围内的地图点进行重投影匹配。
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
其他:
=========================================================================
题目:如何判断局部地图点是否在视野中
参考:
思路:
1.思路:
(1)把地图点转换到当前帧相机坐标系下,如果深度为负,那么返回false.
(2)把地图点转换到当前帧像素坐标系下,如果超出图像边界,那么返回false.
(3)如果地图点和当前相机位置的距离不在最大和最小范围内,返回false
(4)计算从当前相机指向地图点的方向和地图点的平均观测方向大于60度,返回false
(5)根据地图点到光心的距离预测地图点一个尺度,仿照特征点金字塔层级
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
bool Frame::isInFrustum(MapPoint *pMP, float viewingCosLimit)
其他:
=========================================================================
题目:如何判断地图点的最大和最小距离范围。如何根据地图点到光心的距离预测地图点一个尺度,仿照特征点金字塔层级
参考:
思路:
1.思路:
2.图解(请用纸):
根据距离预测地图点所在的金字塔层级
首先,取对数后变为
3.公式推导(请用纸):
要点程序:
六、通俗易懂理解关键帧判断准则NeedNewKeyFrame
题目:关键帧的判定准则是什么
参考:
思路:
1.思路:
Tracking中的参考关键帧就是最新的关键帧。参考关键帧对应的地图点(该地图点被多次观测,比如2或者3)的数量
mnMatchesInliers:
当前帧对应的地图点被观测(大于0就行)的数量
thRefRatio:单目0.9,频繁插入
结论:当前帧对应的地图点被观测的数量小于最新关键帧对应的地图点被观测的数量的90%并且当前帧对应的地图点被观测的数量小于15,插入。还有就是间隔多少帧插入一下。其他不care.
no care:
ratioMap:1
thMapRatio: 0.35
2.图解(请用纸):
3.公式推导(请用纸):
要点程序:
const bool c2 =
((mnMatchesInliers <
nRefMatches *
thRefRatio || // 总的来说,还是参考关键帧观测到的地图点的数目太少,少于给定的阈值
ratioMap < thMapRatio) && // 追踪到的地图点的数目比例太少,少于阈值
mnMatchesInliers > 15); //匹配到的内点太少
int nRefMatches = mpReferenceKF->TrackedMapPoints(nMinObs);