《SLAM十四讲》Ch7 VO1 对PnP结果BA优化的一点改进

bundleAdjustmentG2O( )函数实现

void bundleAdjustmentG2O(
    const VecVector3d &points_3d,
    const VecVector2d &points_2d,
    const Mat &K,
    Sophus::SE3d &pose)
{
  // 构建图优化,先设定g2o
  typedef g2o::BlockSolver<g2o::BlockSolverTraits<6, 3>> BlockSolverType;           // pose is 6, landmark is 3
  typedef g2o::LinearSolverDense<BlockSolverType::PoseMatrixType> LinearSolverType; // 线性求解器类型
  // 梯度下降方法,可以从GN, LM, DogLeg 中选
  auto solver = new g2o::OptimizationAlgorithmGaussNewton(
      g2o::make_unique<BlockSolverType>(g2o::make_unique<LinearSolverType>()));
  g2o::SparseOptimizer optimizer; // 图模型
  optimizer.setAlgorithm(solver); // 设置求解器
  optimizer.setVerbose(true);     // 打开调试输出

  // vertex
  VertexPose *vertex_pose = new VertexPose(); // camera vertex_pose
  vertex_pose->setId(0);
  vertex_pose->setEstimate(Sophus::SE3d());
  optimizer.addVertex(vertex_pose);

  // K
  Eigen::Matrix3d K_eigen;
  K_eigen << K.at<double>(0, 0), K.at<double>(0, 1), K.at<double>(0, 2),
      K.at<double>(1, 0), K.at<double>(1, 1), K.at<double>(1, 2),
      K.at<double>(2, 0), K.at<double>(2, 1), K.at<double>(2, 2);

  // edges
  int index = 1;
  for (size_t i = 0; i < points_2d.size(); ++i)
  {
    auto p2d = points_2d[i];
    auto p3d = points_3d[i];
    EdgeProjection *edge = new EdgeProjection(p3d, K_eigen);
    edge->setId(index);
    edge->setVertex(0, vertex_pose);
    edge->setMeasurement(p2d);
    edge->setInformation(Eigen::Matrix2d::Identity());
    optimizer.addEdge(edge);
    index++;
  }

  chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
  optimizer.setVerbose(true);
  optimizer.initializeOptimization();
  optimizer.optimize(10);
  chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
  chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1);
  cout << "optimization costs time: " << time_used.count() << " seconds." << endl;
  cout << "pose estimated by g2o =\n"
       << vertex_pose->estimate().matrix() << endl;
  pose = vertex_pose->estimate();
}

主要步骤:
1、构建图优化,设定g2o
2、添加顶点vertex
3、添加边edges
4、optimizer.optimize( )优化

注意到设置顶点时:

vertex_pose->setEstimate(Sophus::SE3d());

这里初始值的设定“Sophus::SE3d( )”不是待优化的结果

更改如下:

Matrix3d R_eigen;
  for(int i=0;i<3;++i)
  {
    for(int j=0;j<3;++j)
    {
      R_eigen(i,j)=R.at<double>(i,j);
    }
  }  
  Vector3d t_eigen;
  for(int i=0;i<3;++i)
  {
    t_eigen<<t.at<double>(i,0);
  }

	cout << "calling bundle adjustment by g2o" << endl;
  Sophus::SE3d pose_g2o(R_eigen,t_eigen);

	vertex_pose->setEstimate(pose);

更改后显著提高优化速度,前后对比如下:

更改前:在这里插入图片描述
optimization cost time为0.001844386s
g2o BA优化的时间为0.002059048s
更改后:
在这里插入图片描述
optimization cost time为0.000413748s
g2o BA优化的时间为0.000505369s
速度提高约5倍左右

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《视觉SLAM十四》的第七章主要介绍了ORB特征的手写实现。ORB特征是一种基于FAST角点检测和BRIEF描述子的特征提取方法,它在计算效率和鲁棒性上表现出色,被广泛应用于视觉SLAM中。 第七章还介绍了ORB特征的主要步骤,包括角点检测、特征描述子计算和特征匹配。在角点检测中,通过FAST算法检测图像中的角点位置。然后,利用BRIEF描述子计算对应角点位置的特征描述子。最后,通过特征匹配算法将当前帧的ORB特征与地图中的ORB特征进行匹配,从而实现相机的位姿估计和地图构建。 除了手写ORB特征的实现,第七章还介绍了ORB-SLAM系统的整体框架和关键技术。该系统结合了特征点法和直接法,实现了在无GPS和IMU信息的情况下进行实时的视觉SLAM。通过利用ORB特征进行初始化、追踪和建图,ORB-SLAM系统在室内和室外环境下都取得了良好的效果。 总而言之,视觉SLAM的第七章《视觉SLAM十四》介绍了手写ORB特征的实现方法,并介绍了ORB-SLAM系统的整体框架和关键技术。这些内容对于理解和应用视觉SLAM具有重要意义。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [视觉SLAM十四——ch7](https://blog.csdn.net/weixin_58021155/article/details/123496372)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [《视觉slam十四》学习笔记——ch7实践部分 比较opencv库下的ORB特征的提取和手写ORB的区别](https://blog.csdn.net/weixin_70026476/article/details/127415318)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值