vins是香港科技大学开源的一个单目相机结合IMU的一个VIO,在github上可以下载源码,分为iOS系统下的和ros系统下的两种,ros下的为
https://github.com/HKUST-Aerial-Robotics/VINS-Mono.git
vins的精髓就在视觉和Imu的融合算法,但是我不懂imu就有点尴尬了。所以查看了imu的资料。
vins的主要框架有个很好的图,如下图。
![这里写图片描述](https://img-blog.csdn.net/20171009083951821?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjUyNTQ3Nzc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
在ros下,vins主要就是两个节点,一个节点算前端,节点为feature_tracker_node.cpp,另一个节点算后端,节点为estimator_node.cpp。
今天先从前端开始记,在节点feature_track_node节点中主要的部分都在回调函数中。最开始记下第一帧的时间戳,同时对发布帧的频率做控制。后面有个for循环,这个写是单目vins,但是里面还是做了双目的考虑。双目暂且不考虑,只看单目。然后执行特征点跟踪类中的readImage,
readImage首先判断得到的图像是否合适(有的光照条件不行),如果不合适需要进行直方图均衡化,提高寻找特征点的质量。
判断当前帧是否为空(这里forw表示光流当前帧,cur光流上一帧,pre是上一次发布的帧),如果是第一帧那么你肯定当前帧是空的,此时需要
prev_img = cur_img = forw_img = img;
将img传递给pre, cur , forw。如果你不是第一帧那么仅仅需要
forw_img = img;
传递给当前帧。
做完这个判断就将当前帧的特征点清零。为下面的光流跟踪做准备。
后面就开始光流跟踪,并根据跟踪的结果对pre,cur ,forw的特征点进行删减,同时对特征点的id,和跟踪特征点的总数进行相应的删减。
做完这些就判断这一帧是否需要发布,如果需要发布进入相应的函数中,其中有个函数rejectWithF(),这个函数里面的东西蛮多,有的看的不是太明白,
m_camera->liftProjective(Eigen::Vector2d(prev_pts[i].x, prev_pts[i].y), tmp_p);//cataCamera.cpp
个人理解应该是将图像特征点的坐标
映射到空间坐标,但是其中你会发现开发者做了好多处理畸变的事情。最后得到两组特征点的位置,然后通过这两组点得到基础矩阵。接着通过基础矩阵剔除一些不好的点。
之后开始设置掩码矩阵setMask()
int n_max_cnt = MAX_CNT - static_cast(forw_pts.size());
算出还缺多少个特征点,然后通过goodFeaturesToTrack()补上剩余的。这里面mask起了一定的作用。然后就是:
addPoints();
prev_img = forw_img;
prev_pts = forw_pts;
将新找到的特征点加上,然后把当前帧给上一发布帧,当前点给上一发布点。此时通过判断是否发布的函数完成。
当然如果不要发布的话也必须执行的:
cur_img = forw_img;
cur_pts = forw_pts;
readImage()函数结束。