2. 畸变模型概述
聊鱼眼镜头校正之前,咱们得先把“畸变”这回事儿掰扯清楚。说白了,畸变就是镜头拍出来的像,跟理想的小孔成像对不上号了。你想想看,一个完美的针孔相机模型,光线直来直去,像和物是严格的线性关系。但现实中的镜头是一堆透镜组,光线穿来穿去,不出点偏差才怪。
我个人习惯把畸变分成两大类:一类是镜头本身的光学设计带来的,另一类是装配工艺导致的。鱼眼镜头呢,它更特殊——它故意引入巨大的畸变来换取超广视角,所以它的模型跟普通镜头还不一样。
径向畸变:镜头天生的“肚子”
径向畸变是最常见的一种。光线通过透镜边缘时,折射角度跟中心不一样,结果就是画面边缘的直线变弯了。我刚开始做相机标定时,拍了一张棋盘格,一看边缘的格子全歪了,当时还以为相机坏了。
径向畸变分两种:
- 桶形畸变:画面向外鼓,像木桶。鱼眼镜头尤其明显。
- 枕形畸变:画面向内缩,像枕头。长焦镜头常见。
数学上,我们用多项式来近似这种畸变。设归一化坐标中的点为 (x, y),畸变后的点为 (xd, yd):
x_d = x * (1 + k1 * r² + k2 * r⁴ + k3 * r⁶)
y_d = y * (1 + k1 * r² + k2 * r⁴ + k3 * r⁶)
其中 r² = x² + y²,k1、k2、k3 就是径向畸变系数。r 越大,畸变越严重。嗯,这里要注意:k3 通常只在鱼眼镜头或大畸变镜头中才用,普通镜头用 k1、k2 就够了。
切向畸变:装配没对齐的“锅”
切向畸变,也叫离心畸变。原因是透镜组的光心不在一条直线上,或者传感器跟镜头不平行。说白了,就是装配公差。
我曾经遇到过一台工业相机,拍出来的图像总有一边模糊,标定后发现切向畸变系数特别大。拆开一看,果然是镜头座歪了。
切向畸变的模型是这样的:
x_d = x + [2 * p1 * x * y + p2 * (r² + 2 * x²)]
y_d = y + [p1 * (r² + 2 * y²) + 2 * p2 * x * y]
p1、p2 就是切向畸变系数。这个模型在 OpenCV 的 calibrateCamera 里是默认一起估计的。
鱼眼镜头特有的畸变模型
普通镜头的畸变模型,本质上是基于“入射角的正切”来建模的。但鱼眼镜头不一样——它的视角可以到 180° 甚至 220°,如果用正切模型,边缘的像素会被拉伸到无穷远,根本没法用。
所以鱼眼镜头采用了不同的投影方式。说白了,就是故意用非线性映射,把大视角压缩到有限的传感器上。常见的投影模型有四种:
| 投影模型 | 映射关系 | 特点 |
|---|---|---|
| 等距投影 | r = f * θ | 角度与像高成正比,最常用 |
| 等立体角投影 | r = 2f * sin(θ/2) | 单位立体角对应等面积 |
| 正交投影 | r = f * sin(θ) | 边缘压缩最严重 |
| 体视投影 | r = 2f * tan(θ/2) | 保持局部形状 |
其中 θ 是入射角,f 是焦距,r 是像高。你想想看,当 θ = 90° 时,等距投影的 r = f * π/2,而正交投影的 r = f。同样的视角,正交投影的像高更小,所以边缘压缩更厉害。
我个人在实际项目中最常用的是 等距投影模型。OpenCV 的鱼眼标定模块(fisheye::calibrate)默认用的就是它。为什么呢?因为它的数学形式简单,而且跟实际镜头的物理设计最接近——很多鱼眼镜头的光学设计就是按等距投影来的。
四种投影模型的对比
为了让你更直观地理解它们的区别,我画了一张对比图。横轴是入射角 θ(0° 到 180°),纵轴是归一化像高 r/f:
从图上能看出来:
- 等距投影(蓝线)是线性关系,最直观。
- 等立体角投影(红线)在边缘有轻微压缩。
- 正交投影(绿线)到 180° 时像高为 0,所以实际视角有限。
- 体视投影(紫线)在边缘拉伸最厉害,但局部形状保持最好。
我在做全景拼接项目时,遇到过一个问题:用等距投影标定后,拼接出来的图像边缘有重影。后来发现是镜头实际用的是等立体角投影,而我用了等距模型去校正。换回等立体角模型后,问题就解决了。所以,选对投影模型很重要。
OpenCV 中的鱼眼畸变模型
OpenCV 的鱼眼模块用的是 等距投影 + 多项式畸变 的混合模型。它的完整形式是:
θ_d = θ * (1 + k1 * θ² + k2 * θ⁴ + k3 * θ⁶ + k4 * θ⁸)
x_d = (θ_d / r) * x
y_d = (θ_d / r) * y
其中 θ 是入射角,r = sqrt(x² + y²)。这个模型的好处是:它把投影模型和畸变解耦了。先通过等距投影把角度映射到像高,再用多项式修正残余畸变。
小结一下
这一章我们聊了:
- 径向畸变:透镜曲率带来的,用多项式修正。
- 切向畸变:装配误差带来的,用两个参数修正。
- 鱼眼投影模型:四种常见模型,等距投影最常用。
- OpenCV 的鱼眼模型:等距投影 + 多项式畸变。