4、畸变模型:径向畸变、切向畸变、畸变公式、OpenCV中的畸变系数顺序

在相机标定中,我们通常假设相机满足理想的小孔成像模型,即三维空间点、光心与像点三点共线。然而,真实镜头由于制造工艺、装配误差和光学设计限制,成像光线会发生弯曲,导致实际像点偏离理想位置,这种偏离统称为镜头畸变。畸变模型是连接理想像素坐标与实际像素坐标的数学桥梁,也是标定算法中需要求解的核心参数之一。理解畸变的物理来源、数学表达以及在OpenCV中的存储顺序,是进行高精度标定、图像校正和三维重建的前提。本章将系统讲解径向畸变与切向畸变的原理、畸变公式的推导逻辑,并重点剖析OpenCV中畸变系数向量的排列规则。

畸变模型总览:从物理来源到OpenCV系数 理想小孔模型 三维点 P(X,Y,Z) 理想像点 p 光线直线传播,满足相似三角形 真实镜头畸变 三维点 P 实际像点 p' 光线弯曲,像点偏移 畸变分类 径向畸变 (k1,k2,k3) 切向畸变 (p1,p2) 桶形/枕形 + 倾斜偏移 OpenCV 畸变系数向量 (distCoeffs) [ k1, k2, p1, p2, k3 ] 5参数标准顺序,也可扩展为8参数 (k4,k5,k6) 畸变公式(归一化坐标) x_distorted = x(1 + k1r² + k2r⁴ + k3r⁶) + 2p1xy + p2(r² + 2x²) y_distorted = y(1 + k1r² + k2r⁴ + k3r⁶) + p1(r² + 2y²) + 2p2xy

上图展示了畸变模型的整体框架:理想成像模型是基准,真实镜头因光学缺陷产生畸变,畸变分为径向和切向两类,最终通过OpenCV的系数向量进行数学描述。下面我们逐一深入每个环节。

4.1 径向畸变:成因与数学模型

核心原理:径向畸变是镜头光学设计中最主要的畸变来源,表现为像点沿径向方向(从主点向外或向内)发生位移。其物理根源在于镜头的曲面形状——球面透镜无法将所有光线完美汇聚到同一焦点,导致不同入射高度的光线在像面上的放大率不一致。当镜头边缘的放大率小于中心时,图像呈现“桶形畸变”(广角镜头常见);当边缘放大率大于中心时,则呈现“枕形畸变”(长焦镜头常见)。

径向畸变的数学建模基于泰勒级数展开。设归一化图像坐标(已去除内参影响)为 (x, y),其到主点的距离为 r = √(x² + y²),则畸变后的坐标 (xdistorted, ydistorted) 可表示为:

x_distorted = x * (1 + k1*r² + k2*r⁴ + k3*r⁶)
y_distorted = y * (1 + k1*r² + k2*r⁴ + k3*r⁶)

其中 k1、k2、k3 为径向畸变系数。k1 描述主要畸变程度,k2 描述高阶畸变,k3 通常用于鱼眼镜头或高精度标定。对于普通镜头,k3 常设为0。值得注意的是,该公式是在归一化坐标下定义的,即坐标已除以焦距并减去主点偏移,这样畸变模型与相机分辨率无关,便于跨相机比较。

经验判断:当 k1 为负值时,图像呈桶形畸变(边缘向中心收缩);当 k1 为正值时,呈枕形畸变(边缘向外膨胀)。k2 的符号通常与 k1 相反,用于修正高阶残余误差。

4.2 切向畸变:成因与数学模型

核心原理:切向畸变源于镜头与图像传感器(或镜头组内部镜片)之间的装配不平行,即光轴与传感器平面存在微小倾斜角。这种倾斜导致光线在通过镜头时产生非对称的偏移,像点在切向方向(垂直于径向)发生位移。切向畸变在低端摄像头或受碰撞的镜头中尤为明显。

切向畸变的数学模型由 Brown-Conrady 模型给出,引入两个系数 p1 和 p2:

x_distorted = x + [2*p1*x*y + p2*(r² + 2*x²)]
y_distorted = y + [p1*(r² + 2*y²) + 2*p2*x*y]

从公式可以看出,切向畸变与坐标的乘积项和平方项相关,其影响在图像边缘区域更为显著。p1 主要描述垂直方向的倾斜,p2 描述水平方向的倾斜。实际标定中,切向畸变系数通常远小于径向畸变系数,但在高精度测量场景(如工业视觉定位)中不可忽略。

畸变类型 物理来源 系数 主要影响区域 典型量级
径向畸变 镜头球面像差 k1, k2, k3 图像边缘(径向) 10⁻³ ~ 10⁻¹
切向畸变 镜头/传感器装配倾斜 p1, p2 图像四角(切向) 10⁻⁴ ~ 10⁻²

4.3 完整畸变公式与OpenCV系数顺序

核心原理:将径向和切向畸变合并,得到完整的畸变模型。在OpenCV中,畸变系数以向量形式存储,其顺序有严格规定。对于标准标定(使用 cv::calibrateCamera),畸变系数向量 distCoeffs 的长度为4、5或8,具体含义如下:

  • 4参数:[k1, k2, p1, p2] —— 适用于畸变较小的镜头,忽略 k3。
  • 5参数:[k1, k2, p1, p2, k3] —— 最常用,包含三阶径向畸变。
  • 8参数:[k1, k2, p1, p2, k3, k4, k5, k6] —— 用于鱼眼镜头或高精度模型,其中 k4~k6 为更高阶径向系数。

