2. RAW域预处理:黑电平校正、镜头阴影校正、坏点校正

各位同学,今天咱们聊聊RAW域预处理。这是ISP流水线的第一道关卡,说白了就是让传感器吐出来的原始数据变得“干净”一点。我刚开始接触ISP时,总觉得这步可有可无,直到有一次调试夜景模式,画面偏色偏得离谱……嗯,从那以后我再也不敢小看这三个校正了。

2.1 黑电平校正(BLC)

先说说黑电平校正。传感器在完全无光的情况下,理论上应该输出0,但实际不是这样。因为电路本身有暗电流,像素单元即使没接收到光子,也会积累一些电荷。这个底噪值,就是黑电平。

核心公式:

I_corrected = I_raw - black_level

就这么简单?嗯,原理确实简单,但坑不少。

我在项目中遇到过一个问题:同一颗传感器,不同增益下的黑电平不一样。你想想看,如果只用一个固定值去减,高ISO下画面就会偏绿或偏紫。所以实际工程中,我们通常用动态黑电平——根据增益、温度查表插值。

参数 固定BLC 动态BLC
实现难度 低 中
精度 一般 高
适用场景 光照稳定、低增益 宽动态、高ISO
硬件开销 几乎为零 需少量LUT

避坑指南:我曾经在调试一款车规级传感器时,发现暗角区域的黑电平比中心高了约4个DN。后来查资料才知道,传感器边缘温度更高,暗电流更大。所以BLC最好分区域做,别一刀切。

2.2 镜头阴影校正(LSC)

镜头阴影,也叫亮度衰减。说白了就是镜头边缘进光量比中心少,拍出来的照片四角发暗。你想想看,如果手机镜头做得小,这个问题会更明显。

校正方法其实不复杂:预先拍一张均匀光照下的灰卡,记录每个像素位置的增益系数,然后实时乘回去。

// 简化的LSC实现
for (y = 0; y < height; y++) {
    for (x = 0; x < width; x++) {
        gain = lsc_table[y][x];  // 查表
        pixel[y][x] = pixel[y][x] * gain;
    }
}

但这里有个关键点:增益不能太大。如果边缘增益超过4倍,噪声会被放大到不可接受。我见过一个项目,为了把边缘亮度拉到和中心一样,增益设到6倍,结果暗部全是噪点,还不如不校正。

个人经验:我建议LSC增益上限控制在2.5倍以内。如果镜头本身阴影太严重,先换镜头,别指望算法硬拉。

2.2.1 多项式 vs 网格

LSC的实现方式主要有两种:

  • 多项式模型:用二次或四次曲线拟合阴影分布。优点是参数少,适合硬件加速;缺点是精度有限,尤其对广角镜头。
  • 网格查表:把画面分成16x16或32x32的网格,每个网格存一个增益值,中间双线性插值。精度高,但需要更多存储。

我个人习惯用网格法。虽然存储开销大一点,但现在的ISP芯片动辄几十兆的SRAM,这点开销不算什么。而且网格法调试起来直观——哪个角暗了,直接改那个网格的增益就行。

2.3 坏点校正(DPC)

坏点,就是传感器上那些“不听话”的像素。有的永远亮着(亮点),有的永远黑着(暗点),有的随机闪烁(闪点)。

校正策略分两种:

  1. 静态校正:出厂前标定坏点坐标,存到OTP里。运行时直接跳过这些点,用周围像素插值。
  2. 动态校正:实时检测坏点。比如某个像素和周围8个邻居差异太大,就判定为坏点,当场替换。
类型 优点 缺点
静态DPC 稳定、无漏检 无法处理新生坏点
动态DPC 自适应、覆盖全生命周期 可能误判纹理为坏点

我曾经踩过的坑:动态DPC的阈值设得太低,结果把星空照片里的星星全当坏点抹掉了。后来加了亮度自适应阈值——暗区阈值松一点,亮区阈值紧一点,才解决问题。

2.4 三个校正的流水线关系

这三个模块在硬件流水线里怎么排?我直接画个图给你看:

RAW域预处理流水线 传感器 RAW 黑电平校正 镜头阴影校正 坏点校正 输出 RAW 注意:坏点校正通常放在LSC之后,因为LSC放大了噪声,坏点更容易被检测到

为什么坏点校正放在LSC之后?因为LSC会放大边缘像素的噪声,原本不明显的坏点被放大后更容易被检测到。当然,也有架构把DPC放在BLC之后、LSC之前,这取决于硬件设计。我个人倾向先做LSC再做DPC,检测率更高。

2.5 硬件加速要点

这三个模块在硬件实现上,有几个共同点:

  • 行缓冲:DPC需要3x3窗口,至少需要2行缓存。LSC的网格插值也需要行缓冲。
  • 查表:BLC和LSC都依赖查找表。表的大小直接影响硬件面积,需要权衡。
  • 流水线停顿:如果三个模块串行处理,每帧会有几个时钟周期的延迟。我建议用乒乓缓冲,让三个模块并行工作。

硬件加速小技巧:LSC的增益计算可以用定点数,比如Q8.8格式。这样乘法器面积小,精度也够用。我做过对比,Q8.8和浮点数的PSNR差异不到0.1dB,但硬件面积节省了40%。

好了,RAW域预处理就讲到这里。这三个校正虽然基础,但做不好会直接影响后续所有模块。你想想看,如果黑电平没校好,后面的白平衡、颜色校正全都会偏。所以,别嫌它们简单,认真对待每一个DN的偏差。