1. 畸变校正基础:什么是镜头畸变?径向畸变与切向畸变的数学模型
大家好,欢迎来到《畸变校正与图像质量调优系统指南》的第一章。
说到镜头畸变,我印象特别深。刚入行那会儿,我拿着刚买的广角镜头去拍建筑,回来一看照片——好好的摩天大楼变成了比萨斜塔。当时我还以为是相机坏了,后来才知道,这就是典型的镜头畸变。
说白了,镜头畸变就是相机“撒谎”了。它拍出来的东西,跟现实世界对不上。你想想看,一个完美的镜头应该把直线拍成直线,把正方形拍成正方形。但现实中的镜头,尤其是广角和变焦镜头,总会带点“私心”。
1.1 畸变从哪来?
我习惯把畸变的原因分成两类:
- 物理原因:透镜是球面的,光线经过不同区域时折射角度不一样。边缘的光线比中心的光线弯得更厉害。
- 机械原因:镜头组在装配时,镜片之间不可能做到平行。哪怕偏了0.1毫米,图像边缘就会变形。
嗯,这里要注意:畸变不是“坏镜头”的专利。哪怕几万块的电影镜头,也有畸变,只是程度不同。我在项目中遇到过客户抱怨“我们用的可是蔡司镜头,怎么还有畸变?”——我只好解释,畸变是物理定律,不是工艺问题。
1.2 径向畸变:镜头“肚子”的问题
径向畸变是最常见的一种。它沿着镜头半径方向发生,说白了就是图像被“撑大”或“挤小”了。
为什么会这样?因为光线经过球面透镜时,边缘的折射率跟中心不一样。离光轴越远,偏差越大。
径向畸变分两种:
| 类型 | 现象 | 常见场景 |
|---|---|---|
| 桶形畸变 | 图像向外膨胀,直线向外弯曲 | 广角镜头、手机前置摄像头 |
| 枕形畸变 | 图像向内收缩,直线向内弯曲 | 长焦镜头、变焦镜头远端 |
我记得有一次做车载环视系统,四个鱼眼镜头全是桶形畸变。如果不校正,拼接出来的俯视图就像哈哈镜一样。那会儿我天天盯着畸变参数调,眼睛都快花了。
径向畸变的数学模型
数学上,我们用多项式来描述径向畸变。假设理想图像坐标为 (x, y),畸变后的坐标为 (xd, yd),径向距离 r = √(x² + y²)。那么:
x_d = x * (1 + k1*r² + k2*r⁴ + k3*r⁶)
y_d = y * (1 + k1*r² + k2*r⁴ + k3*r⁶)
这里 k1、k2、k3 就是径向畸变系数。你想想看,r 越大(越靠近图像边缘),r²、r⁴、r⁶ 增长得越快,畸变就越明显。
1.3 切向畸变:镜头“歪了”的问题
切向畸变,说白了就是镜头没装正。镜片组的光轴没跟成像平面垂直,或者镜片之间有了偏移。
这种现象在手机摄像头里特别常见。你想想,手机那么薄,镜头模组是硬塞进去的,装配公差很难控制。我拆过几台手机摄像头,里面的镜片就靠胶水固定,稍微偏一点,切向畸变就出来了。
切向畸变的表现是:图像中的直线变成斜线,或者图像整体有“倾斜感”。比如拍一个矩形,它可能变成平行四边形。
切向畸变的数学模型
切向畸变用两个参数 p1、p2 来描述:
x_d = x + [2*p1*x*y + p2*(r² + 2*x²)]
y_d = y + [p1*(r² + 2*y²) + 2*p2*x*y]
注意看,这里跟径向畸变不一样。径向畸变只跟 r 有关,而切向畸变跟 x 和 y 的具体位置都有关。所以它造成的变形是不对称的。
1.4 两种畸变的对比
| 对比维度 | 径向畸变 | 切向畸变 |
|---|---|---|
| 根本原因 | 透镜球面折射 | 镜片装配偏差 |
| 变形方向 | 沿半径方向 | 沿切线方向 |
| 对称性 | 中心对称 | 不对称 |
| 参数数量 | 3个 (k1, k2, k3) | 2个 (p1, p2) |
| 常见程度 | 几乎每个镜头都有 | 装配质量差的镜头常见 |
| 校正难度 | 较容易 | 需要精确标定 |
1.5 完整畸变模型
实际应用中,我们把径向和切向畸变合在一起。完整的畸变模型就是:
// 先算径向畸变
x_radial = x * (1 + k1*r² + k2*r⁴ + k3*r⁶)
y_radial = y * (1 + k1*r² + k2*r⁴ + k3*r⁶)
// 再加上切向畸变
x_distorted = x_radial + [2*p1*x*y + p2*(r² + 2*x²)]
y_distorted = y_radial + [p1*(r² + 2*y²) + 2*p2*x*y]
这个模型就是 OpenCV 里 cv::fisheye 和 cv::calibrateCamera 用的标准模型。你如果做过相机标定,应该对这套公式不陌生。
1.6 知识结构图
下面这张图帮你理清本章的知识脉络:
1.7 小结
这一章我们聊了镜头畸变的本质和数学模型。总结几个要点:
- 径向畸变是透镜物理特性导致的,用 k1、k2、k3 描述
- 切向畸变是装配偏差导致的,用 p1、p2 描述
- 完整模型是两者叠加,OpenCV 标定输出的就是这5个参数
- 畸变校正是“反推”过程,不是“正推”
我个人习惯,拿到一个新镜头,第一件事就是做标定,看看它的畸变参数有多大。如果 k1 超过 0.1,那这个镜头的畸变就比较明显了,校正时要特别小心边缘区域。