3. 畸变数学模型:径向畸变、切向畸变与标定方法概述

聊鱼眼校正,绕不开一个核心问题——畸变到底长什么样?怎么用数学描述它?

说白了,鱼眼镜头为了把超大视野塞进小小的传感器,必须牺牲“直线性”。光线经过镜头时,离中心越远,弯曲得越厉害。这种弯曲不是随机的,它有规律可循。我们这一节就把这些规律拆开来看。

核心观点:畸变模型是校正算法的“坐标系”。模型选对了,校正就成功了一半。我见过不少项目,算法调了半天没效果,最后发现是模型本身就不匹配镜头特性。

3.1 径向畸变模型

径向畸变是最主要的畸变类型。它沿着镜头半径方向发生,说白了就是“越靠边,变形越严重”。

我习惯把径向畸变分成两类:

  • 桶形畸变(Barrel Distortion):图像边缘向外膨胀,像木桶的弧度。鱼眼镜头几乎全是这种。
  • 枕形畸变(Pincushion Distortion):图像边缘向内收缩,像枕头。长焦镜头常见,鱼眼很少见。

为什么会这样?因为鱼眼镜头的设计刻意让光线在边缘“压缩”,才能拍到更宽的视野。你想想看,一个180°的视场角,如果按小孔成像去算,传感器根本装不下。

3.1.1 Brown模型

Brown模型是工业界最常用的径向畸变模型之一。它由Duane C. Brown在1960年代提出,至今仍是相机标定的主流选择。

它的数学形式很简单:

// 归一化坐标下的径向畸变
x_distorted = x * (1 + k1 * r² + k2 * r⁴ + k3 * r⁶)
y_distorted = y * (1 + k1 * r² + k2 * r⁴ + k3 * r⁶)

// 其中 r² = x² + y²
// k1, k2, k3 是径向畸变系数

这里有个细节:r 是归一化坐标下的半径,不是像素坐标。我刚开始做标定时,直接拿像素坐标去算,结果畸变参数怎么都收敛不了。后来才发现,必须先把像素坐标转换到归一化平面。

我的经验:对于普通广角镜头,用 k1、k2 两个参数就够了。但鱼眼镜头强烈建议用 k3,甚至有些极端镜头需要 k4、k5。我曾经处理过一个185°的鱼眼镜头,只用 k1、k2 校正后边缘还是有明显弯曲,加上 k3 才搞定。

3.1.2 多项式模型

多项式模型是Brown模型的“亲戚”,但更灵活。它用更高阶的多项式来拟合畸变曲线。

通用形式:

// 多项式径向畸变
r_distorted = r * (1 + k1 * r² + k2 * r⁴ + k3 * r⁶ + ... + kn * r^(2n))

// 或者直接用角度表示(鱼眼专用)
θ_distorted = θ * (1 + k1 * θ² + k2 * θ⁴ + k3 * θ⁶ + ...)

两种形式有什么区别?

模型 适用场景 参数数量 特点
Brown模型 普通广角、中焦镜头 3个(k1,k2,k3) 稳定、收敛快
多项式模型(高阶) 超广角、鱼眼镜头 4~8个 拟合能力强,但容易过拟合
多项式模型(角度域) 等距投影鱼眼 3~5个 物理意义更清晰

注意:多项式阶数不是越高越好。我曾经试过用8阶多项式去拟合一个普通镜头,结果在校正图像边缘出现了波浪状的伪影。这就是过拟合——模型记住了噪声,而不是真实的畸变规律。一般建议从3阶开始,逐步增加,直到校正效果不再明显改善为止。

3.2 切向畸变模型

切向畸变,也叫离心畸变。它不是因为镜头的光学设计,而是因为镜头和传感器不平行造成的。

你想想看,如果镜头的光轴和传感器平面不是严格垂直,图像就会产生“倾斜”或“拉伸”的效果。这种畸变沿着切线方向发生,所以叫切向畸变。

数学模型:

// 切向畸变
x_distorted = x + [2 * p1 * x * y + p2 * (r² + 2 * x²)]
y_distorted = y + [p1 * (r² + 2 * y²) + 2 * p2 * x * y]

// 其中 p1, p2 是切向畸变系数

