1. 引言

鱼眼镜头因其独特的视觉效果,在创意摄影中越来越受欢迎。它与移轴镜头、长焦镜头和广角镜头并列为四大特殊镜头类型。与普通“针孔”相机不同,鱼眼镜头使用了一种特殊的投影方式,从而产生显著的桶形畸变。

在本文中,我们将介绍如何通过编程手段校正这种畸变,将鱼眼图像转换为“直线”图像,使其更符合人类视觉习惯。

2. 理解相机参数

我们关心的核心问题是:如何将空间中的一个三维点 X 投影到二维图像平面上的坐标 x 上。这个过程可以用如下公式表示:

x = PX

其中,P 变换矩阵又可进一步分解为 5 个内参和 6 个外参

x = K R [I_3|-X_0] X

2.1. 外参(Extrinsic Parameters)

外参描述了相机在世界坐标系中的位置和姿态,包括三个旋转参数 R 和三个平移参数 [I_3|-X_0],分别对应宽度、高度和深度方向上的位移。

这些参数决定了相机相对于场景的“视角”,在三维重建、SLAM 等任务中尤为重要。

2.2. 内参(Intrinsic Parameters)

内参描述了相机传感器如何将三维世界点映射到二维图像平面,是图像校正、投影变换的基础。通常用一个 3x3 的矩阵 K 表示:

K =\begin{pmatrix}f_x & s & x_0 \\0 & f_y & y_0\\0 & 0 & 1 \end{pmatrix}

其中各元素含义如下:

参数 含义
f_x x 方向的焦距
f_y y 方向的焦距
s 剪切变换参数
x_0 主点在 x 轴上的偏移
y_0 主点在 y 轴上的偏移

这个矩阵在 OpenCV 中被广泛使用,详见其官方文档

2.3. 总体变换矩阵

经过简化后,我们可以将整个变换表示为如下矩阵形式:

\begin{pmatrix}x\\ y \\1 \end{pmatrix} =\begin{pmatrix}f_x & s & x_0 \\0 & f_y & y_0\\0 & 0 & 1 \end{pmatrix}\begin{pmatrix}r_1_1 & r_1_2 & t_1 \\ r_2_1 & r_2_2 & t_2\\r_3_1 & r_3_2 & t_3 \end{pmatrix}\begin{pmatrix}X\\ Y \\1 \end{pmatrix}

或简化为:

\begin{pmatrix}x\\ y \\1 \end{pmatrix} = K [r_1,r_2,t] \begin{pmatrix}X\\ Y \\1 \end{pmatrix}

我们之所以只用 XY 来表示目标坐标,是因为我们假设标定目标是平的,比如常见的棋盘格。

3. 鱼眼镜头类型

不同类型的鱼眼镜头有不同的畸变模型,了解这些类型有助于我们更准确地进行图像校正。常见的鱼眼镜头类型包括:

3.1. 直线投影(Rectilinear)

这类镜头相当于普通针孔相机,图像中直线保持为直线,但视角必须小于 90°,整体视角不能超过 180°。

✅ 优点:保留直线
❌ 缺点:视角有限,设计难度大,价格高

rectilinear

3.2. 立体投影(Stereographic)

保持角度不变,边缘区域压缩较小。

✅ 优点:保留角度
❌ 缺点:边缘细节略显模糊

Stereographic

常见镜头:

  • Samyang f = 8 mm f/2.8
  • Samyang f = 12 mm f/2.8

3.3. 等距投影(Equidistant)

保持角距离不变,适合角度测量应用。

✅ 优点:适合测量角度
❌ 缺点:边缘拉伸明显

Equidistant

常见镜头:

  • Canon FD f = 7.5 mm f/5.6
  • Nikkor f = 8 mm f/2.8
  • Samyang f = 7.5 mm f/3.5

3.4. 等立体角投影(Equisolid Angle)

保持面积不变,图像看起来像球面反射,是目前最常见的鱼眼类型。

✅ 优点:最常见,通用性强
❌ 缺点:边缘压缩明显

EquisolidAngle

常见镜头:

  • Canon EF f = 15 mm f/2.8
  • Sigma f = 8 mm f/4.0
  • Zuiko f = 8 mm f/2.8

