相机模型与标定(七)--LM算法在相机标定中的使用

本文详细介绍了LM(Levenberg-Marquardt)算法在相机标定中的三种应用场景,包括计算最佳外参、内外参以及双目相机系统的内外参与位姿矩阵。通过解析OpenCV源码,深入探讨了LM算法的具体实现过程。

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

LM算法在相机标定的应用共有三处。

(1)单目标定或双目标定中,在内参固定的情况下,计算最佳外参。OpenCV中对应的函数为findExtrinsicCameraParams2。

(2)单目标定中,在内外参都不固定的情况下,计算最佳内外参。OpenCV中对应的函数为calibrateCamera2。

(3)双目标定中,在左右相机的内外参及左右相机的位姿都不固定的情况下,计算最佳的左右相机的内外参及最佳的左右相机的位姿矩阵。OpenCV中对应的函数为stereoCalibrate。

  本文文阅读前提是你已经对LM(Levenberg-Marquardt)算法有足够的了解。因为本文主要是分析LM算法在相机标定中应用。

本文的分析是基于OpenCV的源码,所以可参见OpenCV的源码阅读此文。

0变量设置

设标定板上角点数为m,标定过程中拍摄n幅视图(对双目标定而言,左右相机各抓取n幅视图)。

关于相机的成像模型和畸变模型,我这里就不占空间了,详见OpenCV官方文档或相关论文。我用如下函数表示:

 

其中,(u,v)是像素坐标,(X,Y,Z)是世界坐标,R=(r1, R2, R3)T是旋转外参,T=(T1, T2, T3)T是平移外参,A=(fx, fy, cx, cy)T是投影内参,D=(k1, k2, p1,p2, k3, k4, k5, k6, s1, s2, s3, s4, a, b)T是畸变内参。

纵所周知,(u,v)是存在畸变的(后文称之为畸变坐标),我们用(uu,vv)表示(u,v)对应的非畸变的坐标(后文称之为标准坐标)。我们用findChessboardCorners提取的角点坐标就被当作是标准坐标。

1计算最佳外参

在内参固定的情况下,我们需要计算最佳外参。于是成像模型简化为:

 

对于m个角点则有如下方程:

 

其中(Xi, Yi, Zi)是已知项。计算雅可比矩阵如下:

 

由J可得J和JTJ。

若给定初值(R0, T0)则可得畸变角点序列uv=(u1,v1, u2,v2,…,um,vm)T。若findChessboardCorners获得的标准角点序列为uuvv=(uu1, vv1, uu2, vv2, …, um, vm)T,则误差序列为E=uv-uuvv。于是最终的方程为:

 

解方程后可得更精确的(R1, T1)=(R0, T0)-σ。

注意:以上可能与其它LM算法介绍有些差异。按大多数LM算法的介绍文档应是E=uuvv-uv, (R1, T1) = (R0, T0) +σ。不过仔细观察会发现最终结果其实一样的。我只不过是为了与OpenCV中源码对应才这样写的。

2计算最佳内外参

在内外参都不固定的情况下,成像模型应为:

 

与计算最佳外参不同。计算最佳外参是针对一幅视图,优化目标是使此幅视图的重投影误差最小。而计算最佳内外参,是针对多幅视图,优化目标是使所有视图的重投影误差之和最小。每幅视图有各自的外参,但共用相同的内参。所以每幅视图像上的角点仅对内参和各自的外参存在偏导,对其它视图的外参的偏导为0。于是雅可比矩阵为:

 

其中,Jini和Jexi是第i幅视图对内参和自身外观的雅可比矩阵。Jini是n×18矩阵(因为18个内参所以18列),Jexi是n×6矩阵(因为6个外参所以6列),所以J是(n*n)×(18+6*n)的矩阵。

可算得:

 

 

 

3计算最佳左右相机的内外参及最佳左右相机的位姿矩阵

此步骤中的优化参数是两相机间的位姿矩阵(R, T),两相机的内参(A1, D1, A2, D2)及左两机外参序列(R1i, T1i)。其中左相机的外参(R2i, T2i)=(RR1i, RT1i+T)。于是左相机每幅视图上的角点只对(A1, D1, Ri, Ti)有偏导,对其它参数的偏导为0。而右相机每幅视图上的角点只对(R, T, A2, D2, R1i, T1i)有偏导,对其它参数的偏导为0。其中,对(R, T, R1i, T1i)的偏导来源于对(R2i, T2i)的偏导。

