VINS 估计器之检查视差
为什么检查视差
VINS里为了控制优化计算量,在实时情况下,只对当前帧之前某一部分帧进行优化,而不是全部历史帧。局部优化帧的数量就是窗口大小。为了维持窗口大小,需要去除旧的帧添加新的帧,也就是边缘化 Marginalization。到底是删去最旧的帧(MARGIN_OLD)还是删去刚刚进来窗口倒数第二帧(MARGIN_SECOND_NEW),就需要对当前帧与之前帧进行视差比较,如果是当前帧变化很小,就会删去倒数第二帧,如果变化很大,就删去最旧的帧。
VINS 里把特征点管理和检查视差放在了同一个函数里,先添加特征点,再进行视差检查。所以今天主要看的是这个函数:
bool FeatureManager::addFeatureCheckParallax(int frame_count, const map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> &image, double td);
在哪里需要检查视差
视差检查函数使用位置是在processImage内,也就是当estimator得到一帧图片的信息后,就会立马进行处理,首先第一步就是添加图片内的特征点以及检查视差。
void Estimator::processImage(const map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> &image, const std_msgs::Header &header)
{
ROS_DEBUG("new image coming ------------------------------------------");
ROS_DEBUG("Adding feature points %lu", image.size());
if (f_manager.addFeatureCheckParallax(frame_count, image, td))
marginalization_flag = MARGIN_OLD;
else
marginalization_flag = MARGIN_SECOND_NEW;
...
如何检查视差
分析函数内代码
bool FeatureManager::addFeatureCheckParallax(int frame_count, const map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> &image, double td)
{
ROS_DEBUG("input feature: %d", (int)image.size());
ROS_DEBUG("num of feature: %d", getFeatureCount());
//所有特征点视差总和
double parallax_sum = 0;
// 满足某些条件的特征点个数
int parallax_num = 0;
//被跟踪点的个数
last_track_num = 0;
for (auto &id_pts : image)
{
//特征点管理器,存储特征点格式:首先按照特征点ID,一个一个存储,每个ID会包含其在不同帧上的位置
FeaturePerFrame f_per_fra(id_pts.second[0].second, td);
int feature_id = id_pts.first;
// find_if 函数,找到一个interator使第三个仿函数参数为真
auto it = find_if(feature.begin(), feature.end(), [feature_id](const FeaturePerId &it)
{
return it.feature_id == feature_id;
} );
if (it == feature.end())
{
//如果没有找到此ID,就在管理器中增加此特征点
feature.push_back(FeaturePerId(feature_id, frame_count));
feature.back().feature_per_frame.push_back(f_per_fra);
}
else if (it->feature_id == feature_id)
{
//如果找到了相同ID特征点,就在其FeaturePerFrame内增加此特征点在此帧的位置以及其他信息,然后增加last_track_num,说明此帧有多少个相同特征点被跟踪到
it->feature_per_frame.push_back(f_per_fra);
last_track_num++;
}
}
if (frame_count < 2 || last_track_num < 20)
return true;
for (auto &it_per_id : feature)
{
//计算能被当前帧和其前两帧共同看到的特征点视差
if (it_per_id.start_frame <= frame_count - 2 &&
it_per_id.start_frame + int(it_per_id.feature_per_frame.size()) - 1 >= frame_count - 1)
{
parallax_sum += compensatedParallax2(it_per_id, frame_count);
parallax_num++;
}
}
if (parallax_num == 0)
{
return true;
}
else
{
ROS_DEBUG("parallax_sum: %lf, parallax_num: %d", parallax_sum, parallax_num);
ROS_DEBUG("current parallax: %lf", parallax_sum / parallax_num * FOCAL_LENGTH);
return parallax_sum / parallax_num >= MIN_PARALLAX;
}
}
每个特征点视差计算如下:
double FeatureManager::compensatedParallax2(const FeaturePerId &it_per_id, int frame_count)
{
//check the second last frame is keyframe or not
//parallax betwwen second last frame and third last frame
const FeaturePerFrame &frame_i = it_per_id.feature_per_frame[frame_count - 2 - it_per_id.start_frame];
const FeaturePerFrame &frame_j = it_per_id.feature_per_frame[frame_count - 1 - it_per_id.start_frame];
double ans = 0;
Vector3d p_j = frame_j.point;
double u_j = p_j(0);
double v_j = p_j(1);
Vector3d p_i = frame_i.point;
Vector3d p_i_comp;
p_i_comp = p_i;
double dep_i = p_i(2);
double u_i = p_i(0) / dep_i;
double v_i = p_i(1) / dep_i;
double du = u_i - u_j, dv = v_i - v_j;
// 这一步与上一步重复,不知道必要性在哪里,目前没有必须性
double dep_i_comp = p_i_comp(2);
double u_i_comp = p_i_comp(0) / dep_i_comp;
double v_i_comp = p_i_comp(1) / dep_i_comp;
double du_comp = u_i_comp - u_j, dv_comp = v_i_comp - v_j;
//其实就是算斜边大小
ans = max(ans, sqrt(min(du * du + dv * dv, du_comp * du_comp + dv_comp * dv_comp)));
return ans;
}
VINS 估计器之检查视差的更多相关文章
- VINS 估计器之结构初始化
为什么要初始化 非线性VINS估计器的性能对于初始的速度,尺度,重力向量,空间点3D位置,以及外参等非常敏感.在很多场合中,能做到相机和IMU即插即用,线上自动校准与初始化,将会给用户带来极大的方便性 ...
- VINS 估计器之优化与边缘化
VINS的优化除了添加了投影残差,回环检测残差,还有IMU的残差,边缘化产生的先验信息残差等.有些比较难理解,可参考此博客和知乎回答. void Estimator::optimization() { ...
- OpenCV stereo matching 代码 matlab实现视差显示
转载请注明出处:http://blog.csdn.net/wangyaninglm/article/details/44151213, 来自:shiter编写程序的艺术 基础知识 计算机视觉是一门研究 ...
- 学习OpenCV双目测距原理及常见问题解答
学习OpenCV双目测距原理及常见问题解答 转自博客:https://blog.csdn.net/angle_cal/article/details/50800775 一. 整体思路和问题转化. 图 ...
- 【转】破解Source Insight 3.5.0072过程 附:安装软件+注册机
转载地址:http://blog.csdn.net/qs_hud/article/details/8884867 注册机及软件下载地址:http://download.csdn.net/detail/ ...
- 1025WHERE执行顺序以及MySQL查询优化器
转自http://blog.csdn.net/zhanyan_x/article/details/25294539 -- WHERE执行顺序-- 过滤比较多的放在前面,然后更加容易匹配,从左到右进行执 ...
- 立体视觉-opencv中立体匹配相关代码
三种匹配算法比较 BM算法: 该算法代码: view plaincopy to clipboardprint? CvStereoBMState *BMState = cvCreateStereoBMS ...
- TCP协议学习总结(下)
在前两边TCP学习总结中,也大概地学习了TCP的整个流程,但许多细节中的细节并没有详细学习,例如超时重传问题,每次瓶颈回归慢启动效率问题以及最大窗口限制问题等.本学习篇章最要针对这些细节中的细节进行学 ...
- jarvis OJ WEB题目writeup
0x00前言 发现一个很好的ctf平台,题目感觉很有趣,学习了一波并记录一下 https://www.jarvisoj.com 0x01 Port51 题目要求是用51端口去访问该网页,注意下,要用具 ...
随机推荐
- 解决图片裁剪com.android.camera.action.CROP和intent.putExtra("return-data", true);
最近在做一个图片上传,在上传之前需要对照片进行裁剪,遇到一个坑,在别的手机上运行都正常,在小米手机上却遇见一个问题,选中图片无法裁剪,直接闪退,目前已解决!之前出过问题的地方会标红 //选择图片 pr ...
- Konckout第六个实例:自定义组件 -- 发表评论
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- (Matlab)GPU计算及CPU计算能力的比较
%%首先以200*200的矩阵做加减乘除 做比较 t = zeros(1,100); A = rand(200,200);B = rand(200,200);C = rand(200,200); fo ...
- sql模糊查询效率
在数据库量比较大的时候通常有一些查询,例如查询文本类型的数据,存储量大,用like进行模糊查询效率实在太低 select * from stdcontent where content like ' ...
- 对lua表中数据按一定格式处理,循环
function putStartCard(handCard) function dataDeal(array,a,b,c) cclog("进入datadeal=============== ...
- HTML5文件操作API
HTML5文件操作API 一.文件操作API 在之前我们操作本地文件都是使用flash.silverlight或者第三方的activeX插件等技术,由于使用了这些技术后就很难进行跨平台.或 ...
- Count on a tree
bzoj 2588: Spoj 10628. Count on a tree http://www.lydsy.com/JudgeOnline/problem.php?id=2588 Descrip ...
- Raid5两块硬盘掉线可以恢复数据吗_raid数据恢复案例分享
本案例中发生故障的存储类型是HP P2000,虚拟化平台为vmware exsi,共有10块硬盘组成raid5(硬盘容量为1t,其中6号盘是热备盘),由于某些故障导致阵列中两块硬盘亮黄灯掉线,硬盘无法 ...
- jsp文件调用本地文件的方法(Tomcat server.xml 设置虚拟目录)
JSP文件: <video id="my-video" class="video-js" controls preload="auto" ...
- python之路--day15--常用模块之logging模块
常用模块 1 logging模块 日志级别:Noset (不设置) Debug---(调试信息)----也可用10表示 Info--(消息信息)----也可用20表示 Warning---(警告信息) ...