3.5. 正射投影(Orthographic)

保持平面照度不变,中心图像压缩较小,边缘严重失真。

❌ 缺点:边缘失真严重,不适用于大多数场景

Orthographic

常见镜头:

  • Nikkor f = 10 mm f/5.6
  • Yasuhara Madoka180 f = 7.3 mm f/4

4. 示例演示

我们可以使用 FisheyeGl 这个 JavaScript WebGL 库来快速校正一张鱼眼图像。

我们以这张 APS-C 传感器拍摄的 75mm 鱼眼照片为例:

75mmOnAPS C

加载到 FisheyeGl 后,设置如下参数:

  • f_x = 0.26
  • f_y = 0.26
  • Scale = 0.7
  • ab 保持默认值 1

最终输出图像如下:

undistorting end2

可以看到图像边缘的线条被拉直了,但图像边缘也出现了明显的拉伸变形。我们通过设置 Scale 为 0.7 来控制输出图像尺寸。

⚠️ 注意:手动调整参数效果有限,因为该模型是线性的,无法完全拟合复杂畸变。

5. 畸变与相机标定

如果我们希望对某款相机进行高精度的图像校正,最可靠的方式是使用标定板进行相机标定。

5.1. Zhang’s 方法

由微软在 1999 年提出的一种灵活的相机标定方法,被称为 Zhang's Method,是目前最广泛使用的标定算法之一。

其核心思想是通过拍摄多个不同角度的棋盘格图像,提取角点信息,从而估计相机的内参和畸变系数。

5.2. 线性参数估计

对于棋盘格中的每一个点,我们都可以建立如下方程:

\begin{pmatrix}x\\ y \\1 \end{pmatrix} =\begin{pmatrix}f_x & s & x_0 \\0 & f_y & y_0\\0 & 0 & 1 \end{pmatrix}\begin{pmatrix}r_1_1 & r_1_2 & t_1 \\ r_2_1 & r_2_2 & t_2\\r_3_1 & r_3_2 & t_3 \end{pmatrix}\begin{pmatrix}X\\ Y \\1 \end{pmatrix}

通过建立多个这样的方程,我们可以构建一个 3x3 的单应性矩阵 H,并从中提取相机矩阵 K

具体步骤如下:

  1. 利用 K, r_1, r_2 的约束条件
  2. 定义矩阵 B = K^{-T} K^{-1}
  3. 解一个齐次线性系统得到 B
  4. B 进行分解得到 K

5.3. 非线性参数估计

为了更准确地建模畸变,通常使用如下公式:

$$ x^a = x(1+q_1 r^2 + q_2 r^4) $$ $$ y^a = y(1+q_1 r^2 + q_2 r^4) $$

其中:

  • r 是像素点到主点的距离
  • q_1q_2 是径向畸变系数

最终目标是通过最小化如下误差函数来优化参数:

$$ \Sigma_n\Sigma_i || x_{ni}-^{x}(K,q,R_n,t_n,X_{ni})||^2 $$

6. OpenCV 实现

OpenCV 是目前最流行的计算机视觉库之一,它提供了非常完善的相机标定接口。

通过 OpenCV 的标定教程,我们可以自动检测棋盘格角点,并输出相机内参矩阵和畸变系数,效果如下图所示:

camera calibration checkerboard2

多张图像可以提高标定精度,因为每张图像都提供了更多的标定点信息。

📌 提示:如果是热成像相机,也可以使用专门的标定板,方法与可见光相机一致。

OpenCV 标定教程详见:OpenCV Calibration Tutorial

7. 小结

本文系统介绍了鱼眼图像的校正原理与实现方法,包括:

  • 相机参数(内参、外参)的基本概念
  • 不同类型的鱼眼镜头及其畸变模型
  • 使用参数校正鱼眼图像的流程
  • 基于 Zhang 方法的相机标定理论
  • OpenCV 实现与示例演示

通过这些知识,我们可以更准确地对鱼眼图像进行校正,提升图像质量,为后续的图像处理、视觉定位等任务打下基础。


原始标题:Correcting Fisheye Images