OpenCV的文档明确说明,无论向量长度如何,前四个元素始终是 k1, k2, p1, p2。这一点在编写代码时极易出错——若将 p1, p2 误认为 k3, k4,会导致标定结果完全错误。此外,OpenCV的畸变公式与上述 Brown-Conrady 模型略有差异,其实际实现为:

x_distorted = x * (1 + k1*r² + k2*r⁴ + k3*r⁶) + 2*p1*x*y + p2*(r² + 2*x²)
y_distorted = y * (1 + k1*r² + k2*r⁴ + k3*r⁶) + p1*(r² + 2*y²) + 2*p2*x*y

注意:OpenCV在计算时,若使用5参数模型,k3 参与计算;若使用4参数模型,k3 被忽略。在调用 cv::undistort 或 cv::initUndistortRectifyMap 时,必须确保传入的畸变系数顺序正确。

常见陷阱:很多开发者从 MATLAB 或自定义标定工具迁移到 OpenCV 时,容易混淆系数顺序。MATLAB 的相机标定工具箱使用 [k1, k2, p1, p2, k3] 顺序,与 OpenCV 一致,但某些第三方库(如 ROS 的 camera_info)可能使用不同排列。务必查阅目标库的官方文档。

4.4 案例拆解:从标定结果到畸变校正

场景与目标:某工业机器人视觉引导项目,使用 500 万像素工业相机(分辨率 2448×2048)搭配 8mm 定焦镜头,工作距离约 500mm。系统需要实现 ±0.1mm 的定位精度。初始测试发现,在图像边缘区域,机器人抓取位置偏差达到 2~3mm,怀疑是镜头畸变未校正所致。

关键数据与现象:使用 12×9 棋盘格(方格边长 20mm)拍摄 25 张不同位姿图像,通过 OpenCV 标定得到内参矩阵和畸变系数:

内参矩阵 (fx, fy, cx, cy) = (3452.7, 3450.1, 1224.3, 1023.8)
畸变系数 (5参数) = [-0.2841, 0.0823, -0.0012, 0.0008, -0.0156]

分析:k1 = -0.2841 为负值,表明存在明显的桶形畸变;k2 = 0.0823 为正,用于修正边缘过度收缩;p1, p2 接近零,说明装配精度良好;k3 = -0.0156 较小,但保留可提升边缘精度。

操作步骤:

  1. 使用 cv::initUndistortRectifyMap 计算映射表,参数选择 CV_32FC1 类型。
  2. 调用 cv::remap 对每帧图像进行校正,采用双线性插值。
  3. 校正后重新测量棋盘格角点,计算重投影误差:从 0.32 像素降至 0.08 像素。
  4. 在机器人抓取测试中,边缘区域定位偏差从 2.5mm 降至 0.15mm,满足 ±0.1mm 的工艺要求。

风险与代价:校正后的图像边缘区域会有约 8% 的像素被裁剪(因桶形畸变校正后边缘拉伸),需重新调整 ROI 区域。此外,若使用 4 参数模型(忽略 k3),边缘精度会下降约 0.3mm,因此必须保留 k3。

复盘经验:畸变系数顺序错误是标定流程中最隐蔽的错误。建议在标定后立即打印系数向量,并与已知的棋盘格图像进行视觉对比——若校正后直线仍弯曲,优先检查系数顺序。另外,标定图像的位姿多样性(倾斜、旋转、边缘)直接影响 k1~k3 的稳定性,应确保棋盘格覆盖视场各区域。

4.5 常见误区与总结复盘

误区一:忽略切向畸变。许多教程只讲径向畸变,但实际镜头装配误差总会引入切向分量。即使 p1, p2 很小,在高精度测量中也会造成系统性偏差。建议始终使用5参数模型。

误区二:混淆归一化坐标与像素坐标。畸变公式中的 (x, y) 是归一化坐标(已除以焦距),而非像素坐标。若直接对像素坐标应用畸变公式,结果完全错误。OpenCV 内部会自动进行坐标转换,但自定义代码时需格外小心。

误区三:k3 随意置零。对于广角镜头或鱼眼镜头,k3 对边缘畸变的修正至关重要。即使标定结果中 k3 数值较小,也应保留。若使用4参数模型,应确认镜头畸变确实较小(如长焦镜头)。

误区四:畸变系数与内参的耦合。标定过程中,内参 (fx, fy, cx, cy) 与畸变系数是联合优化的。若初始猜测值偏差过大,可能收敛到局部最优解。建议使用 cv::CALIB_USE_INTRINSIC_GUESS 时提供合理初值,或先使用 cv::CALIB_FIX_ASPECT_RATIO 简化问题。

总结:畸变模型是相机标定的核心输出之一。径向畸变由镜头曲面引起,用 k1, k2, k3 描述;切向畸变由装配倾斜引起,用 p1, p2 描述。OpenCV 的系数顺序固定为 [k1, k2, p1, p2, k3],扩展模型为 [k1, k2, p1, p2, k3, k4, k5, k6]。在实际工程中,应优先使用5参数模型,并通过重投影误差和直线度检查验证标定质量。理解畸变公式的归一化坐标前提,是正确实现自定义校正算法的关键。