📷 第4章 · 摄像头成像原理、CMOS噪声与运动模糊
—— 从光子到像素,传感器工程师的“眼底”世界
摄像头是自动驾驶的“眼睛”。但说实话,这颗眼睛远没有人类视觉那么可靠。我在项目里见过太多因为噪声或模糊导致感知失灵的案例——嗯,这一章我们就来拆解摄像头从成像到噪声的完整链路。
1. 摄像头成像 · 光信号如何变成数字图像
摄像头成像说白了就是“光子计数”。外界光线穿过镜头,经过光圈、滤光片,最后落在CMOS感光阵列上。每个像素把光子转换成电子,再通过ADC变成数字值。我习惯把这个过程拆成三步:光电转换 → 电荷积累 → 量化输出。
你想想看,每个像素其实就是一个微型“水桶”。光子落进来,电子越积越多,电压就越高。但水桶总会漏、会溢,这就是噪声的源头。
💡 核心公式(理想情况)
像素输出 DN = (Φ · QE · A · tint) / (e-/DN) + 暗信号
其中 Φ 是光子通量,QE 是量子效率,A 是像素面积,tint 是积分时间。我在调参时经常用这个公式估算信噪比下限。
2. CMOS 噪声模型 · 三大“暗箭”
CMOS传感器里的噪声,我把它归为三类。每一类我都吃过亏,咱们一个一个说。
| 噪声类型 | 来源 | 特性 | 我的避坑经验 |
|---|---|---|---|
| 散粒噪声 (Shot noise) | 光子到达的随机性 | √信号,泊松分布 | 低照度下尤其明显,别指望降噪算法能完全消除 |
| 读出噪声 (Read noise) | 像素复位、放大器、ADC | 近似高斯,与信号无关 | 我曾经因为PCB走线干扰把读出噪声放大了3倍……后来加了屏蔽 |
| 固定模式噪声 (FPN) | 像素工艺偏差 | 空间固定,列/行条纹 | 标定后减掉均值能干掉80%,但温度漂移后又会冒出来 |
🔧 个人习惯:我在仿真中通常用 shot = np.random.poisson(signal) 模拟散粒噪声,再用 np.random.normal(0, sigma_read) 叠加读出噪声。FPN 则用固定增益偏差图。
3. 运动模糊 · 自动驾驶的“动态梦魇”
运动模糊不是噪声,但比噪声更头疼。车辆一加速或转弯,像素积分时间内场景移动,图像就拖尾了。我见过一个极端案例——高速上的锥桶因为运动模糊直接“消失”在图像里。
为什么会这样?因为CMOS是逐行曝光的(rolling shutter),每一行曝光起始时间不同。如果车在动,物体就会倾斜、变形。嗯,这里要注意:全局快门(global shutter)能缓解,但动态范围会下降。
⚠️ 曾经踩过的坑:有一次我们做仿真验证,只加了高斯噪声,没加运动模糊。结果实车测试时感知模块在匝道上疯狂漏检。从那以后,我的仿真管线里必加 基于速度场的运动模糊核。
运动模糊的建模其实不复杂。假设曝光时间 T,像素速度 v,模糊核就是一个长度为 v·T 的线段。我常用下面的代码生成模糊核:
def motion_blur_kernel(length, angle):
# length: 模糊像素长度, angle: 运动方向(弧度)
kernel = np.zeros((length, length))
center = length // 2
for i in range(length):
x = int(center + (i - center) * np.cos(angle))
y = int(center + (i - center) * np.sin(angle))
if 0 <= x < length and 0 <= y < length:
kernel[y, x] = 1.0
return kernel / kernel.sum()
然后对图像做卷积。注意边界处理——我习惯用 scipy.signal.convolve2d 的 'same' 模式。
4. 综合噪声仿真管线建议
在实际项目中,我不会把噪声一个个单独加。而是构建一个串行管线:
- 原始辐射量 → 加入散粒噪声(泊松采样)
- 电子信号 → 加入读出噪声(高斯) & FPN(乘性偏差)
- 量化前 → 应用运动模糊(空间可变核)
- ADC量化 → 加量化噪声(均匀分布 ±0.5 LSB)
你想想看,如果跳过第一步,低照度下的信噪比会乐观很多,实车就露馅了。我个人习惯在仿真中保留每一步的中间输出,方便调试。
📌 关键参数速查表(典型车载摄像头)
| 参数 | 典型值 | 说明 |
|---|---|---|
| 量子效率 (QE) | 0.5 ~ 0.7 | 背照式CMOS更高 |
| 读出噪声 | 2 ~ 6 e⁻ | 越低越好,高端传感器 <2 e⁻ |
| 满阱容量 | 10k ~ 30k e⁻ | 决定动态范围 |
| 暗电流 | 0.1 ~ 1 e⁻/s @25°C | 温度每升10°C翻倍 |
| 曝光时间 | 10 ~ 40 ms | 太长容易运动模糊 |
最后说一句:摄像头仿真不是越复杂越好。我见过有人堆了十几个噪声项,结果主要矛盾反而被淹没了。抓住散粒噪声、读出噪声、运动模糊这三板斧,就能覆盖90%的退化场景。剩下的,等实车测试回来再迭代。