这个公式看起来有点复杂,但核心思想很简单:切向畸变是 x 和 y 的耦合项。它不像径向畸变那样只跟半径有关,而是跟具体位置有关。

避坑指南:我曾经处理过一个工业检测项目,相机安装时稍微歪了一点。用纯径向模型校正后,图像中心区域看起来没问题,但边缘的直线还是弯的。后来加上切向畸变模型,一次就搞定了。所以,如果你的相机是人工安装的,千万别忽略切向畸变。

3.3 畸变参数标定方法概述

有了模型,下一步就是求参数。标定方法说白了就是:拿已知的图案去拍,然后反推畸变参数。

我按自己的经验,把主流方法分成三类:

  1. 基于棋盘格的传统标定(如张正友标定法)
  2. 基于直线特征的自动标定(如直线校正法)
  3. 基于深度学习的端到端标定(如直接回归畸变参数)

下面这张图展示了它们的关系:

畸变参数标定方法分类 标定方法 传统棋盘格标定 直线特征自动标定 深度学习端到端标定 张正友标定法 Tsai两步法 直线校正法 消失点法 参数回归网络 无监督校正 选择建议 • 实验室环境:优先用棋盘格标定,精度最高 • 现场部署:用直线特征法,不需要标定板 • 大规模量产:考虑深度学习,速度快但需要训练数据

3.3.1 传统棋盘格标定

这是最经典的方法。你打印一张棋盘格,从不同角度拍十几张照片,然后让算法自动检测角点,再通过最小二乘法求解畸变参数。

具体步骤:

  1. 采集图像:至少10张,覆盖不同角度和位置
  2. 角点检测:用OpenCV的 findChessboardCorners
  3. 求解内参和畸变:用 calibrateCamera
  4. 验证:用 undistort 检查校正效果

我的习惯:采集图像时,尽量让棋盘格出现在图像的边缘和角落。因为畸变在边缘最明显,如果棋盘格只出现在中心区域,标定出来的参数对边缘畸变几乎没有约束力。我一般会保证每张照片的棋盘格至少覆盖图像面积的30%,并且至少有3张照片的棋盘格靠近图像边缘。

3.3.2 基于直线特征的自动标定

这个方法不需要标定板。它的原理很简单:现实世界中的直线,在畸变图像中应该是曲线。校正的目标就是把这些曲线拉直。

我特别喜欢这个方法的一个场景——户外监控摄像头。你不可能在几十米高的杆子上贴棋盘格,但你可以利用建筑物边缘、道路标线这些天然直线。

算法流程:

  • 从图像中提取直线边缘(如Canny + Hough变换)
  • 定义能量函数:所有直线在校正后应该变成直线
  • 用非线性优化求解畸变参数,使能量函数最小

注意:这个方法对图像质量要求较高。如果场景中直线特征太少,或者直线本身就不直(比如弯曲的马路牙子),优化结果会很不稳定。我曾经在一个仓库场景试过,到处都是货架,直线倒是很多,但货架本身就不完全平行,结果校正出来的图像反而更奇怪了。

3.3.3 基于深度学习的端到端标定

这是近几年兴起的方法。直接用神经网络从图像中回归出畸变参数,或者直接输出校正后的图像。

优点很明显:

  • 速度快:训练好后,单张图像推理只需几毫秒
  • 不需要标定板:只要有大量畸变-校正图像对就行
  • 能处理非标准畸变:比如镜头本身有缺陷的情况

缺点也很明显:

  • 需要大量训练数据:而且数据要覆盖各种畸变程度
  • 泛化能力有限:换一个镜头型号,可能就要重新训练
  • 可解释性差:你很难说清楚网络到底学到了什么

我个人觉得,深度学习标定更适合大规模量产场景——同一款镜头生产几万个,标定参数都差不多,用传统方法一个个标太慢。但如果是做研究或者小批量项目,传统方法更靠谱。

3.4 本章小结

嗯,这一节内容不少,我帮你捋一下核心:

  • 径向畸变是鱼眼的主要畸变,用Brown模型或多项式模型描述
  • 切向畸变是镜头和传感器不平行造成的,千万别忽略
  • 标定方法有三种:传统棋盘格(精度高)、直线特征(无标定板)、深度学习(速度快)