3. 相机模型与坐标系:针孔相机模型、世界坐标系、相机坐标系、图像坐标系、像素坐标系及其转换关系
做深度图与彩色图对齐,说白了就是搞清楚「每个像素点到底对应现实世界中的哪个点」。
我刚开始接触这个领域时,觉得坐标系转换特别绕。什么世界坐标、相机坐标、图像坐标……一堆名词砸过来。后来在项目里踩了几次坑,才真正理解——这其实就是一套「定位系统」。
你想想看,现实中的一个点,要变成照片上的一个像素,中间经历了什么?
嗯,这就是我们今天要聊的核心。
3.1 针孔相机模型:最朴素的成像原理
先说说针孔相机模型。它是最简单、最经典的成像模型,也是我们理解相机工作的基础。
说白了,就是一个小黑盒,前面开个小孔,光线穿过小孔,在后面的感光平面上成像。这个模型虽然简单,但几乎所有现代相机的几何关系,都是基于它推导出来的。
核心参数:
- 光心:小孔的位置,也就是相机坐标系的原点
- 焦距 f:光心到成像平面的距离
- 主点:光轴与成像平面的交点
我在项目中遇到过一个问题:用手机拍棋盘格标定,结果算出来的焦距总是偏大。后来发现,是因为手机镜头不是真正的「针孔」,而是有畸变的透镜组。所以实际应用中,我们通常会用针孔模型做近似,再配合畸变校正。
我的经验:针孔模型是「理想情况」。真实相机有畸变、有偏移,但没关系——我们先用这个模型理解几何关系,再通过标定去修正偏差。
3.2 四大坐标系:从世界到像素的「传送带」
一个现实中的点,要变成图像上的像素,需要经过四个坐标系的转换。我习惯把它们比作一条「传送带」:
- 世界坐标系 (Xw, Yw, Zw):现实世界的绝对位置。单位是米或毫米。
- 相机坐标系 (Xc, Yc, Zc):以相机光心为原点。Z轴指向相机前方。
- 图像坐标系 (x, y):在成像平面上,以主点为原点。单位是毫米。
- 像素坐标系 (u, v):在图像上,以左上角为原点。单位是像素。
为什么会需要这么多坐标系?
因为每个环节的「度量衡」不一样。世界坐标系是三维的、物理的;像素坐标系是二维的、离散的。中间需要一步步转换。
3.3 转换关系:一步步拆解
3.3.1 世界坐标系 → 相机坐标系(刚体变换)
这一步是三维空间中的旋转和平移。说白了,就是把世界坐标「搬到」相机坐标系下。
// 刚体变换公式
[Xc] [R t] [Xw]
[Yc] = [ ] [Yw]
[Zc] [0 1] [Zw]
[1 ] [1 ]
// 其中 R 是 3x3 旋转矩阵,t 是 3x1 平移向量
我记得有一次做双目视觉标定,左右相机的 R 和 t 算出来总是对不上。后来发现,是我把旋转矩阵的符号搞反了。嗯,这里要特别小心——旋转矩阵是正交矩阵,它的逆等于它的转置。
3.3.2 相机坐标系 → 图像坐标系(透视投影)
这一步是三维到二维的投影。利用相似三角形原理:
x = f * (Xc / Zc)
y = f * (Yc / Zc)
这里有个关键点:Zc 不能为 0。如果物体正好在相机光心所在的平面上,那它在图像上就「消失」了。我在做深度图对齐时,就遇到过这种极端情况——一个平面物体贴得太近,结果深度图全是噪点。
避坑指南:我曾经在项目中直接用这个公式,忘了考虑 Zc 为负的情况(物体在相机后方)。结果渲染出来的图像是镜像的。所以,记得加一个判断:Zc > 0 才有效。
3.3.3 图像坐标系 → 像素坐标系(离散化)
这一步最简单,就是把毫米单位的坐标,变成像素单位的坐标。
u = x / dx + u0
v = y / dy + v0
// 其中 dx, dy 是每个像素的物理尺寸(毫米/像素)
// u0, v0 是主点在像素坐标系中的位置
说白了,就是缩放加平移。我习惯把 dx 和 dy 叫做「像素密度」——它决定了你的相机分辨率有多高。
3.4 完整转换公式:一张图说清楚
把上面三步串起来,就是完整的投影公式:
Zc * [u] [fx 0 u0 0] [R t] [Xw]
[v] = [0 fy v0 0] [ ] [Yw]
[1] [0 0 1 0] [0 1] [Zw]
[ ] [1 ]
// 其中 fx = f/dx, fy = f/dy
这个公式,就是深度图与彩色图对齐的数学基础。你想想看,深度图里的每个像素,其实都对应一个 (Xw, Yw, Zw) 的世界坐标。而彩色图里的每个像素,也对应一个 (u, v) 的像素坐标。对齐,就是找到这两者之间的映射关系。
3.5 实际应用中的注意事项
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 深度图与彩色图不对齐 | 两个相机的内参、外参不同 | 联合标定,计算相对位姿 |
| 图像边缘畸变严重 | 镜头畸变(径向、切向) | 标定后做畸变校正 |
| Zc 为负导致图像翻转 | 物体在相机后方 | 检查深度值范围,过滤无效点 |
| 像素坐标出现小数 | 投影计算结果是浮点数 | 双线性插值或最近邻插值 |
我的习惯:在做深度图对齐前,先单独验证每个坐标系的转换是否正确。比如,先拿一个已知世界坐标的点,手动算一遍像素坐标,看和实际图像上的位置是否吻合。这一步能帮你发现很多隐藏问题。
好了,关于相机模型和坐标系,我们就聊到这里。记住一句话:对齐的本质,就是找到从世界坐标到像素坐标的映射关系。后面的章节,我们会在这个基础上,深入讨论具体的对齐算法和工程实现。
公众号:蓝海资料掘金营,微信deep3321