【SLAM-Vins_Fusion】feature_tracker

【SLAM-Vins_Fusion】总览中讲出
main函数中
d.开启了一个新线程sync_process。
线程的作用:如果图像buffer里面有数据的话,读入数据并且添加到estimator中。
过程为:

void sync_process() 
          image0 = getImageFromMsg(img0_buf.front());
          estimator.inputImage(time, image0, image1);
                          中有-->featureFrame = featureTracker.trackImage(t, _img);
                                      featureBuf.push(make_pair(t, featureFrame));

featureBuf 为estimator的一个public数据成员 ,

queue<pair<double, map<int, vector<pair<int, Eigen::Matrix<double, 7, 1> > > > > > featureBuf;

(需要注意,VINS-Mono里面feature_tracker和estimator是完全分开的,而这里feature_tracker包含在estimator里,唯一的差别在于减少了前端跟踪和后端之间的rostopic的发布和订阅)

而在

main---> setParameter()--->processMeasurement() 中 读取featureBuf;
feature = featureBuf.front();

//然后有
processIMU(accVector[i].first, dt, accVector[i].second, gyrVector[i].second);
processImage(feature.second, feature.first);

featureFrame = featureTracker.trackImage(t, _img);

前面讲了featureTracker的调用步骤,接下来开始进入featureTracker函数内部。

featureTracker文件夹下有个feature_tracker.h文件,其中定义了一个FeatureTracker类。
发现通篇仅有一个成员函数FeatureTracker::trackImage()中调用了cv::goodFeaturesToTracke()函数来检测特征点,因此,从该函数开始分析:
输入参数:_cur_time,_img,_img1
返回参数:map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> (乍看起来可复杂,细细分析之)首先是一个map,键值对中的值是一个vector,其中每个元素是一个pair。
原文链接:https://blog.csdn.net/CSDN_XCS/article/details/90340274

类中主要函数为trackImage()

TicToc是一个类,感觉和计时有关,使用std::chrono实现(The elements in this header deal with time.)暂时不展开。
predict_pts,cur_pts:类数据成员,vector<cv::Point2f> predict_pts,cur_pts;
hadPrediction:数据成员,bool hasPrediction;,初始值为什么?(254行赋值为hasPrediction = false;)
如果值为true,则调用openCV的函数进行光流跟踪:
调用了cv::goodFeaturesToTracke()函数来检测特征点
函数详细内容可以查看:calcOpticalFlowPyrLK官方介绍
或查看博客:https://blog.csdn.net/CSDN_XCS/article/details/90340274

可知
代码中调用的时候,传入参数表示的含义:

cv::calcOpticalFlowPyrLK(prev_img, cur_img, prev_pts, cur_pts, status, err, cv::Size(21, 21), 1, 
                cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 30, 0.01), cv::OPTFLOW_USE_INITIAL_FLOW);
   /*
  prev_img, cur_img:上一帧图片,当前帧图片;
  prev_pts, cur_pts:特征点在上一帧中的位置(等待找到对应的流),特整点在当前帧中的          位置(用以保存该算法计算结果);
  status:vector<uchar> status;
  err:vector<float> err;
  cv::Size(21, 21):在每层金字塔中搜索窗的大小(21×21;
  1: 对应两层;
  cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 30, 0.01):终止条件——迭代次数 和 精度;
  cv::OPTFLOW_USE_INITIAL_FLOW:保持和原来一样多特征点数。
*/

然后统计跟踪成功的点数,(即status为1的个数)
如果跟踪成功的点数少于10,那么再执行一次,这次修改传入参数中金字塔的层数为4层

if (succ_num < 10)
              cv::calcOpticalFlowPyrLK(prev_img, cur_img, prev_pts, cur_pts, status, err, cv::Size(21, 21), 3);

假设跟踪成功的点的数目足够多了,进行下一步处理操作:
当FLOW_BACK为true时,再调用cv::calcOpticalFlowPyrLK()进行一次反向的光流跟踪(传入参数时将两幅图像、特征点做对应调换)

cv::calcOpticalFlowPyrLK(prev_img, cur_img, prev_pts, cur_pts, status, err, cv::Size(21, 21), 3);

FLOW_BACK 默认为1
定义在catkin_ws/src/VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml

符合以下要求的才认为是跟踪成功的点:
status[i] && reverse_status[i] && distance(prev_pts[i], reverse_pts[i]) <= 0.5

将跟踪失败的点删除(即当status[i]值为0,删除各vector中下标i对应的元素):
reduceVector(prev_pts, status);
reduceVector(cur_pts, status);
reduceVector(ids, status);
reduceVector(track_cnt, status);
ids, track_cnt:FeatureTracker类的数据成员vector<int> ids;和vector<int> track_cnt;

这里 track_cnt 代表了什么意义?表示了这个点跟踪的次数。

调用undistortedPts成员函数,该函数比较简单,主要想实现的功能是
将像素坐标系下的坐标,转换为归一化相机坐标系下的坐标?即cur_un_pts为归一化相机坐标系下的坐标

cur_un_pts = undistortedPts(cur_pts, m_camera[0]);

接下来,计算pts_velocity,其为当前帧相对于前一帧 特征点沿x,y方向的像素移动速度。
cur_un_pts_map中存放ids[i]和cur_un_pts[i]构成的键值对。
在prev_un_pts_map非空的情况下,对每一个cur_un_pts_map中的键值对都去寻找是否在prev_un_pts_map中存在,若存在像素移动速度不难计算;若不存在则为0;
如果prev_un_pts_map是空的情况下,置零。

pts_velocity = ptsVelocity(ids, cur_un_pts, cur_un_pts_map, prev_un_pts_map);

左右图像的匹配上,方法也是光流跟踪,由左图跟踪到右图,得到右图的匹配点,在反过来光流,剔除掉偏差大的点,但是这里并没有像orb-slam那样直接就三角化出深度,而是把点保存下来,放到后面计算。

cv::calcOpticalFlowPyrLK(cur_img, rightImg, cur_pts, cur_right_pts, status, err, cv::Size(21, 21), 3);
            // reverse check cur right ---- cur left
            if(FLOW_BACK)
            {
                cv::calcOpticalFlowPyrLK(rightImg, cur_img, cur_right_pts, reverseLeftPts, statusRightLeft, err, cv::Size(21, 21), 3);
                for(size_t i = 0; i < status.size(); i++)
                {
                    if(status[i] && statusRightLeft[i] && inBorder(cur_right_pts[i]) && distance(cur_pts[i], reverseLeftPts[i]) <= 0.5)
                        status[i] = 1;
                    else
                        status[i] = 0;
                }
            }

总结

最终返回的 featureFrame
返回值map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> featureFrame
其中Eigen::Matrix<double, 7, 1> xyz_uv_velocity;
包含跟踪点归一化相机坐标系下的坐标3,像素平面上的坐标2,像素移动速度2。

看一下流程过程


FeatureTracker__trackImage.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,755评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,305评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,138评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,791评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,794评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,631评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,362评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,264评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,724评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,900评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,040评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,742评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,364评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,944评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,060评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,247评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,979评论 2 355

推荐阅读更多精彩内容