<think>好的,我现在要解释如何使用Levenberg-Marquardt(LM算法优化相机标定数。首先,我需要回忆一下相机标定的基本概念和LM算法的作用。 相机标定的目的是确定相机的内(比如焦距、主点坐标、畸变系数)和(比如旋转矩阵和平移向量)。通常,这通过拍摄已知的标定板(比如棋盘格)来实现,收集多个角点的图像坐标和对应的世界坐标,然后建立投影模型,通过优化算法最小化重投影误差来求解数。 Levenberg-Marquardt算法是一种非线性最小二乘优化算法,结合了梯度下降和高斯-牛顿法的优点。在相机标定中,重投影误差通常是非线性的,因此需要LM这样的迭代算法来优化数。 接下来,我需要分步骤说明LM算法相机标定中的应用流程: 1. **建立投影模型**:首先确定相机模型,比如针孔模型加上径向和切向畸变。投影过程将3D世界点转换到2D图像坐标,涉及内。 2. **目标函数定义**:定义重投影误差作为优化的目标函数。对于每个标定板的角点,计算其投影到图像平面的坐标实测坐标的差值,平方后求和作为总误差。 3. **数初始化**:提供相机数的初始估计值。可能需要使用张正友标定法等方法先获取粗略的数,作为LM算法的起点。 4. **迭代优化**:LM算法在每一步迭代中,根据当前数计算雅可比矩阵,进而构建线性方程组,调整数以减少误差。LM通过调节阻尼因子在梯度下降和高斯-牛顿法之间切换,确保稳定收敛。 5. **收敛判断**:当数变化或误差下降小于阈值时,停止迭代,得到优化后的数。 在此过程中,需要注意几点:雅可比矩阵的计算可能比较复杂,需使用数值方法或解析求导;初始值的好坏会影响收敛速度和结果;畸变模型的复杂性可能导致局部极小值,需要合理选择模型结构。 可能遇到的问题包括:数过多导致过拟合,标定板角点数量不足,或者噪声较大的数据影响优化结果。此时需要检查数据质量,增加标定点数量,或者调整LM算法数如初始阻尼因子、最大迭代次数等。 总结来说,LM算法通过迭代调整相机数,最小化重投影误差,是相机标定中常用的优化方法,兼具效率和稳定性。</think>使用Levenberg-Marquardt(LM算法优化相机标定数的过程可分为以下步骤,其核心是通过非线性最小二乘优化最小化重投影误差: --- ### **1. 相机标定问题建模** - **投影模型**:建立3D世界点$(X_w, Y_w, Z_w)$到2D图像点$(u, v)$的映射关系: $$ \begin{aligned} s\begin{bmatrix}u \\ v \\ 1\end{bmatrix} &= \mathbf{K} \left[ \mathbf{R} \mid \mathbf{t} \right] \begin{bmatrix}X_w \\ Y_w \\ Z_w \\ 1\end{bmatrix} + \text{畸变项} \\ \mathbf{K} &= \begin{bmatrix} f_x & \gamma & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \quad (\text{内矩阵}) \end{aligned} $$ 其中包含内$(f_x, f_y, c_x, c_y, \gamma)$、$(\mathbf{R}, \mathbf{t})$及畸变数$(k_1, k_2, p_1, p_2, k_3)$。 - **重投影误差**:对$N$个标定板角点,误差函数为: $$ E = \sum_{i=1}^{N} \left\| \boldsymbol{u}_i^{\text{观测}} - \boldsymbol{u}_i^{\text{投影}} \right\|^2 $$ --- ### **2. LM算法优化流程** - **步骤1:数初始化** 使用张正友标定法等粗略估计初始数$\boldsymbol{\theta}_0$(包含内和畸变数)。 - **步骤2:计算雅可比矩阵** 计算误差函数对每个数的偏导数,构建雅可比矩阵$\mathbf{J}$,维度为$2N \times m$($m$为数总数)。 - **步骤3:构建增量方程** LM算法迭代公式: $$ (\mathbf{J}^T\mathbf{J} + \lambda \mathbf{I}) \Delta \boldsymbol{\theta} = \mathbf{J}^T \mathbf{e} $$ 其中$\lambda$为阻尼因子,$\mathbf{e}$为误差向量。 - **步骤4:数更新阻尼调节** - 若误差减小,接受$\Delta \boldsymbol{\theta}$,减小$\lambda$(偏向高斯-牛顿法加速收敛)。 - 若误差增大,增大$\lambda$(偏向梯度下降法稳定搜索)。 - **步骤5:收敛判断** 当满足 $\|\Delta \boldsymbol{\theta}\| < \epsilon_1$ 或 $\Delta E < \epsilon_2$ 时终止迭代。 --- ### **3. 关键实现细节** - **雅可比矩阵计算** 使用解析法(链式法则求导)或数值差分法。例如,对焦距$f_x$的偏导: $$ \frac{\partial u}{\partial f_x} = \frac{X_c}{Z_c} \quad (\text{其中} X_c = \mathbf{R}X_w + t_x) $$ - **畸变模型处理** 包含径向畸变$(k_1, k_2, k_3)$和切向畸变$(p_1, p_2)$: $$ \begin{aligned} x_{\text{distorted}} &= x(1 + k_1 r^2 + k_2 r^4 + k_3 r^6) + 2p_1 xy + p_2(r^2 + 2x^2) \\ y_{\text{distorted}} &= y(1 + k_1 r^2 + k_2 r^4 + k_3 r^6) + p_1(r^2 + 2y^2) + 2p_2 xy \end{aligned} $$ - **鲁棒性增强** 可引入M估计(如Huber损失)抑制离群点影响。 --- ### **4. 实际应用中的注意事项** - **数据质量**:标定板需覆盖图像不同区域,角度多样,避免退化配置。 - **数耦合**:内(如$f_x, f_y$)和可能存在耦合,需足够的数据点解耦。 - **过拟合控制**:畸变数过多时,可通过交叉验证选择合适模型阶数。 --- ### **示例代码框架(Python伪代码)** ```python import numpy as np from scipy.optimize import least_squares def project_points(world_points, K, dist_coeffs, rvecs, tvecs): # 将世界坐标投影到图像平面(含畸变) # 返回投影坐标和雅可比矩阵 def compute_residuals(params, world_points, observed_points): # 解析数:params = [fx, fy, cx, cy, k1, k2, p1, p2, ..., rvecs, tvecs] # 计算重投影误差 # 初始数猜测 params_init = [fx_guess, fy_guess, cx_guess, cy_guess, 0, 0, 0, 0, ...] # LM优化 result = least_squares( fun=compute_residuals, x0=params_init, method='lm', args=(world_points, observed_points) ) optimized_params = result.x ``` --- ### **总结** LM算法通过自适应调整阻尼因子,在相机标定中平衡收敛速度稳定性,有效优化非线性数。其成功依赖于准确的初始值、合理的畸变模型设计以及高质量的标定数据。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值