3、相机内参与外参:内参矩阵、畸变系数、外参(旋转和平移)的物理意义与数学表示

相机标定的本质,是建立三维世界坐标与二维像素坐标之间的映射关系。这个映射被拆解为两个阶段:第一阶段由相机内部的光学与传感属性决定,称为内参;第二阶段由相机在世界坐标系中的位姿决定,称为外参。理解内参与外参的物理意义与数学表示,是进行标定、去畸变、双目立体匹配以及视觉定位的基础。本章将从针孔模型出发,逐一拆解内参矩阵、畸变系数以及外参旋转和平移的数学形式,并结合实际工程场景说明其应用与常见误区。

相机成像模型:外参 → 内参 → 像素 世界坐标系 P_w = (X_w, Y_w, Z_w) 三维真实点 单位:米/mm 外参 R, t 相机坐标系 P_c = (X_c, Y_c, Z_c) 光心为原点 Z轴指向相机前方 内参 K, 畸变 像素坐标系 p = (u, v) 单位:像素 原点在图像左上角 内参矩阵 K [ fx 0 cx ] [ 0 fy cy ] [ 0 0 1 ] fx=f/dx, fy=f/dy(焦距/像元尺寸) 畸变模型(径向+切向) x_dist = x(1+k1·r²+k2·r⁴+k3·r⁶) + 2p1·xy + p2(r²+2x²) y_dist = y(1+k1·r²+k2·r⁴+k3·r⁶) + p1(r²+2y²) + 2p2·xy 外参:R(3×3旋转) + t(3×1平移) P_c = R · P_w + t R描述姿态,t描述位置,共6自由度 畸变系数向量 D = [k1, k2, p1, p2, k3] OpenCV中顺序固定,k3可省略

上图展示了从世界坐标到像素坐标的完整链路。外参将世界点变换到相机坐标系,内参将相机坐标投影到像素平面,而畸变系数则修正了透镜带来的非线性误差。下面我们逐一深入。

3.1 内参矩阵:从相机坐标到像素坐标的线性映射

3.1.1 核心原理:针孔模型的数学化

针孔模型假设光线沿直线传播,三维点 \(P_c=(X_c, Y_c, Z_c)\) 在相机坐标系下,通过光心投影到成像平面。理想情况下,投影坐标 \((x, y)\) 满足:

x = f · X_c / Z_c
y = f · Y_c / Z_c

其中 \(f\) 为物理焦距(单位:毫米)。但像素坐标 \((u, v)\) 的原点位于图像左上角,且 \(u\) 轴向右、\(v\) 轴向下,因此需要引入主点偏移 \((c_x, c_y)\) 和像素尺寸 \(d_x, d_y\)(单位:毫米/像素)。最终得到:

u = (f/d_x) · (X_c/Z_c) + c_x = f_x · (X_c/Z_c) + c_x
v = (f/d_y) · (Y_c/Z_c) + c_y = f_y · (Y_c/Z_c) + c_y

写成齐次坐标矩阵形式即为内参矩阵 \(K\):

[ u ]   [ f_x  0  c_x ] [ X_c ]
[ v ] = [ 0   f_y c_y ] [ Y_c ]
[ 1 ]   [ 0    0   1  ] [ Z_c ]

注意,这里的 \(Z_c\) 是深度值,实际计算时需将齐次坐标除以 \(Z_c\) 得到非齐次像素坐标。

3.1.2 判断方法:如何理解 \(f_x\) 与 \(f_y\) 的差异

\(f_x\) 与 \(f_y\) 通常不相等,原因有二:一是 CMOS 传感器的像元并非严格正方形,二是相机内部可能对图像进行了缩放或裁剪。在 OpenCV 标定结果中,若 \(f_x\) 与 \(f_y\) 相差超过 1%,应检查标定板是否倾斜或图像是否被非等比缩放。此外,\(c_x, c_y\) 理论上应接近图像中心 \((width/2, height/2)\),若偏差超过 5% 像素,说明镜头光轴与传感器中心未对齐,属于正常制造公差,但若偏差过大则需检查相机装配。

3.1.3 案例拆解:单目相机标定中的内参获取

假设使用 1280×720 分辨率的工业相机,标定板为 9×6 棋盘格,格边长 25mm。通过 OpenCV 的 calibrateCamera() 函数,输入 20 张不同姿态的棋盘格图像,得到典型内参:

K = [ 1425.3  0      639.5 ]
    [ 0       1423.8 359.2 ]
    [ 0       0      1     ]
畸变系数: [ -0.321, 0.152, -0.0012, 0.0008, -0.038 ]

