1. 相机模型与成像原理:小孔成像模型、针孔相机数学模型、世界坐标系到像素坐标系的转换

各位同学,咱们今天聊点硬核的——相机到底是怎么“看”到世界的?

我刚开始接触视觉时,总觉得相机拍照就是个“咔嚓”的事。直到第一次做畸变校正,发现图像边缘怎么都拉不直,才意识到:不懂成像模型,你连相机在干啥都不知道。今天咱们就把这个基础打牢。

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

你想想看,最早的相机长什么样?就是一个黑盒子,前面戳个小孔。光线从物体上反射过来,穿过小孔,在后面的屏幕上形成一个倒立的像。这就是小孔成像

我记得在大学实验室里,老师拿个鞋盒、一张锡纸、一根针,现场给我们演示。蜡烛的火焰倒映在盒底的磨砂纸上,虽然模糊,但原理清清楚楚。

核心要点:

  • 物体通过小孔在成像平面上形成倒立、左右颠倒的实像
  • 像的大小与物距、像距有关:像高 / 物高 = 像距 / 物距
  • 小孔越小,图像越清晰,但亮度越低——这是个矛盾

说白了,小孔成像就是最原始的相机模型。现代相机虽然复杂得多,但数学本质没变

1.2 针孔相机数学模型:从物理到数学

实际相机不能真的用针孔——太暗了。我们得用透镜来聚光。但透镜会引入畸变,这个后面再讲。先看理想情况:针孔相机模型

这个模型做了三个假设:

  1. 光线沿直线传播(不考虑衍射)
  2. 所有光线都通过一个点——光心
  3. 成像平面是完美的平面

嗯,这里要注意:真实相机并不完全满足这些假设,但作为近似,它已经足够用了。我在做标定时,90%的情况用这个模型就能搞定。

数学上,针孔模型用相似三角形来描述:

设三维空间中一点 P = (X, Y, Z),投影到成像平面上的点 p = (x, y)
则有:
  x = f * X / Z
  y = f * Y / Z

其中 f 是焦距(光心到成像平面的距离)

你看,就这么简单。一个除法,把三维降到了二维。但这里有个坑:Z 不能为 0,否则除零错误。实际中我们也不会把物体贴在镜头上拍。

1.3 世界坐标系到像素坐标系的转换

好,现在问题来了:我们拍照时,物体在真实世界中,而照片是像素组成的。怎么把世界坐标 (X, Y, Z) 变成像素坐标 (u, v)?

这需要经过四步变换,我习惯把它拆成两个阶段:

我的记忆口诀:「世界→相机→归一化→像素」

阶段一:刚体变换(世界→相机)

把物体从世界坐标系转到相机坐标系。说白了就是旋转 + 平移

[X_c]   [R   t] [X_w]
[Y_c] = [      ] [Y_w]
[Z_c]   [0   1] [Z_w]
[1  ]             [1  ]

其中 R 是 3×3 旋转矩阵,t 是 3×1 平移向量

我曾经在项目中犯过一个低级错误:把旋转矩阵写反了。结果标定出来的点全跑到相机后面去了。排查了整整两天……嗯,从那以后我每次都会检查 R 矩阵的行列式是不是 1。

阶段二:透视投影(相机→归一化平面)

这一步就是针孔模型的除法:

x_n = X_c / Z_c
y_n = Y_c / Z_c

得到的是归一化坐标,单位是「米/米」,无量纲。这个坐标很重要,因为畸变校正就是在这个平面上做的

阶段三:畸变校正(可选但重要)

真实镜头有畸变,主要是径向畸变(桶形/枕形)和切向畸变(镜头装配误差)。

我建议你记住这个公式:

x_corrected = x_n * (1 + k1*r^2 + k2*r^4 + k3*r^6) + 2*p1*x_n*y_n + p2*(r^2 + 2*x_n^2)
y_corrected = y_n * (1 + k1*r^2 + k2*r^4 + k3*r^6) + p1*(r^2 + 2*y_n^2) + 2*p2*x_n*y_n

其中 r^2 = x_n^2 + y_n^2
k1, k2, k3 是径向畸变系数
p1, p2 是切向畸变系数

避坑指南:我曾经在标定时用了 5 阶径向畸变模型,结果过拟合了。对于普通镜头,k1, k2 就够了,鱼眼镜头才需要 k3。别贪多。

阶段四:像素映射(归一化→像素)

最后一步,把归一化坐标变成像素坐标:

u = fx * x_corrected + cx
v = fy * y_corrected + cy

其中 fx, fy 是焦距(像素单位)
cx, cy 是主点坐标(光心在像素平面上的位置)

这四个参数 (fx, fy, cx, cy) 就是相机内参。每个相机都不一样,需要标定得到。

1.4 知识体系总览

说了这么多,咱们用一张图把整个流程串起来:

世界坐标系 → 像素坐标系 完整流程 世界坐标系 (X_w, Y_w, Z_w) 相机坐标系 (X_c, Y_c, Z_c) 归一化平面 (x_n, y_n) 像素坐标系 (u, v) 刚体变换 R, t 透视投影 除以 Z_c 畸变校正 k1,k2,p1,p2 像素映射 fx, fy, cx, cy 一句话总结 世界坐标 → 旋转平移 → 相机坐标 → 除以 Z → 归一化坐标 → 畸变校正 → 内参缩放平移 → 像素坐标 整个过程就是「刚体变换 + 透视投影 + 畸变校正 + 像素映射」

1.5 实战中的坑与经验

最后,分享几个我踩过的坑:

常见问题 现象 解决办法
主点偏差大 校正后图像中心偏移 重新标定,检查标定板是否在视野中央
焦距不准 校正后图像缩放异常 用不同距离的标定图像,增加约束
畸变系数过拟合 边缘出现波浪形扭曲 减少畸变参数阶数,只用 k1, k2
Z 值太小 近处物体畸变严重 标定时保持标定板与相机距离适中

我的建议:刚开始做标定时,别急着用高级模型。先用最简单的针孔模型 + 2 个径向畸变参数,跑通了再慢慢加。我见过太多人一上来就搞 5 参数、8 参数,结果越调越乱。

好了,这一章的内容就是这些。记住:相机模型是视觉的基石,后面的畸变校正、立体匹配、三维重建,全都建立在这个基础上。把今天的内容吃透,后面你会轻松很多。


公众号:蓝海资料掘金营,微信deep3321