SVO的重定位部分代码解析与分析
SVO的重定位功能体现在:运动跟踪丢失后通过与上一关键帧匹配以及地图点投影,找回当前相机位姿。由于没有后端和回环,SVO的重定位并不是回环校正后的重定位。
代码部分被放在运动跟踪线程里,只有寥寥几行,作用效果十分有限。
原文代码部分如下:
FrameHandlerMono::UpdateResult FrameHandlerMono::relocalizeFrame( const SE3 &T_cur_ref, FramePtr ref_keyframe)
{
SVO_WARN_STREAM_THROTTLE(1.0, "Relocalizing frame");
if (ref_keyframe == nullptr) { //先判断一下last_kf是否存在,如果上个关键帧是空 就直接返回RESULT_FAILURE <重定位失败>
SVO_INFO_STREAM("No reference keyframe.");
return RESULT_FAILURE;
}
//这里类似运动跟踪的第一步: 使用上一关键帧对当前图像进行对齐
SparseAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, true, false);//false false
size_t img_align_n_tracked = img_align.run(ref_keyframe, new_frame_);
//接下来进行判断1:如果跟踪到超过30个点
if (img_align_n_tracked > 30) {
SE3 T_f_w_last = last_frame_->T_f_w_;
last_frame_ = ref_keyframe; //把last_kf作为上一帧
FrameHandlerMono::UpdateResult res = processFrame(); //进行运动跟踪处理
//如果跟踪上了,那在下一帧开始恢复正常的图像运动跟踪
if (res != RESULT_FAILURE) {
stage_ = STAGE_DEFAULT_FRAME;
SVO_INFO_STREAM("Relocalization successful.");
} else{
//如果跟踪失败 <重定位失败>
new_frame_->T_f_w_ = T_f_w_last; //把上一帧的位姿赋给当前帧
SVO_INFO_STREAM("Relocalization failure.");
}
return res;
}
//2. 如果跟踪小于30个点 <重定位失败>
return RESULT_FAILURE;
}
从上面的代码看来,SVO的重定位成功的条件必要满足:1.上一关键帧存在;2当前帧与上一关键帧的图像对齐,跟踪到>30个特征点;3能够通过processFrame()的重重考验(相邻帧位姿优化、重投影位姿优化后的内点>阈值)
要满足前两点非常容易,但重定位往往在第三点上吊死。
在实际运行过程中发现,重定位在图像对齐环节还是可以跟踪到的点是足够的,但是经过重投影之后剩下的匹配点数太少,以至于重定位失败!!
再来看看启动重定位的条件有哪些:
在整个frame_handler_mono.cpp里面 我只找到了当res== result_faliure 时才会进行下一帧的重定位。因此在运动跟踪过程中,一旦某一步失败——下一帧马上开始重定位,要是重定位又失败呢?——继续下一帧重定位·· 重定位···
~ 如果载体在跟踪丢失点附近小范围慢速运动,由于观测的地图点相差并不太大,即便多次重定位失败,还是有机会跟踪回来的。
~ 但是更真实的情况是,机体运动一下子超出范围,开足马力拍屁股走人,然后重定位再也无法跟踪上,视觉跟踪宣布失败!!!
~ 并且重定位一直假定当前帧位姿为上一个有效跟踪点地位姿,当一直重定位不上时,可以通过可视化看见机体位姿不再移动也不再增加,而是一直在丢失点闪啊闪啊闪···
跟踪质量不佳的判定
在运动跟踪过程中,若不满足给定指标要求,则会判定tracking_quality_ = TRACKING_INSUFFICIENT
出现以下几种情况都将被判定为跟踪质量不佳:
1.num_observation < Config::qualityMinFts()
[num_observations实为位姿优化后保留下来的特征点数]
2.feature_drop / init_match_number >0.6
[feature_drop = init_match_number -num_observation ]
重投影后当前帧与地图的匹配点数 - 优化后剩下的特征点数 = 优化过程中特征丢失的数量
即:位姿优化后丢失的特征点数不能超过优化前的3/5,不然就认为跟踪质量不佳
3.repr_n_new_references <Config::qualityMinFts()
此处为重投影之后,若投影成功的地图点数量小于阈值,也判定为跟踪效果不佳。这里有点小疑问,此处的repr_n_new_references 应该就是第二个条件里的init_match_number,个人认为这里的阈值应该要比条件1的阈值要高才行,否则丢特征前后的特征点数量指标相同,这有点不太合理??
4. if( dropout == RESULT_FAILURE && (stage_ == STAGE_DEFAULT_FRAME || stage_ == STAGE_RELOCALIZING))
{stage_ = STAGE_RELOCALIZING;
tracking_quality_ = TRACKING_INSUFFICIENT }
在每一帧结束处理的时候,也会进行一次判断:如果处理默认帧或处理重定位帧的结果为 res 等于 RESULT_FAILURE ;那么判定跟踪质量不好,并在下一帧进行重定位。
在判定当前跟踪质量不好之后,为了避免位姿出现较大跳变,一般会令当前帧位姿为上一帧位姿
并且在下一帧的时候开启重定位!!
总结起来,SVO 的重定位部分问题比较多,丢失之后基本无法重定位回来,有很多地方值得修改
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)