2.在代码中分析VINS---图解特征点管理(feature_manager.h)

这篇博客主要讲解VINS中特征点的管理,它主要涉及3个类,位于feature_manager.h中的FeaturePerFrame、FeaturePerId、FeatureManager

1.特征点管理示意图

在这里插入图片描述
上图中有两个路标特征点P1,P2,分别被帧1~2,2~4观测到。

2.FeaturePerId

就特征点P1来说,它被两个帧观测到,第一次观测到P1的帧为frame1,即start_frame=1,最后一次观测到P1的帧为frame2,即endframe()=2,并把start_frame~endframe() 对应帧的属性存储起来,对应的示意图如下:
在这里插入图片描述
上述对应的代码为:

class FeaturePerId//管理一个特征点
{
  public:
    const int feature_id;//特征点id
    int start_frame;//第一次出现该特征点的帧号
    vector<FeaturePerFrame> feature_per_frame;//管理对应帧的属性
    int used_num;//出现的次数
    double estimated_depth;//逆深度
    int solve_flag; // 0 haven't solve yet; 1 solve succ; 2 solve fail;该特征点的状态,是否被三角化
    Vector3d gt_p;
    FeaturePerId(int _feature_id, int _start_frame)//以feature_id为索引,并保存了出现该角点的第一帧的id
        : feature_id(_feature_id), start_frame(_start_frame),
          used_num(0), estimated_depth(-1.0), solve_flag(0)
    {
    }
    int endFrame();//得到该特征点最后一次跟踪到的帧号
};

3.FeaturePerFrame

在上面提到对应帧的属性这个概念,它指的是空间特征点P1映射到frame1或frame2上对应的图像坐标、特征点的跟踪速度、空间坐标等属性都封装到类FeaturePerFrame中,对应的示意图如下:
在这里插入图片描述
它对应的代码为:

class FeaturePerFrame//一个特征点的属性
{
  public:
    FeaturePerFrame(const Eigen::Matrix<double, 7, 1> &_point, double td)
    {
        point.x() = _point(0);
        point.y() = _point(1);
        point.z() = _point(2);
        uv.x() = _point(3);
        uv.y() = _point(4);
        velocity.x() = _point(5); 
        velocity.y() = _point(6); 
        cur_td = td;
    }
    double cur_td;//imu-camera的不同步时的相差时间
    Vector3d point;//特征点空间坐标
    Vector2d uv;//特征点映射到该帧上的图像坐标
    Vector2d velocity;//特征点的跟踪速度
    double z;
    bool is_used;
    double parallax;
    MatrixXd A;
    VectorXd b;
    double dep_gradient;
};

4.FeaturePerId

上述是对一个特征点讨论的,如果是对所有的特征点进行讨论的话,则可以构建list容器,存储每一个特征点,对应的示意图如下:
在这里插入图片描述
对应代码为:

class FeatureManager//管理所有i特征点
{
list<FeaturePerId> feature;//存储每一个特征点,及其对应的每帧的属性
}

5.说明

前面只是对特征点的管理做了一个最简单的概述,其实真实特征点的管理很复杂,还得考虑特征点的三角化、两帧之间的视差处理等等。

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
VINS-Mono的Marginalization.cpp文件的滑窗代码如下所示: ``` for (int j = 0; j < _pre_integration_vec.size(); j++) { if (_pre_integration_vec[j]->sum_dt > _repropagation_threshold) { if (j == 0) { continue; } delete _pre_integration_vec[j - 1]; _pre_integration_vec.erase(_pre_integration_vec.begin(), _pre_integration_vec.begin() + j - 1); j = 0; } } if (_pre_integration_vec.size() > 2) { // sort imu measurements sort(_pre_integration_vec.begin(), _pre_integration_vec.end(), [](const IntegrationBase *p1, const IntegrationBase *p2) { return p1->sum_dt < p2->sum_dt; }); // remove the oldest pre-integration IntegrationBase *pre_integrations = _pre_integration_vec.front(); _pre_integration_vec.pop_front(); delete pre_integrations; // create new marginalization factor MarginalizationFactor *marginalization_factor = new MarginalizationFactor(_pre_integration_vec.front(), i); _marginalization_factors.push_back(marginalization_factor); // update Jacobian and residual for (int j = 0; j < _pre_integration_vec.size(); j++) { if (j != 0) { _pre_integration_vec[j]->repropagate( _pre_integration_vec[j - 1]->delta_q, _pre_integration_vec[j - 1]->delta_v, _pre_integration_vec[j - 1]->delta_p); } _pre_integration_vec[j]->compute_jacobian(); marginalization_factor->add_information( _pre_integration_vec[j]->jacobian, _pre_integration_vec[j]->residual); } } ``` 其,变量`_pre_integration_vec`是一个存储IMU预积分量的vector,而`_marginalization_factors`存储的是边缘化因子。该代码实现了Marginalization Factor的滑窗策略,根据预积分时间的累积和来判断是否需要删除旧的预积分量,然后创建新的边缘化因子,并更新其Jacobian矩阵和残差。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值