为什么检查视差

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 估计器之检查视差的更多相关文章

  1. VINS 估计器之结构初始化

    为什么要初始化 非线性VINS估计器的性能对于初始的速度,尺度,重力向量,空间点3D位置,以及外参等非常敏感.在很多场合中,能做到相机和IMU即插即用,线上自动校准与初始化,将会给用户带来极大的方便性 ...

  2. VINS 估计器之优化与边缘化

    VINS的优化除了添加了投影残差,回环检测残差,还有IMU的残差,边缘化产生的先验信息残差等.有些比较难理解,可参考此博客和知乎回答. void Estimator::optimization() { ...

  3. OpenCV stereo matching 代码 matlab实现视差显示

    转载请注明出处:http://blog.csdn.net/wangyaninglm/article/details/44151213, 来自:shiter编写程序的艺术 基础知识 计算机视觉是一门研究 ...

  4. 学习OpenCV双目测距原理及常见问题解答

    学习OpenCV双目测距原理及常见问题解答 转自博客:https://blog.csdn.net/angle_cal/article/details/50800775 一. 整体思路和问题转化.  图 ...

  5. 【转】破解Source Insight 3.5.0072过程 附:安装软件+注册机

    转载地址:http://blog.csdn.net/qs_hud/article/details/8884867 注册机及软件下载地址:http://download.csdn.net/detail/ ...

  6. 1025WHERE执行顺序以及MySQL查询优化器

    转自http://blog.csdn.net/zhanyan_x/article/details/25294539 -- WHERE执行顺序-- 过滤比较多的放在前面,然后更加容易匹配,从左到右进行执 ...

  7. 立体视觉-opencv中立体匹配相关代码

    三种匹配算法比较 BM算法: 该算法代码: view plaincopy to clipboardprint? CvStereoBMState *BMState = cvCreateStereoBMS ...

  8. TCP协议学习总结(下)

    在前两边TCP学习总结中,也大概地学习了TCP的整个流程,但许多细节中的细节并没有详细学习,例如超时重传问题,每次瓶颈回归慢启动效率问题以及最大窗口限制问题等.本学习篇章最要针对这些细节中的细节进行学 ...

  9. jarvis OJ WEB题目writeup

    0x00前言 发现一个很好的ctf平台,题目感觉很有趣,学习了一波并记录一下 https://www.jarvisoj.com 0x01 Port51 题目要求是用51端口去访问该网页,注意下,要用具 ...

随机推荐

  1. mqtt异步publish方法

    Python基于mqtt异步编程主要用到asyncio及第三方库hbmqtt,这里主要介绍mqtt的异步发布及遇到的一些问题. hbmqtt安装很简单,pip hbmqtt install. mqtt ...

  2. linux小白成长之路7————Docker安装mysql

    [内容指引] 从Docker检索mysql镜像: Mysql Docker镜像下载: 查看本地镜像列表: 设置Mysql的Docker镜像开机自动运行: 常用Docker指令及参数: 1.从Docke ...

  3. input输入框限制输入正整数、小数、字母、文字

    有的时候需要限制input的输入格式: 例如,输入大于0的正整数 <input onkeyup="if(this.value.length==1){this.value=this.va ...

  4. Java基础学习笔记五 Java基础语法之面向对象

    面向对象 理解什么是面向过程.面向对象 面向过程与面向对象都是我们编程中,编写程序的一种思维方式.面向过程的程序设计方式,是遇到一件事时,思考“我该怎么做”,然后一步步实现的过程.例如:公司打扫卫生( ...

  5. java虚拟机的内存分配与回收机制

    分为4个方面来介绍内存分配与回收,分别是内存是如何分配的.哪些内存需要回收.在什么情况下执行回收.如何监控和优化GC机制. java GC(Garbage Collction)垃圾回收机制,是java ...

  6. PYTHON 词云

    #!/usr/bin/env python # -*- coding:utf-8 -*- import matplotlib.pyplot as plt from wordcloud import W ...

  7. 《招一个靠谱的移动开发》iOS面试题及详解(上篇)

    以下问题主要用于技术的总结与回顾 主要问题总结 单例的写法.在单利中创建数组应该注意些什么. NSString 的时候用copy和strong的区别. 多线程.特别是NSOperation 和 GCD ...

  8. Oracle 使用pl/sql将表中的数据读出到文件中

    (1)在服务器上创建文件路径及文件 [oracle@redhat errormsg]$ touch test01.txt (2)在数据库中创建路径及授权 (3)创建存储过程 CREATE OR REP ...

  9. 常用的汇编指令 movs stos

    movsb   把寄存机esi所存的地址的数据以字节复制到edi movsw  把寄存机esi所存的地址的数据以word复制到edi movsd   把寄存机esi所存的地址的数据以dword复制到e ...

  10. 分贝块---dBblock

    分贝,用英语来表达的话,是decibel,是量度两个相同单位之数量比例的计量单位,主要用于度量声音强度,常用dB表示. 块,block,在百度百科中,指数据库中的最小存储和处理单位,包含块本身的头信息 ...