4、系统标定联合优化:重投影误差最小化与光束法平差
好,咱们接着聊标定。前面几节我们把相机和投影仪各自的内参、外参都捋了一遍,但说实话,那只是「各自为战」。你想想看,相机标自己的,投影仪标自己的,最后拼在一起,误差能小吗?
我早年做第一个结构光项目时就吃过这个亏。相机重投影误差0.1像素,投影仪也标得挺漂亮,可一重建三维点,偏差直接飙到毫米级。后来我才明白——系统标定必须联合优化。
4.1 为什么需要联合优化?
单独标定有个根本问题:相机和投影仪的误差会互相放大。
举个例子。你标定相机时,用的是棋盘格角点。这些角点的三维坐标,是你假设的「理想值」。但投影仪标定时,它投射的编码条纹也会受相机畸变影响。两个误差源一叠加,最终重建精度就崩了。
说白了,相机-投影仪是一个双目系统。你不能把左眼和右眼分开训练,对吧?
核心思想:将相机和投影仪视为一个整体,构建联合代价函数,同时优化所有参数。让重投影误差在全局意义上最小化。
4.2 联合代价函数怎么构建?
这里我直接给出公式,别怕,其实逻辑很简单。
假设我们有N个标定点(比如棋盘格角点),每个点在世界坐标系下的坐标为 Xw。相机观测到的像素坐标为 uc,投影仪投射的编码对应像素坐标为 up。
那么,联合代价函数就是:
E = Σ || u_c - π_c(K_c, R_c, t_c, X_w) ||²
+ Σ || u_p - π_p(K_p, R_p, t_p, X_w) ||²
其中:
- π_c 是相机的投影函数(含畸变)
- π_p 是投影仪的投影函数(含畸变)
- K_c, K_p 是内参矩阵
- R_c, t_c, R_p, t_p 是外参(旋转和平移)
注意,这里的 X_w 也是优化变量!不是固定死的。这就是光束法平差(Bundle Adjustment)的精髓——同时优化三维点和相机/投影仪参数。
我的经验:一开始别把所有参数都放开优化。先固定内参,只优化外参和三维点。迭代几轮后,再放开内参。这样收敛更快,不容易掉进局部最优。
4.3 Levenberg-Marquardt 算法怎么用?
LM算法,说白了就是梯度下降法 + 高斯牛顿法的混合体。它有个阻尼因子 λ,控制着算法在「信任区域」内搜索。
具体步骤我简化一下:
- 初始化:用单独标定的结果作为初值
- 计算雅可比矩阵:对每个参数求偏导
- 求解增量方程:(JTJ + λI) Δx = -JTe
- 更新参数:x = x + Δx
- 判断收敛:如果重投影误差下降小于阈值,停止
这里有个关键点——雅可比矩阵的稀疏性。因为每个三维点只出现在少数几个观测方程中,所以 JTJ 是高度稀疏的。利用稀疏求解器(比如 SuiteSparse),速度能快几十倍。
// 伪代码示例(C++风格)
void bundleAdjustment(
vector<Point3d>& points, // 三维点
vector<Camera>& cameras, // 相机+投影仪参数
vector<Observation>& obs // 观测数据
) {
LevenbergMarquardt lm;
lm.setMaxIterations(100);
lm.setLambda(0.001);
while (!lm.converged()) {
// 构建稀疏矩阵
SparseMatrix J = buildJacobian(points, cameras, obs);
Vector e = computeResidual(points, cameras, obs);
// 求解增量
Vector dx = lm.solve(J, e);
// 更新参数
updateParameters(points, cameras, dx);
// 调整阻尼因子
lm.updateLambda(e, dx);
}
}
注意:投影仪的畸变模型和相机略有不同。我建议投影仪用 多项式模型(径向畸变+切向畸变),而不要用除法模型。后者在投影仪上容易发散。
4.4 我曾经踩过的坑
讲几个真实案例,你遇到了能少走弯路。
坑1:初值太差,LM直接崩了
有一次我偷懒,直接用投影仪标定的初值,没做任何预处理。结果LM迭代到第3步,重投影误差从0.5像素直接跳到50像素。后来我加了两步法:先用线性方法求一个粗略解,再用LM精化。稳得很。
坑2:忽略了投影仪的「虚拟像素」
投影仪本质上是一个逆向相机。它的像素坐标是投射出去的编码值,不是直接拍摄的。所以计算重投影误差时,要把投影仪的观测值转换到「虚拟图像坐标系」下。我一开始没注意,误差算出来全是错的。
坑3:过度优化导致过拟合
标定点太少时,联合优化会把噪声也拟合进去。我建议每个标定板图像至少提取50个角点,总共20-30张图像。这样参数空间才够约束。
4.5 联合优化的效果有多明显?
直接上数据。这是我一个项目中的实测对比:
| 标定方法 | 相机重投影误差 (pixel) | 投影仪重投影误差 (pixel) | 三维重建误差 (mm) |
|---|---|---|---|
| 单独标定 | 0.12 | 0.18 | 0.85 |
| 联合优化(仅外参) | 0.10 | 0.15 | 0.52 |
| 联合优化(内外参+三维点) | 0.08 | 0.11 | 0.31 |
看到了吧?联合优化能把三维重建误差降低60%以上。这可不是小数目。
4.6 核心逻辑流程图
下面这张图,我把整个联合优化的流程画出来了。你一看就明白。
4.7 总结一下
联合优化不是什么高深莫测的技术,它就是把相机和投影仪当成一个整体来调优。核心就三点:
- 构建联合代价函数——同时考虑相机和投影仪的残差
- 使用LM算法——稳健的迭代优化方法
- 注意初值和稀疏性——别让算法跑飞了
嗯,这一节内容不少,但你只要动手跑一遍代码,就会发现其实没那么复杂。下一节我们聊聊标定板的设计——别小看它,好的标定板能让你的精度再上一个台阶。
公众号:蓝海资料掘金营,微信deep3321