bundle adjustment原理(1)

本文深入探讨了光束平差(bundle adjustment)的数学原理,这是三维重建中的关键步骤之一。通过逐步解析单个和多个摄像机场景下的重投影误差最小化过程,介绍了如何使用L-M算法进行优化,并提供了MATLAB代码示例来计算误差函数的偏导数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

那些光束平差的工具,比如SBA、SSBA之类的虽然好,然而例子和教程都不够多且不够详细,让初学者难以上手。

要传入的参数虽然有解释,然而却也不是十分清楚其含义,具体要怎么生成,生成为什么形式。

我在折腾了一段时间后也还是没成功,逼得我自己找这方面的资料学习,想要更了解bundle adjustment的原理。

想着干脆自己写一个简单的bundle框架练练手,就算写不成也将有助于让这些工具正常工作起来。

 

三维重建的最后一步是光束平差,又称bundle adjustment,本文介绍一下bundle adjustment的数学原理。

主要是参考 https://www.coursera.org/learn/robotics-perception/home/welcome 第4周里头的内容。

本文做一些数学上的推导以及将资料中的各种公式的含义细化。

自己在推导过程中发现了上述课程ppt中的一些细节地方的公式有错。

2016-09-07 10:24:33

 

除了上面的资料外,还参考了另一篇文献 “SBA: A Software Package for Generic Sparse Bundle Adjustment”,在bundle adjustment的wiki下以及MATLAB R2016a自带的bundleAdjustment函数中都参考了这篇文献。这篇文献和上述课程ppt中的变量设置略有不同,但大体框架是一样的。

 

整个 bundle adjustment 的目标是重投影误差最小,所以可以分为两个部分:

1,将某个误差函数的值最小化。这是一个最优化问题,用的是L-M算法。我已经写了一篇L-M算法的博客。

2,将重投影误差的误差函数的具体表达式写出来,套到上面的L-M算法里头去。

假设读者已经有一些最优化的知识。

 

先从只有1个点、1个相机讲起:

 

 

2个摄像机1个点的情况:

 

2个摄像机2个点的情况:

 

假如有3个摄像机,4个点,则J的大致情形如下,里头的含义模仿上面很容易搞清楚:

 

对于列来讲,前面3列对应着3个摄像机的变量,后面4列对应着4个点的变量。

 

那么函数f对变量p和x的偏导怎么求?只有用MATLAB的符号推导才能搞出来,手算非常容易出错

MATLAB代码如下:

被调用的函数sym_mat:

function rtn = sym_mat(x,m,n)
% 生成符号矩阵,第一个参数是一个符号,后面两个参数是符号矩阵的尺寸
% 如果你想生成符号矩阵[x11 x12; x21 x22]只需输入sym_mat(x,2,2)
% 但事先要先声明符号x,用syms x
% 如果你只需要生成一维矩阵,sym_mat会生成一个列向量,如sym_mat(x,2);
% 例子:
% syms x;
% A = sym_mat(x,3,4) 返回一个3 x 4的符号矩阵

if nargin == 2
    for i=1:m
        rtn(i)=sym([inputname(1),num2str(i)]);
    end    
    rtn = rtn.';
elseif nargin == 3
    for i = 1:m
        for j = 1:n
            rtn(i,j) = sym([inputname(1),num2str(i),num2str(j)]);
        end
    end
end

符号推导部分:

clear all;clc;close all;

syms P;
P = sym_mat(P,3,4);
P(3,4) = 1
P_var = symvar(P)

syms X;
X = [sym_mat(X,3);
    1]
X_var = symvar(X)

uvw = P*X;

u = uvw(1,:);
v = uvw(2,:);
w = uvw(3,:);

f = ...
    [u/w;
     v/w];

f_P = jacobian(f,P_var)
f_X = jacobian(f,X_var)

J = [f_P f_X]
sym_in_J = symvar(J)

f_P 代表函数 f 对 P  求导,得到 2 x 11 的矩阵

f_X 代表函数 f 对 X 求导,得到 2 x 3 的矩阵

结果很复杂,就不贴出来了。

具体计算矩阵J的值的时候,把变量替换成相应的值就可以了,MATLAB中有subs函数,如果用c++写,

则要自己写一个函数,把值传进去算矩阵J的值。

 

对于多点多相机的矩阵J,计算不同部分的 f_P 和 f_X,然后把它们组装成一个大的矩阵即可。

先写到这里。。。

2016年9月9日21:50:17

转载于:https://www.cnblogs.com/shepherd2015/p/5848430.html