分析:\(f_x\) 与 \(f_y\) 相差 1.5 像素(约 0.1%),可视为正方形像元;主点 \((639.5, 359.2)\) 与理论中心 \((640, 360)\) 偏差小于 1 像素,说明镜头安装良好。若标定重投影误差小于 0.1 像素,则内参可信。

3.1.4 常见误区:内参矩阵不是固定不变的

内参矩阵依赖于焦距和分辨率。当相机变焦、切换分辨率或裁剪 ROI 时,内参必须重新标定。此外,内参矩阵不包含畸变信息,畸变是单独建模的。初学者常将内参与畸变混为一谈,实际上它们是两个独立的校正步骤:先去畸变,再投影。

3.2 畸变系数:透镜的非线性误差模型

3.2.1 核心原理:径向畸变与切向畸变

实际透镜存在制造误差,导致光线弯曲。畸变分为两类:

  • 径向畸变:由透镜形状引起,光线离中心越远弯曲越严重。用 \(k_1, k_2, k_3\) 描述,其中 \(k_3\) 用于高畸变镜头(如鱼眼)。
  • 切向畸变:由透镜与传感器不平行引起,用 \(p_1, p_2\) 描述。

畸变模型作用于归一化相机坐标 \((x, y)\)(即 \(X_c/Z_c, Y_c/Z_c\)),而非像素坐标。校正公式为:

x_corrected = x · (1 + k1·r² + k2·r⁴ + k3·r⁶) + 2p1·x·y + p2·(r² + 2x²)
y_corrected = y · (1 + k1·r² + k2·r⁴ + k3·r⁶) + p1·(r² + 2y²) + 2p2·x·y

其中 \(r² = x² + y²\)。OpenCV 的 cv2.undistort() 函数内部即执行此计算。

3.2.2 判断方法:畸变系数的量级与影响

对于普通工业镜头,\(k_1\) 通常在 -0.5 到 +0.5 之间,\(k_2\) 在 -0.3 到 +0.3 之间,\(p_1, p_2\) 通常小于 0.01。若 \(|k_1| > 1\),说明镜头畸变极大(如广角或鱼眼),此时需要更多标定图像或使用专门模型。判断畸变是否严重,可观察图像边缘的直线是否弯曲:棋盘格边缘若呈桶形(向外凸)则 \(k_1 < 0\),枕形(向内凹)则 \(k_1 > 0\)。

3.2.3 案例拆解:去畸变前后的测量误差对比

在机器人抓取场景中,使用上述内参和畸变系数对一张含棋盘格的图像进行去畸变。取棋盘格角点坐标,计算相邻角点距离(已知实际间距 25mm)。去畸变前,图像边缘角点距离误差达 3.2mm(约 12.8%);去畸变后,误差降至 0.4mm(约 1.6%)。这说明畸变校正在高精度测量中至关重要。操作流程:

  1. 读取图像并转为灰度图;
  2. 调用 cv2.findChessboardCorners() 提取角点;
  3. 调用 cv2.calibrateCamera() 获得畸变系数;
  4. 调用 cv2.undistort() 生成校正图;
  5. 重新提取角点并计算距离误差。

3.2.4 常见误区:畸变系数与图像分辨率相关

畸变系数是在特定分辨率下标定的。若将 1280×720 下标定的畸变系数用于 640×480 图像,必须先将归一化坐标按比例缩放,否则校正结果错误。OpenCV 的 getOptimalNewCameraMatrix() 可辅助处理分辨率变化,但最稳妥的做法是:在目标分辨率下重新标定。

3.3 外参:旋转与平移的物理意义

3.3.1 核心原理:世界坐标到相机坐标的刚体变换

外参描述相机在世界坐标系中的位姿。数学上,一个三维点 \(P_w\) 通过旋转矩阵 \(R\) 和平移向量 \(t\) 变换到相机坐标系:

P_c = R · P_w + t

其中 \(R\) 是 3×3 正交矩阵(满足 \(R^T R = I\),\(\det(R)=1\)),\(t\) 是 3×1 平移向量。\(R\) 和 \(t\) 共 6 个自由度(3 旋转 + 3 平移),称为相机外参。物理上,\(R\) 的列向量表示相机坐标轴在世界坐标系中的方向,\(t\) 表示相机光心在世界坐标系中的位置(注意:\(t\) 不是光心坐标,而是 \(-R^T t\) 才是光心坐标)。

3.3.2 判断方法:旋转矩阵的分解与验证

