Ceres计算Bundle Adjustment

概念

        Bundle Adjustment,中文名称是光束法平差,经典的BA目的是优化相机的pose和landmark,其在SfM和SLAM 领域中扮演者重要角色。开发Ceres的主要原因之一是需要解决大规模的Bundle Adjustment. 目前bundle adjustment 优化框架最为代表的是ceres solver和g2o ,据说ceres的命名是天文学家Piazzi闲暇无事的时候观测一颗没有观测到的星星,最后用least squares算出了这个小行星的轨道,故将这个小行星命名为ceres。

Bundle Adjustment 定义

Bundle Adjustment的目标是找到使重投影误差最小的3D点位置和相机参数。这个优化问题通常被描述为非线性最小二乘法问题,要最小化的目标函数即为测得图像中特征点位置和相机成像平面上的对应的投影之间的差的平方。ceres例程使用了BAL数据集:Bundle Adjustment in the Large  .ceres 例程是examples文件夹中的 simple_bundle_adjuster.cc 。

观察值:像素点坐标

优化变量:相机pose 、相机内参、lanemark概念概念

 ceres 代码解读

// Templated pinhole camera model for used with Ceres.  The camera is
// parameterized using 9 parameters: 3 for rotation, 3 for translation, 1 for
// focal length and 2 for radial distortion. The principal point is not modeled
// (i.e. it is assumed be located at the image center).
struct SnavelyReprojectionError {
  SnavelyReprojectionError(double observed_x, double observed_y)
      : observed_x(observed_x), observed_y(observed_y) {}

  template <typename T>
  bool operator()(const T* const camera,
                  const T* const point,
                  T* residuals) const {
    // camera[0,1,2] are the angle-axis rotation.
    T p[3];
    ceres::AngleAxisRotatePoint(camera, point, p);

    // camera[3,4,5] are the translation.
    p[0] += camera[3];
    p[1] += camera[4];
    p[2] += camera[5];

    // Compute the center of distortion. The sign change comes from
    // the camera model that Noah Snavely's Bundler assumes, whereby
    // the camera coordinate system has a negative z axis.
    T xp = -p[0] / p[2];
    T yp = -p[1] / p[2];

    // Apply second and fourth order radial distortion.
    // k1 k2
### OpenMVG中的Bundle Adjustment功能实现 OpenMVG(Open Multiple View Geometry)是一个开源的计算机视觉库,专注于多视图几何问题的研究和解决。其中,Bundle Adjustment 是其核心模块之一,用于优化相机参数和三维点的位置。 #### Bundle Adjustment 的定义与目标 Bundle Adjustment 是一种全局优化方法,旨在通过最小化重投影误差来调整相机姿态、内部参数以及场景中三维点的位置[^1]。具体来说,它试图找到一组最优的相机参数 \( \{R_i, T_i\} \) 和三维点坐标 \( X_j \),使得这些参数能够最大程度上解释图像中标记点的实际位置。这一过程通常被描述为如下非线性最小二乘问题: \[ E(R,T,X) = \sum_{i,j} w_{ij}\|p_{ij} - \pi(K,R,T,X)\|^2 \] 其中: - \( p_{ij} \) 表示第 \( j \) 个三维点在第 \( i \) 台摄像机下的观测二维像素坐标; - \( K \) 是相机的内参矩阵; - \( R_i, T_i \) 分别表示第 \( i \) 台摄像机的姿态旋转和平移向量; - \( X_j \) 表示第 \( j \) 个三维点的世界坐标; - \( \pi(\cdot) \) 定义了从世界坐标到图像坐标的投影函数; - \( w_{ij} \) 是权重因子,用来衡量该对应关系的可靠性。 为了简化上述复杂的非线性函数优化问题,常用的方法包括高斯牛顿法(Gauss-Newton)[^2]、Levenberg-Marquardt算法等迭代技术来进行求解。 #### OpenMVG 中的具体实现方式 在 OpenMVG 库里,bundle adjustment 功能主要依赖于 Ceres Solver 这一强大的数值计算工具完成实际运算操作。以下是其实现的关键部分概述: 1. **数据准备**: 需要输入初始估计值,包括每台摄像机的内外部参数初值以及初步重建得到的所有稀疏3D特征点集合。 2. **构建残差模型**: 对应每一个观察到的匹配对\( (u,v)_k \), 建立相应的误差项表达式作为待优化的目标函数的一部分。 3. **设置并调用Ceres solver**: 将所有变量(即各摄像头参数及空间点坐标)标记可变与否;指定损失函数形式;最后启动solver执行最优化流程直至收敛为止。 下面给出一段简单的伪代码展示如何利用openmvg api 来配置一次完整的BA任务: ```cpp // Initialize BA problem with cameras & points. auto baProblem = std::make_shared<openMVG::sfm::SfM_Data>(); baProblem->SetIntrinsics(intrinsicParams); for(auto cam : allCameras){ baProblem->AddPose(cam.id(),cam.R(),cam.t()); } for(auto pt3d : reconstructedPoints){ baProblem->AddStructure(pt3d.id(),pt3d.coord()); } // Configure options for ceres based optimization process. ceres::Solver::Options options; options.linear_solver_type = ceres::SPARSE_SCHUR; // Choose appropriate linear system solving strategy. // Perform bundle adjustment via calling openmvg's wrapper around ceres library functions. ceres::Problem problem; BuildReprojectionResiduals(baProblem,&problem); ceres::Solver::Summary summary; ceres::Solve(options,&problem,&summary); std::cout << "Final Report:\n" << summary.FullReport() << "\n"; ``` 此段程序片段展示了怎样把已知信息组装成适合传递给底层求解器的形式,并最终获得经过精细校准后的结果集。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值