3. 传感器噪声模型:光子散粒噪声、读出噪声、固定模式噪声(FPN)、暗电流
做RAW域AI ISP,第一关就是搞懂传感器噪声。
你想想看,算法再牛,如果连噪声的根儿都摸不清,那后处理就是瞎折腾。我在芯片公司那几年,见过太多团队把精力花在花里胡哨的降噪网络上,结果连最基本的散粒噪声和读出噪声都没分开建模——最后效果嘛,自然是一言难尽。
今天咱们就把传感器噪声这四大家族聊透:光子散粒噪声、读出噪声、固定模式噪声(FPN)、暗电流。搞懂了它们,你才算真正入了RAW域的门。
3.1 噪声从哪来?一张图看懂
先给你个全景图。传感器噪声按来源和特性,可以分成两大类:
- 时间随机噪声:每帧都不一样,靠多帧叠加能压下去。散粒噪声、读出噪声属于这一类。
- 空间固定噪声:每帧都在同一个位置出现,多帧叠加没用。FPN、暗电流不均匀性属于这一类。
下面这张SVG图,把四类噪声的源头和关系理清楚了:
3.2 光子散粒噪声——躲不掉的物理宿命
光子到达传感器是随机的,服从泊松分布。这个噪声是物理极限,你没法消除它。
数学上很简单:
N_shot = sqrt(S)
其中 S 是信号电子数,N_shot 是散粒噪声标准差。
举个例子:信号100个电子,噪声就是10个电子,信噪比10:1。信号10000个电子,噪声100个电子,信噪比100:1。所以暗光下散粒噪声最要命。
核心结论:散粒噪声是信号依赖的。信号越强,噪声值越大,但信噪比反而越高。AI ISP里,对暗部区域要单独处理,就是这个原因。
我在项目中遇到过一件事:有同事用高斯噪声模型去拟合暗光RAW图,结果降噪后暗部出现奇怪的颗粒感。为什么?因为高斯噪声是信号无关的,而散粒噪声在暗部是明显的泊松分布。后来我们改用泊松-高斯混合模型,问题才解决。
3.3 读出噪声——电路设计的硬功夫
读出噪声是传感器读出电路引入的,跟信号大小没关系。它主要包括:
- 复位噪声(KTC噪声):像素复位时,电容上的热噪声
- 源跟随器噪声:像素内放大管的1/f噪声和热噪声
- 列放大器噪声:列并行ADC前的放大器噪声
- ADC量化噪声:模数转换的量化误差
这些噪声合起来,就是传感器数据手册上那个“读出噪声”指标,单位是e-(电子数)。
我的经验:选传感器时,读出噪声比像素尺寸更关键。一个读出噪声1.5e-的传感器,在暗光下比读出噪声3e-的传感器好不止一档。别只看像素数,那是营销话术。
读出噪声的建模很简单,一般用高斯分布:
N_read ~ Gaussian(0, σ_read²)
但要注意,不同增益下读出噪声不一样。高增益(ISO高)时,读出噪声会被放大。我建议在标定时,至少测3个增益点的读出噪声,然后插值使用。
3.4 固定模式噪声(FPN)——每颗传感器都有自己的“指纹”
FPN是空间噪声,每帧都在同一个位置出现。它分两种:
| 类型 | 来源 | 特性 | 校正方法 |
|---|---|---|---|
| 像素FPN (PFPN) | 每个像素的暗电平偏移不同 | 像素级固定偏移 | 暗帧减除(DSNU) |
| 列FPN (CFPN) | 列放大器/ADC的增益和偏移差异 | 整列一致的条纹 | 列校正(通常用暗行参考) |
| 行FPN (RFPN) | 行选通时序差异 | 整行一致的条纹 | 行校正(较少见) |
FPN的数学模型:
I_out(x,y) = G(x,y) * I_real(x,y) + O(x,y)
其中 G(x,y) 是增益非均匀性(PRNU),O(x,y) 是偏移非均匀性(DSNU)。
注意:FPN在长曝光和高温下会恶化。我曾经在调试一款安防传感器时,发现60℃下FPN比25℃时大了3倍。后来我们在AI ISP里加入了温度自适应的FPN校正模块,效果立竿见影。
3.5 暗电流——温度和时间的朋友
暗电流是传感器在没有光照时,由于热激发产生的电子。它跟温度强相关,每升高6-8℃,暗电流翻倍。
暗电流的组成:
- 扩散暗电流:耗尽区外热激发电子扩散进来
- 耗尽区暗电流:耗尽区内热激发
- 表面暗电流:Si-SiO2界面缺陷导致
暗电流的建模:
I_dark(T, t) = I_0 * exp(-Ea/(k*T)) * t
其中 I_0 是常数,Ea 是激活能(约0.6-1.0eV),k 是玻尔兹曼常数,T 是温度,t 是曝光时间。
暗电流有两个麻烦:
- 均值偏移:整体变亮,需要暗帧减除
- 不均匀性(DCNU):每个像素暗电流不同,形成固定噪声
实战建议:在AI ISP训练数据中,一定要包含不同温度下的暗帧。我见过太多团队只用25℃的数据训练,结果在50℃场景下暗部偏色严重。暗电流校正不是简单的减一个常数,要逐像素建模。
3.6 完整噪声模型——把它们串起来
实际传感器的输出,是上面所有噪声的叠加:
I_out = G * (I_photon + N_shot + I_dark + N_dark) + N_read + O_fpn
其中:
I_photon : 光子信号
N_shot : 散粒噪声(泊松分布,方差 = I_photon + I_dark)
I_dark : 暗电流均值
N_dark : 暗电流不均匀性(固定噪声)
N_read : 读出噪声(高斯分布)
G : 增益非均匀性(PRNU)
O_fpn : 偏移非均匀性(DSNU)
这个模型,就是AI ISP降噪网络的物理先验。你设计的网络结构、损失函数、训练数据,都应该围绕这个模型展开。
我的习惯:在项目启动时,先花一周做传感器标定。用暗帧测DSNU和读出噪声,用均匀光照测PRNU,用变温箱测暗电流温度曲线。这些标定数据,比任何公开数据集都值钱。
3.7 噪声模型在AI ISP中的应用
搞懂噪声模型,不是为了写,是为了落地。具体怎么用?
| 应用场景 | 噪声模型的作用 | 实现方式 |
|---|---|---|
| 合成训练数据 | 生成逼真的RAW域噪声 | 按模型参数,在干净RAW上叠加噪声 |
| 网络结构设计 | 指导降噪网络的分支设计 | 信号依赖分支 + 信号无关分支 |
| 损失函数 | 区分不同噪声的优化目标 | 散粒噪声用泊松似然,读出噪声用L2 |
| 后处理调优 | 暗部/亮部分开处理 | 根据信噪比自适应降噪强度 |
| 硬件部署 | 减少计算量,定点化 | 用查找表近似噪声模型参数 |
举个例子。我在做一款手机ISP芯片时,降噪网络需要处理从1/30秒到1/1000秒的曝光范围。如果用一个网络硬扛,暗部过曝部都处理不好。后来我们根据噪声模型,把输入分成3个信噪比区间,每个区间用不同的网络权重。效果提升明显,而且硬件面积只增加了15%。
避坑指南:千万不要直接用sRGB域的噪声模型去生成RAW域训练数据。我曾经吃过这个亏——在sRGB域加高斯噪声,训练出来的网络在真实RAW图上完全失效。RAW域的噪声统计特性跟sRGB域天差地别,一定要在RAW域建模。