摄像头传感器原理:从光子到像素的旅程
各位同学,今天我们来聊聊摄像头传感器。这是座舱感知的「眼睛」,选错传感器,后面算法再牛也白搭。
我在车载摄像头项目里摸爬滚打了好几年,踩过不少坑。今天就把这些经验掰开揉碎了讲给你听。
一、CMOS 与 CCD 传感器:两种「底片」的较量
先问个问题:为什么现在车载摄像头几乎全是 CMOS,没人用 CCD 了?
说白了,就是「速度」和「成本」的博弈。
| 对比项 | CCD | CMOS |
|---|---|---|
| 读出方式 | 逐行扫描,统一输出 | 每个像素独立读出 |
| 功耗 | 高(约 CMOS 的 10 倍) | 低 |
| 噪声 | 低,画质干净 | 早期噪声大,现在已改善 |
| 帧率 | 受限,难上 60fps | 轻松 120fps 甚至更高 |
| 成本 | 高 | 低 |
| 车载适用性 | 差(发热、帧率低) | 优 |
CCD 的优点是画质好、噪声低。但它的致命伤是读出速度慢。你想想看,座舱里要捕捉驾驶员打哈欠、转头这些瞬间动作,帧率低于 60fps 根本不行。CCD 跑不到那么快。
CMOS 就不一样了。每个像素自带放大器,可以并行读出。我做过一个项目,用 CMOS 传感器跑 120fps,捕捉眼球运动毫无压力。CCD 在这个场景下直接「糊片」。
关键结论:车载座舱场景,选 CMOS 是唯一合理的选择。CCD 更适合工业检测、天文摄影这类对画质要求极高、对速度不敏感的场景。
我的经验:选 CMOS 时别只看分辨率。像素尺寸同样重要。座舱内光线变化大,2.8μm 以上的像素尺寸能保证低照度下的信噪比。我曾经贪便宜选了 1.4μm 的小像素传感器,结果黄昏时分人脸全是噪点,算法直接罢工。
二、RGB 与 IR 摄像头:看得见与看不见的光
人眼能看到的叫可见光,波长 380-780nm。RGB 摄像头就是模拟人眼的。但座舱里有个特殊需求——夜间驾驶。
这时候就需要 IR(红外)摄像头了。它能看到 850nm 或 940nm 的近红外光。配合车内的红外补光灯,在全黑环境下也能看清驾驶员的脸。
我见过不少方案把 RGB 和 IR 分开做两个摄像头。但这样会带来一个问题:两个摄像头视角不同,融合时需要对图像做配准,麻烦得很。
更好的方案是 RGB-IR 双模传感器。这种传感器在每个像素上做了特殊设计,一部分像素对可见光敏感,另一部分对红外光敏感。通过算法分离,可以同时输出 RGB 图像和 IR 图像。
注意:RGB-IR 传感器输出的 IR 图像是单通道的灰度图,分辨率通常只有 RGB 的一半。这是物理限制,算法上要做好心理准备。
我建议在座舱方案里优先考虑 RGB-IR 一体式传感器。原因很简单:
- 节省空间(一个镜头搞定)
- 视角完全一致(省去配准步骤)
- 成本更低(少一个摄像头模组)
避坑指南:我曾经在一个项目里用了 RGB-IR 传感器,但没注意 IR 通道的响应曲线。结果发现 IR 图像在 940nm 波长下灵敏度极低,补光灯功率得翻倍才能用。后来才意识到,不同厂家的 IR 传感器对 850nm 和 940nm 的响应差异很大。选型时一定要看 datasheet 里的量子效率曲线。
三、鱼眼摄像头与广角摄像头:视野的博弈
座舱里空间有限,摄像头安装位置通常很受限。这就带来了一个矛盾:想看到整个座舱,但摄像头离得近,视角不够宽。
广角摄像头(FOV 60°-120°)和鱼眼摄像头(FOV 120°-220°)就是来解决这个问题的。
广角摄像头畸变较小,图像边缘的变形在可接受范围内。适合做驾驶员分心检测、手势识别这类需要精确位置信息的任务。
鱼眼摄像头视野极宽,但代价是严重的桶形畸变。你看鱼眼拍出来的照片,边缘的直线都弯了。这种图像不能直接给算法用,必须先做畸变校正。
我的建议:如果只用一个摄像头覆盖全座舱,选鱼眼。但要做好畸变校正的预处理。如果空间允许装两个摄像头,用两个广角摄像头拼接,效果更好。
畸变校正的数学模型是这样的:
// 鱼眼畸变校正(OpenCV 风格)
// 输入:原始图像上的点 (u, v)
// 输出:校正后的点 (x, y)
// 1. 将像素坐标转换为归一化坐标
x_norm = (u - cx) / fx
y_norm = (v - cy) / fy
// 2. 计算径向距离
r = sqrt(x_norm^2 + y_norm^2)
// 3. 应用畸变模型(这里用等距投影模型)
theta = atan(r)
theta_d = theta * (1 + k1 * theta^2 + k2 * theta^4 + k3 * theta^6)
// 4. 计算校正后的坐标
scale = theta_d / r
x_corrected = x_norm * scale
y_corrected = y_norm * scale
// 5. 映射回像素坐标
u_corrected = fx * x_corrected + cx
v_corrected = fy * y_corrected + cy
这段代码看着简单,但实际调参很折磨人。k1、k2、k3 这三个畸变系数需要标定才能得到。我建议直接用 OpenCV 的 fisheye::calibrate() 函数,别自己手写。
小技巧:鱼眼校正后,图像边缘的分辨率会下降。因为校正过程相当于把边缘的像素「拉伸」开了。所以做目标检测时,尽量让目标出现在图像中心区域。边缘区域的分辨率可能不够用。
四、摄像头标定基础:让摄像头知道自己的「位置」
摄像头标定,说白了就是让摄像头告诉你:「我的内参是多少?我装在车上的外参是多少?」
内参包括:焦距 (fx, fy)、主点 (cx, cy)、畸变系数。这些参数决定了「世界坐标系中的点,映射到图像坐标系中的哪个像素」。
外参包括:旋转矩阵 R 和平移向量 T。这些参数决定了「摄像头相对于车辆坐标系的位置和朝向」。
标定的方法有很多,最常用的是张正友标定法。你需要打印一张棋盘格,在不同角度拍 10-20 张照片,然后用算法解算出内参和外参。
关键点:座舱摄像头的标定和自动驾驶摄像头不一样。自动驾驶摄像头看的是远处,标定板放 5-10 米外就行。座舱摄像头看的是近处(0.3-1.5 米),标定板必须放在这个距离范围内。否则标定出来的参数在近处会不准。
我分享一个标定流程:
- 准备一张 A3 大小的棋盘格,格子边长 30mm
- 把棋盘格放在座舱内不同位置:主驾座椅、副驾座椅、后排中间
- 每个位置拍 3-5 张,角度稍微变化
- 总共收集 15-20 张有效图像
- 用 OpenCV 的
calibrateCamera()计算内参 - 用
solvePnP()计算外参(需要知道棋盘格在车辆坐标系中的实际位置)
我曾经踩过的坑:标定座舱摄像头时,我偷懒只拍了 8 张照片。结果标定出来的畸变系数偏差很大,导致后续的视线估计算法误差超过 5 度。后来老老实实拍了 20 张,误差降到 1 度以内。标定这件事,真的不能省。
标定完成后,记得做一次验证。拿一个已知尺寸的物体(比如 A4 纸)放在座舱里,用标定好的参数计算它的尺寸。如果误差在 5% 以内,说明标定合格。
嗯,今天的内容就到这里。摄像头传感器是座舱感知的基石,选对传感器、标定好参数,后面的算法才能事半功倍。下一章我们讲激光雷达和毫米波雷达,到时候再聊。