OpenCV 的 calibrateCamera() 返回每张标定图的旋转向量 \(rvec\)(Rodrigues 形式)和平移向量 \(tvec\)。旋转向量通过 cv2.Rodrigues() 转换为旋转矩阵。验证外参正确性的方法:将标定板角点的世界坐标(假设 Z=0)通过 \(R, t\) 投影到图像,计算重投影误差。若误差大于 0.5 像素,说明外参估计不准,可能原因包括标定板不平整或图像模糊。

3.3.3 案例拆解:双目相机的外参标定

双目系统中,左相机外参 \(R_l, t_l\) 和右相机外参 \(R_r, t_r\) 分别描述各自与世界坐标的关系。两相机之间的相对位姿为:

R_rel = R_r · R_l^T
t_rel = t_r - R_rel · t_l

实际标定中,使用 OpenCV 的 stereoCalibrate() 直接输出 \(R_rel, t_rel\)。例如,某双目相机标定结果为:

R_rel = [ 0.9999  -0.0012  0.0045 ]
        [ 0.0013   0.9999 -0.0021 ]
        [ -0.0045  0.0021  0.9999 ]
t_rel = [ -119.8, 0.5, -1.2 ]  (单位:mm)

分析:\(t_rel\) 的 x 分量约 -120mm,说明右相机在左相机左侧 120mm(基线长度);y、z 分量接近 0,说明两相机光轴基本平行。旋转矩阵接近单位阵,说明安装角度偏差小于 0.3°。此结果可直接用于立体校正。

3.3.4 常见误区:外参不是唯一的

外参依赖于世界坐标系的定义。若世界坐标系原点移动,\(R, t\) 会改变,但相机与物体的相对位置不变。因此,外参必须与标定板的世界坐标定义一起使用。此外,旋转矩阵的欧拉角表示存在万向锁问题,工程中建议使用旋转向量或四元数。

3.4 内参与外参的联合应用与标定流程

3.4.1 核心原理:完整投影方程

将内参、外参和畸变组合,得到完整的投影模型:

步骤1: P_c = R · P_w + t
步骤2: x = X_c/Z_c, y = Y_c/Z_c
步骤3: 应用畸变模型得到 x_dist, y_dist
步骤4: u = f_x · x_dist + c_x, v = f_y · y_dist + c_y

OpenCV 的 projectPoints() 函数实现了上述全部步骤。理解这个流程,有助于排查标定问题:若重投影误差大,可分别检查外参(步骤1)和内参(步骤4)的贡献。

3.4.2 判断方法:标定质量评估指标

指标优秀范围可接受范围需重新标定
重投影误差< 0.1 像素0.1 - 0.3 像素> 0.5 像素
标定图像数量20 - 30 张10 - 20 张< 10 张
姿态覆盖范围倾斜 ±30°,旋转 360°倾斜 ±20°仅平面平移
角点检测成功率> 95%80% - 95%< 80%

3.4.3 案例拆解:标定流程优化实战

某视觉引导项目需要 0.1mm 精度,但初始标定重投影误差为 0.8 像素。分析发现:标定板仅拍摄了 8 张图像,且全部为正面视角。优化措施:

  1. 增加至 25 张图像,覆盖不同倾斜角度(±30°)和旋转位置;
  2. 确保标定板占图像面积 20% - 80%,避免过小或过大;
  3. 使用亚像素角点检测(cornerSubPix())提高精度;
  4. 剔除重投影误差大于 0.3 像素的异常图像。

优化后重投影误差降至 0.08 像素,实际测量精度达到 0.08mm。代价是标定时间从 2 分钟增加到 5 分钟,但换来了 10 倍精度提升。

3.4.4 常见误区与总结复盘

风险提示:不要使用不同分辨率下的内参进行三维重建。若必须切换分辨率,应使用 cv2.getOptimalNewCameraMatrix() 重新计算内参,或直接重新标定。此外,标定板必须平整,打印在纸上并贴在硬板上时,需检查是否有气泡或弯曲。
经验总结:内参矩阵描述“相机如何看”,外参描述“相机在哪看”。标定过程中,先固定内参(同一相机),再针对不同场景更新外参(如机械臂移动相机)。在 OpenCV 中,solvePnP() 可用于已知内参时快速求解外参,这是视觉定位的核心工具。

本章详细拆解了内参矩阵、畸变系数和外参的物理意义与数学形式。内参矩阵中的 \(f_x, f_y, c_x, c_y\) 是线性投影的基础,畸变系数 \(k_1, k_2, p_1, p_2, k_3\) 修正非线性误差,而外参 \(R, t\) 将世界坐标与相机坐标关联。三者共同构成完整的相机模型,是后续立体视觉、位姿估计和三维重建的基石。在实际工程中,务必重视标定图像的质量与数量,并定期校验标定结果。