前言
在做相机标定和外参校准,手眼标定,动捕系统优化等环节,均需要进行迭代最优化来求解具体参数。
在内参标定过程中,由于OpenCV等库的自带flag参数有限,因此使用Ceres-solver手动构建求解函数。
一、手动构建最小二乘法求解器
在参数求解中使用Ceres-solver手动构建最小二乘法求解器,有较高的灵活性。
在数据处理过程中,发现原始数据存在噪声和Bias偏差,容易使优化陷入局部最优。
经过通义灵码提示,有以下优化思路:
多项式拟合参数不稳定且容易陷入局部最优的问题,可以考虑以下优化策略:
-
降低多项式阶数: 高阶多项式可能会导致过拟合和局部最优问题。尝试降低多项式的阶数,如从五次多项式降至三次或四次多项式,这样既可以减少优化变量的数量,也有助于避免过度复杂的模型带来的问题。
-
正则化: 在优化过程中加入正则化项,以防止过拟合。例如,可以为每个多项式系数添加L1或L2范数惩罚项,使得优化过程更倾向于选择平滑变化、泛化能力更强的解。
-
分段线性/多项式拟合: 对不同zoom范围采用不同的低阶多项式进行拟合,而不是用一个全局高阶多项式来覆盖所有zoom值。这种方法有助于捕捉不同zoom范围内的特性,并可能减轻局部最优问题。
-
初始化策略: 确保优化算法有一个良好的初始点,可以从已有的标定结果或者先验知识出发,甚至使用多起点搜索策略,增加找到全局最优解的可能性。
-
优化算法调整:
- 调整Ceres求解器设置,比如增大最大迭代次数、改变信赖域大小、尝试不同的线性求解器等。
- 采用多种优化算法(如梯度下降法、Levenberg-Marquardt算法、牛顿法等)并比较其效果,选择最适合当前问题的算法。
-
数据增强与筛选:
- 增加更多种类的数据,包括不同视角、光照条件下的图像,确保训练集的多样性。
- 筛选高质量的特征点,剔除异常值或噪声较大的点,这些点可能导致优化过程偏离全局最优路径。
-
分步优化: 先固定一部分内参不变,只优化畸变参数或其他随焦距变化的参数,然后逐步加入其他内参的优化,逐个解决各个子问题,最后联合优化所有参数。
-
全局优化方法: 如果常规优化方法仍然无法达到满意的效果,可以尝试全局优化算法,例如遗传算法、模拟退火、粒子群优化等。但需要注意的是,全局优化方法可能需要更多的计算资源和时间。
二、正则化构建残差函数
1.Tikhonov正则化
经过测试,为内参优化过程中的主点也就是光心cx和cy添加一个正则项到目标函数中。这里可以通过引入拉普拉斯平滑项或Tikhonov正则化
//此处0.5为归一化光心,实际应用中应修改为 0.5*图像宽 | 0.5*图像高
double cx_deviation = K[1] - 0.5;
double cy_deviation = K[3] - 0.5;
// 添加正则项到残差中,λ是正则化参数,根据实际情况调整
residuals[2] = λ * cx_deviation;
residuals[3] = λ * cy_deviation;
//然后修改Ceres-solver方法中的残差维度:
2.套用模板函数
注意调用Ceres-solver时需要使用模板函数传参,可针对性修改参数。
这样,在优化过程中,Ceres将同时最小化投影误差以及光心偏移的正则项,从而使得优化后的光心更接近图像中心。
三、优化λ范围
其中λ的取值很重要:
λ(Lambda)是正则化参数,其取值对优化结果有重要影响。它控制了正则项在目标函数中的权重,从而影响模型的复杂度和拟合效果:
-
如果λ过小:正则化项的影响较小,光心可能不会被强制接近图像中心,模型可能仍然存在过拟合的风险。
-
如果λ过大:正则化项的作用过于强烈,可能导致模型欠拟合,即过分追求光心接近图像中心而牺牲了对其他数据点的拟合质量。
选择合适的λ值通常需要通过交叉验证、网格搜索或者自适应调整方法来确定。一个简单的尝试方式是:
- 初始化λ为一个较小的正值,如0.01或1。
- 进行优化,并观察优化后光心位置与图像中心的偏离程度以及整体拟合误差。
- 根据结果逐渐增大或减小λ值,直到找到既能保证光心接近图像中心又能保持良好全局拟合效果的平衡点。
另外,也可以采用L-curve分析、贝叶斯优化等高级方法来寻找最优的正则化参数。实际应用时,可能需要多次试验和迭代才能找到理想的λ值。
本例中图像分辨率为1920×1080,图像的cxcy偏差可达100像素,对应的重投影误差的残差约为0.1-1pixel,因此λ≈0.01,实测在此范围取值可达到比较好的效果。
总结
在实测中,发现镜头标定参数不够稳定,即使采用氧化铝薄膜的玻璃标定板进行标定,镜头的参数也有较大变化,分析是标定图像存在误差导致优化陷入局部最优解,尤其是镜头的切向畸变和光心耦合变化,使得结果非常不稳定。
此时需要针对参数做部分调整,例如固定光心,针对焦距给出多组初始值等方法。