1. 相机成像原理:从光线到像素的奇妙旅程

大家好,我是你们这门课的老师。今天咱们来聊聊相机成像原理——说白了,就是搞明白「光线是怎么变成照片的」。这个基础打不牢,后面做标定和三维重建就容易踩坑。我自己刚入行时也在这上面吃过亏,所以今天咱们好好捋一捋。

1.1 小孔成像模型:最朴素的相机

先说说最原始的小孔成像。你想想看,一个黑盒子,前面戳个小孔,光线穿过小孔,在后面的屏幕上形成倒立的像。这就是相机最根本的原理。

为什么像是倒立的?因为光线是直线传播的。物体上方的光线穿过小孔打到屏幕下方,下方的光线打到上方,自然就颠倒了。嗯,这个大家初中物理都学过。

小孔成像有个关键参数——像距(小孔到屏幕的距离)。像距决定了成像的大小。物体离得越远,像越小;小孔离屏幕越远,像越大。这个关系很简单:

像的大小 / 物体的大小 = 像距 / 物距

我在项目中遇到过用针孔相机做实验的情况。说实话,小孔成像虽然原理简单,但实际用起来问题不少——小孔太小,进光量不足,图像太暗;小孔太大,图像又模糊。所以现代相机都不这么干了。

小技巧: 小孔成像模型虽然不实用,但它是理解相机几何关系的基石。后面讲相机标定时,很多公式都是从这儿推导出来的。

1.2 针孔相机模型:理想化的数学抽象

针孔相机模型,其实就是把小孔成像数学化了。它假设光线严格直线传播,没有畸变,没有模糊。说白了,这是一个理想化的模型。

在这个模型里,我们引入几个关键概念:

  • 光心:相当于小孔的位置,记作 O
  • 主光轴:过光心且垂直于成像平面的直线
  • 焦距 f:光心到成像平面的距离
  • 成像平面:感光元件所在的位置

数学上,针孔相机模型可以用一个 3x4 的投影矩阵来表示。这个矩阵把三维世界中的点 (X, Y, Z) 映射到二维图像上的点 (u, v)。公式长这样:

s * [u, v, 1]^T = K * [R | t] * [X, Y, Z, 1]^T

其中:

  • s 是尺度因子(深度信息)
  • K 是相机内参矩阵(焦距、主点等)
  • [R | t] 是相机外参(旋转和平移)

我个人习惯把内参矩阵 K 记成「相机自己的参数」,外参 [R | t] 记成「相机在世界中的位置」。这样好理解多了。

重点: 针孔相机模型是所有相机标定算法的基础。OpenCV 的 cv::calibrateCamera() 函数就是基于这个模型来求解相机参数的。

1.3 透镜畸变:现实世界的无奈

理想很丰满,现实很骨感。针孔相机模型假设光线完美直线传播,但实际相机用的是透镜。透镜嘛,总会带来各种畸变。我最早做标定时,就因为这个畸变没处理好,重建出来的三维模型歪歪扭扭的,跟哈哈镜似的。

畸变主要分两种:径向畸变切向畸变

1.3.1 径向畸变

径向畸变是透镜形状引起的。说白了,就是透镜边缘和中心对光线的折射程度不一样。离光轴越远,畸变越明显。

径向畸变有两种:

  • 桶形畸变:图像边缘向外凸出,像木桶一样。广角镜头常见。
  • 枕形畸变:图像边缘向内凹陷,像枕头一样。长焦镜头常见。

数学上,径向畸变用三个参数 k1, k2, k3 来描述。校正公式是:

x_corrected = x * (1 + k1*r^2 + k2*r^4 + k3*r^6)
y_corrected = y * (1 + k1*r^2 + k2*r^4 + k3*r^6)

其中 r 是像素点到光心的距离。注意,k3 一般只在畸变特别严重时才用,比如鱼眼镜头。

避坑指南: 我曾经在标定一个广角相机时,只用了 k1 和 k2,结果边缘区域始终校正不好。后来加上 k3 才搞定。所以,如果你的镜头畸变明显,别省 k3。

1.3.2 切向畸变

切向畸变是透镜和成像平面不平行引起的。说白了,就是镜头装歪了。这种情况在工业相机中比较常见,尤其是那些便宜货。

切向畸变用两个参数 p1, p2 来描述:

x_corrected = x + [2*p1*x*y + p2*(r^2 + 2*x^2)]
y_corrected = y + [p1*(r^2 + 2*y^2) + 2*p2*x*y]

嗯,公式看着有点复杂,但 OpenCV 已经帮我们封装好了。你只需要提供畸变参数向量 [k1, k2, p1, p2, k3] 给 cv::undistort() 函数就行。

1.4 相机坐标系与世界坐标系

搞清楚了畸变,咱们再来看看坐标系。这是三维重建中最容易搞混的地方。我见过不少新手,坐标系没理清,重建出来的模型位置全乱套了。

相机成像涉及四个坐标系:

坐标系 说明 单位
世界坐标系 描述物体在真实世界中的位置,是全局参考系 米/毫米
相机坐标系 以相机光心为原点,Z轴指向镜头前方 米/毫米
图像坐标系 在成像平面上,以光轴与平面的交点为原点 毫米
像素坐标系 在图像上,以左上角为原点,单位是像素 像素

它们之间的转换关系是这样的:

  1. 世界 → 相机:通过外参 [R | t] 变换。R 是旋转矩阵,t 是平移向量。
  2. 相机 → 图像:通过内参 K 投影。把三维点投影到二维平面上。
  3. 图像 → 像素:通过缩放和平移,把物理尺寸变成像素坐标。

举个例子。假设世界坐标系中有一个点 P = (X, Y, Z)。它在相机坐标系中的坐标是:

P_cam = R * P + t

然后投影到图像平面:

x = f * X_cam / Z_cam
y = f * Y_cam / Z_cam

最后转成像素坐标:

u = fx * x + cx
v = fy * y + cy

其中 fx, fy 是焦距的像素表示,cx, cy 是主点坐标。

我的经验: 做标定时,我习惯把棋盘格放在世界坐标系的 Z=0 平面上。这样外参求解会简单很多。另外,记得检查你的相机坐标系是右手系还是左手系——OpenCV 用的是右手系。

1.5 总结一下

今天咱们讲了相机成像的四个核心概念:

  • 小孔成像模型:最朴素的成像原理,光线直线传播
  • 针孔相机模型:数学化的理想模型,是标定的理论基础
  • 透镜畸变:径向畸变(桶形/枕形)和切向畸变(镜头装歪)
  • 坐标系变换:世界→相机→图像→像素,四步走

这些概念看着多,但说白了就是一件事——搞清楚光线是怎么从物体跑到像素上的。后面讲相机标定时,我们会用 OpenCV 把这些公式一一实现。到时候你会发现,数学公式虽然枯燥,但跑通代码的那一刻,还是挺有成就感的。

下一章咱们聊标定板的制作和图像采集。记得提前打印好棋盘格,咱们动手干起来。