<think>嗯,我现在需要理解什么是Bundle Adjustment(BA)以及它在计算机视觉中的优化技术。首先,我听说过BA在三维重建和SLAM(同步定位与地图构建)中很重要,但具体细节不是很清楚。让我先回忆一下之前学过的相关知识。 BA可能和相机参数、三维点坐标的优化有关吧?记得在视觉SLAM中,通过多张图像中的特征点匹配来估计相机的位置和场景结构,但可能会有累积误差,这时候可能需要BA来优化这些估计。那BA具体是怎么工作的呢?是不是一种优化算法,比如最小化重投影误差? 重投影误差应该是指将三维点投影到图像平面上的预测位置与实际检测到的特征点位置之间的差异。BA的目标就是调整相机参数和三维点的位置,使得所有点的重投影误差总和最小。这应该是一个非线性最小二乘问题,可能需要用高斯-牛顿法或者列文伯格-马夸尔特算法来求解。 那具体实现时,需要考虑哪些参数呢?每个相机的位姿(旋转和平移)、内参(焦距、主点等),还有每个三维点的坐标。这些参数都是需要优化的变量。当变量很多的时候,计算量会很大,这时候可能需要利用稀疏性来加速计算,比如使用稀疏矩阵的分解方法。 我还记得BA通常是在SFM(结构光运动恢复结构)或者SLAM的后端优化中使用。例如,在ORB-SLAM中,局部建图和闭环检测时都会用到BA来优化地图和相机轨迹。这应该能提高整个系统的精度,减少漂移误差。 另外,BA的实现可能涉及到雅可比矩阵的计算,因为优化算法需要知道每个参数对误差的影响程度。雅可比矩阵可能会很大,但由于每个观测只涉及少数参数(比如一个三维点和两个相机位姿),所以矩阵应该是稀疏的。利用这种稀疏结构可以显著提高计算效率。 不过,我有点不确定BA的具体数学表达是怎样的。比如,重投影误差是如何公式化的?假设有一个三维点$P_j$在相机位姿$T_i$下的投影是$p_{ij}$,而实际检测到的点是$q_{ij}$,那么误差应该是$||p_{ij} - q_{ij}||^2$。所有这样的误差加起来就是目标函数,需要最小化这个总误差。 BA的优化变量包括所有的相机位姿参数和三维点坐标。如果用李代数表示相机的旋转,可能会更方便计算导数。此外,可能还要处理不同的参数化方式,比如使用四元数还是旋转矩阵,或者是否固定某些参数(比如内参是否已知)。 实现BA的时候,可能需要使用现有的库,比如ceres-solver或者g2o,这些库提供了非线性优化的框架,用户只需要定义误差函数和雅可比矩阵的计算方式。这样就能高效地处理大规模的问题。 不过,关于稀疏BA的实现,可能还有更高效的方法,比如使用舒尔补来分解问题,先求解相机参数,再求解三维点参数,或者交替优化。这可能会减少计算量,因为三维点的数量通常远多于相机位姿的数量,分解后的问题规模更小。 另外,增量式BA可能也是一种优化策略,当新增相机或三维点时,只对相关部分进行优化,而不是重新计算全部参数。这在实时系统中可能很有用,比如SLAM的在线建图过程。 但是,BA的计算复杂度很高,当数据量很大时,可能需要分布式计算或者使用GPU加速。这在实际应用中是一个挑战,尤其是对于需要实时处理的系统。 总结一下,Bundle Adjustment是一个通过优化相机参数和三维点坐标来最小化重投影误差的过程,属于非线性最小二乘问题,常用高斯-牛顿或LM算法求解,并利用稀疏性加速计算。在实现时需要考虑参数化、雅可比矩阵计算、稀疏求解以及高效优化库的使用。</think>### Bundle Adjustment 概念与实现方法 Bundle Adjustment(光束法平差)是计算机视觉中用于同时优化三维点坐标和相机参数的优化技术,其核心目标是最小化**重投影误差**,即三维点在图像平面上的投影位置与实际观测特征点位置之间的差异[^1]。以下是其关键点: --- #### **数学原理** 1. **重投影误差定义** 对于三维点$P_j$在相机$i$的位姿$T_i$下投影到图像坐标为$p_{ij}$,而实际观测值为$q_{ij}$,则误差为: $$ e_{ij} = ||\pi(T_i, P_j) - q_{ij}||^2 $$ 其中$\pi(\cdot)$为投影函数,包含相机内参(如焦距$f$、主点$(c_x, c_y)$)和畸变参数。 2. **目标函数** 最小化所有观测的总误差: $$ \min_{\{T_i\}, \{P_j\}} \sum_{i,j} \rho\left( e_{ij}^\top \Sigma_{ij}^{-1} e_{ij} \right) $$ 其中$\rho$为鲁棒核函数(如Huber函数),$\Sigma_{ij}$为协方差矩阵。 --- #### **实现步骤** 1. **参数化** - 相机位姿:使用李代数$\mathfrak{se}(3)$或四元数+平移向量表示,避免万向节锁。 - 三维点:齐次坐标或非齐次坐标。 - 内参:可固定(已知标定)或参与优化。 2. **稀疏性与雅可比矩阵** - 每个观测仅关联一个相机和一个三维点,导致雅可比矩阵高度稀疏。 - 利用稀疏性加速求解(如Schur补消元法)[^3]。 3. **优化算法** - **列文伯格-马夸尔特(LM)算法**:结合高斯-牛顿法和梯度下降,动态调整步长。 - **高斯-牛顿法**:二阶近似,适用于局部优化。 ```python # 伪代码示例:使用Ceres Solver库 problem = ceres.Problem() for each observation (i,j): cost_function = ceres.AutoDiffCostFunction(ReprojectionError, 2, 6, 3) problem.AddResidualBlock(cost_function, None, pose_i, point_j) options = ceres.SolverOptions() ceres.Solve(options, problem, summary) ``` --- #### **应用与优化** 1. **应用场景** - **SLAM**:闭环检测后全局优化位姿与地图[^2]。 - **SfM**:多视图三维重建中优化稀疏点云。 - **相机标定**:联合优化内参和外参。 2. **加速技术** - **增量式BA**:仅优化新增变量(如iSAM2)。 - **关键帧选择**:减少冗余观测。 - **GPU并行化**:加速雅可比矩阵计算。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值