相机成像模型:从三维世界到二维像素
做RGBD相机标定,绕不开一个核心问题:相机到底是怎么看到世界的?
说白了,相机成像就是把三维空间里的点,映射到二维图像上。这个过程,我们用一个数学模型来描述。今天我就带你把这个模型拆开揉碎了讲清楚。
核心要点:相机成像模型 = 针孔模型(理想情况) + 畸变模型(实际情况)
1. 针孔相机模型:最朴素的成像原理
针孔相机模型,是所有相机模型的基础。它假设光线通过一个小孔,在后面的成像平面上形成倒像。嗯,这里要注意,我们实际用的相机都有镜头,但数学上我们把它等效成针孔模型来处理。
我个人习惯把针孔模型理解成一个相似三角形的问题。你看:
- 三维空间点 P(X, Y, Z)
- 成像平面上的点 p(x, y)
- 焦距 f(光心到成像平面的距离)
根据相似三角形,有:
x = f * (X / Z)
y = f * (Y / Z)
就这么简单。但实际中,我们用的像素坐标,不是物理坐标。所以需要引入像素坐标系。
2. 相机内参矩阵:从物理坐标到像素坐标
我在项目中遇到过一个问题:明明算出来的物理坐标是对的,但映射到图像上就是偏的。后来发现,是没考虑像素坐标系的原点偏移。
像素坐标系的原点通常在图像的左上角,而物理坐标系的原点在光轴上。所以我们需要一个转换矩阵——相机内参矩阵 K。
K = [fx 0 cx
0 fy cy
0 0 1]
其中:
- fx, fy:焦距在x、y方向上的像素尺度(单位:像素)
- cx, cy:光心在像素坐标系中的位置(单位:像素)
完整的投影公式就变成了:
像素坐标 = K * [R|t] * 世界坐标
这里 [R|t] 是相机的外参,描述相机在世界坐标系中的位置和姿态。不过那是另一章的内容了,今天我们先聚焦内参。
我的经验:标定内参时,我建议至少拍20张不同角度的棋盘格照片。角度要覆盖各个方向,尤其是边缘区域。我曾经只拍了10张,结果标定出来的fx和fy差了2个像素,后来补拍才解决。
3. 畸变模型:现实总是不完美的
你想想看,针孔模型是理想情况。但实际镜头有透镜,透镜就会引入畸变。说白了,就是图像变形了。
畸变主要分两种:
3.1 径向畸变
径向畸变是沿着镜头半径方向的变形。越靠近图像边缘,变形越明显。我最早做标定时,拍出来的棋盘格边缘都是弯的,就是径向畸变在作怪。
数学模型用泰勒级数展开来近似:
x_distorted = x * (1 + k1*r^2 + k2*r^4 + k3*r^6)
y_distorted = y * (1 + k1*r^2 + k2*r^4 + k3*r^6)
其中 r^2 = x^2 + y^2,k1、k2、k3 是径向畸变系数。
这里有个坑:k3 通常只用于鱼眼镜头。普通镜头用 k1、k2 就够了。我曾经在标定普通镜头时强行加了 k3,结果过拟合,反而把图像搞得更扭曲了。
3.2 切向畸变
切向畸变是因为镜头和成像平面不平行造成的。说白了,就是镜头装歪了。
数学模型:
x_distorted = x + [2*p1*x*y + p2*(r^2 + 2*x^2)]
y_distorted = y + [p1*(r^2 + 2*y^2) + 2*p2*x*y]
p1、p2 是切向畸变系数。
避坑指南:我曾经在标定一个工业相机时,发现切向畸变系数特别大。排查了半天,发现是镜头接口的螺丝没拧紧。所以,标定前先检查硬件,别上来就调参数。
4. 完整畸变模型
把径向和切向畸变合在一起,就是完整的畸变模型:
// 畸变参数向量: [k1, k2, p1, p2, k3]
// 通常我们只标定前4个或5个参数
// 去畸变流程:
// 1. 计算归一化坐标 (x, y)
// 2. 计算 r^2 = x^2 + y^2
// 3. 计算径向畸变系数
// 4. 计算切向畸变系数
// 5. 得到畸变后的坐标
实际标定时,OpenCV 的 calibrateCamera() 函数会帮我们自动求解这些参数。但理解背后的原理,能帮你更好地判断标定结果是否合理。
5. 知识体系总览
下面这张图,是我自己整理的相机成像模型知识结构。你看一眼,就能把今天讲的内容串起来:
6. 实际标定中的注意事项
| 参数 | 典型值范围 | 我的经验 |
|---|---|---|
| fx, fy | 500 ~ 2000 像素 | 两个值越接近,说明镜头质量越好 |
| cx, cy | 图像中心附近 | 如果偏离超过20像素,检查镜头安装 |
| k1, k2 | -0.5 ~ 0.5 | 绝对值大于0.1时,畸变已经很明显了 |
| p1, p2 | -0.05 ~ 0.05 | 超过0.01就要检查硬件了 |
我的建议:标定完成后,一定要做重投影误差检查。如果平均误差超过0.5像素,说明标定质量不够好。我一般要求控制在0.3像素以内。
好了,相机成像模型这部分就讲到这里。记住三个核心:针孔模型是基础,内参矩阵是桥梁,畸变模型是修正。搞懂这些,你就能理解相机标定到底在干什么了。
公众号:蓝海资料掘金营,微信deep3321