4. 相机内参标定误差:畸变模型、焦距误差、主点偏移对标定结果的影响

相机内参标定,说白了就是给相机做“体检”。你想想看,手眼标定的本质,是把相机看到的像素坐标,和机器人知道的世界坐标对齐。如果相机自己的“体检报告”都不准,那后面再怎么算,都是白搭。

我个人习惯,每次做手眼标定之前,一定会先确认内参标定的质量。因为内参误差会直接“传染”给外参,而且很难排查。今天我们就来拆解一下,内参里最容易出问题的三个地方:畸变模型、焦距误差、主点偏移。

4.1 畸变模型:镜头天生的“近视”与“散光”

没有镜头是完美的。哪怕是几万块的工业镜头,也逃不过畸变。畸变主要分两种:径向畸变和切向畸变。

  • 径向畸变:光线通过镜头边缘时,弯曲程度比中心大。表现为“桶形畸变”(画面向外鼓)或“枕形畸变”(画面向内凹)。
  • 切向畸变:镜头和成像平面不平行,导致画面像被“拧”了一下。这个在装配不良的镜头里更常见。

标定的时候,我们通常用多项式模型去拟合畸变。比如 OpenCV 里用的就是 k1, k2, k3, p1, p2 这五个参数。但这里有个坑:模型阶数选错了,或者标定板覆盖不全,畸变参数就会“跑偏”。

我曾经踩过的坑: 有一次用 7x9 的棋盘格,只拍了 10 张图,畸变参数看起来收敛了。结果换到视野边缘做手眼标定,误差直接翻倍。后来发现,标定板没有覆盖画面的四个角落,边缘畸变根本没被约束住。

畸变模型不准,最直接的影响是:像素坐标的“真实位置”被扭曲了。你想想看,手眼标定里,我们提取的角点坐标,如果先被错误的畸变模型“矫正”了一遍,那这个坐标本身就是错的。外参算出来,自然也是错的。

4.2 焦距误差:放大倍数的“失准”

焦距 fx, fy,决定了像素坐标和物理尺寸之间的比例关系。你可以把它理解成“放大倍数”。

焦距误差的来源,通常有两个:

  1. 标定板距离变化不够:如果所有标定图像都在同一个深度拍摄,焦距和深度之间会产生耦合,解不出来。我见过有人把标定板贴在墙上,相机前后移动不到 10cm,结果焦距误差能到 5%。
  2. 镜头调焦环松动:工业镜头如果没锁紧,调焦环轻微转动,焦距就变了。这时候你之前标定的内参,全部作废。

焦距误差会怎么影响手眼标定?举个例子:

假设你的机器人末端移动了 100mm,相机看到像素移动了 200 个像素。如果焦距是 1000 像素/mm,那算出来就是 0.2mm/像素。但如果焦距实际是 1020,那你的位移估计就会偏 2%。这个误差会直接进入手眼矩阵的平移部分,而且随着工作距离增大,误差会线性放大。

我的建议: 标定焦距时,一定要让标定板在至少 3 个不同的距离上成像。近、中、远各拍一组。这样焦距和深度的耦合才能解耦。我一般会拍 20-30 张图,覆盖整个工作空间。

4.3 主点偏移:光轴对不准的“偏心”

主点 cx, cy,理论上应该是图像的中心。但实际镜头装配时,光轴和 CMOS 中心很难完全对齐。这个偏移量,就是主点偏移。

主点偏移的影响,在视野边缘尤其明显。你想想看,如果主点偏了 10 个像素,那画面左上角和右下角的“真实方向”都会跟着偏。在手眼标定里,这会导致旋转矩阵的估计出现系统性偏差。

我遇到过最头疼的情况,是主点偏移和畸变参数互相“打架”。标定算法如果自由度太高,畸变参数会去“补偿”主点偏移,导致两个参数都不准。这时候你单独看重投影误差可能很小,但一用到手眼标定里,就露馅了。

内参参数 典型误差来源 对手眼标定的影响 我的避坑方法
畸变系数 (k1, k2, p1...) 标定板未覆盖边缘、模型阶数不足 角点位置扭曲,外参平移和旋转都错 确保标定板出现在画面四角和边缘
焦距 (fx, fy) 标定距离变化不够、镜头松动 平移分量比例误差,随距离放大 至少 3 个深度,20+ 张图
主点 (cx, cy) 镜头装配偏差、与畸变耦合 旋转矩阵系统性偏差 先固定畸变模型,再优化主点

4.4 内参误差的“传染链”

为了让你更直观地理解,我画了一张图。它展示了内参误差是怎么一步步“传染”到手眼标定结果里的。

内参误差“传染链” 畸变模型误差 角点位置扭曲 焦距误差 尺度比例失准 主点偏移 光轴方向偏差 像素坐标 → 归一化坐标 转换错误 内参矩阵和畸变参数同时参与,误差叠加 手眼标定输入:错误的 3D-2D 对应关系 机器人位姿 + 错误的内参 → 错误的外参估计 手眼标定结果:平移误差 + 旋转误差

从这张图可以看得很清楚:内参误差不是“独立”的,它会沿着标定流程一路向下传导。你如果在手眼标定阶段发现误差很大,不妨回头检查一下内参标定的质量。

4.5 如何快速诊断内参标定质量?

这里分享几个我常用的“土办法”:

  • 重投影误差检查:标定完成后,看所有角点的平均重投影误差。如果超过 0.5 像素,我建议重新标定。0.1 像素以下才算优秀。
  • 畸变矫正预览:把一张标定板图片做畸变矫正,看看边缘的直线是不是真的变直了。如果还有弯曲,说明畸变参数没学好。
  • 焦距稳定性测试:在不同距离各拍 5 张图,分别标定,看焦距的波动。如果波动超过 0.5%,说明标定过程有问题。
一个小技巧: 我习惯在标定完成后,把内参矩阵和畸变系数保存下来,然后在手眼标定的代码里加一个“内参一致性检查”。如果这次标定的焦距和上次相差超过 1%,就报个警告。这能帮我提前发现镜头松动之类的问题。

嗯,内参标定这块,说白了就是“基础不牢,地动山摇”。你花 80% 的精力把内参搞准了,手眼标定那 20% 的工作就会顺利很多。别嫌麻烦,这步省不了。