传统ISP核心模块:黑电平校正、镜头阴影校正、坏点校正

各位同学,今天我们来聊聊ISP流水线最前面的三个“守门员”。

很多人觉得BLC、LSC、DPC是基础,没什么好讲的。但我个人经验告诉我,恰恰是这些基础模块,决定了后面所有高级算法的上限。你想想看,如果原始数据就有问题,后面再怎么调也是白搭。

黑电平校正(BLC)

先说黑电平校正。说白了,就是让传感器在完全没光的时候,输出应该是0,但实际不是0。

为什么?因为传感器本身有暗电流,还有ADC的偏置。我遇到过一款手机传感器,暗电流能到30个DN(数字值)。如果不校正,你拍出来的黑色物体,其实是深灰色的。

核心公式:

Icorrected = Iraw - Boffset

其中Boffset是黑电平值,通常从传感器的OB(光学黑)区域统计得到。

校正方式有两种:

  • 全局BLC:整幅图像减去同一个值。简单粗暴,适合低端传感器。
  • 逐行BLC:每行单独统计OB值。我建议用这个,因为暗电流随温度变化,不同行的OB值其实不一样。

我的经验:曾经有个项目,图像偏色怎么都调不好。查了三天,发现是BLC值没更新——传感器温度从25度升到60度,暗电流漂了15个DN。从那以后,我坚持每帧都重新统计OB值。

嗯,这里要注意:BLC之后,可能会出现负值。一定要做截断处理,否则后面的模块会出问题。

镜头阴影校正(LSC)

镜头阴影,也叫“暗角”。你拍一张纯白墙,会发现四周比中心暗。这不是传感器的问题,是镜头的光学特性决定的。

我刚开始做ISP时,觉得LSC不就是乘个增益嘛。后来发现,没那么简单。

校正原理:

  1. 先拍一张均匀光照下的灰卡,得到参考图像。
  2. 计算每个像素位置的增益系数:Gain(x,y) = Target / Ireference(x,y)
  3. 对实际图像逐像素乘以增益系数。

注意:增益系数通常用网格形式存储。比如16x16的网格,每个格子对应一个增益值。中间像素通过双线性插值得到。

我遇到过一个问题:用了LSC之后,图像边缘出现“彩色条纹”。后来发现是R、G、B三个通道的阴影程度不一样,需要分别校正。说白了,就是每个通道要单独算增益网格。

避坑指南:我曾经在量产时发现,同一批镜头,阴影曲线居然有差异。后来加了镜头标定环节,每颗镜头单独生成LSC参数。虽然成本高了点,但图像质量稳定多了。

LSC的增益不能太大。一般控制在2倍以内,否则噪声会被放大。你想想看,边缘区域信号本来就弱,再乘个2倍增益,噪声也跟着翻倍了。

坏点校正(DPC)

坏点,就是传感器上那些“不听话”的像素。要么一直亮(白点),要么一直暗(黑点),要么响应异常。

我见过最夸张的案例:一颗传感器上有200多个坏点。如果不校正,拍出来的照片就像长了麻子。

坏点检测方法:

  • 静态检测:出厂时标定,存一张坏点位置表。简单,但无法应对使用过程中新产生的坏点。
  • 动态检测:实时判断。比如,某个像素的值和周围8个邻居差异太大,就标记为坏点。

我个人的习惯是两者结合:静态表保底,动态检测做补充。

校正方法:

  1. 中值滤波:用周围像素的中值替换坏点。效果不错,但会损失细节。
  2. 插值法:根据周围好点的梯度方向插值。我推荐这个,能保留边缘信息。
  3. 自适应校正:先判断坏点所在区域是平坦还是纹理区,再选择不同策略。

我的经验:动态检测的阈值很关键。设得太严,会把正常像素误判为坏点;设得太松,坏点漏检。我一般用3倍局部标准差作为阈值,效果比较稳健。

嗯,这里有个坑:Bayer格式下,坏点校正要考虑颜色通道。比如R通道的坏点,只能用同通道的邻居来校正,不能混用G或B的像素。

三个模块的协同关系

这三个模块在ISP流水线中的顺序是固定的:BLC → LSC → DPC。为什么?

  • BLC先做,因为后面的模块都假设黑电平已经归零。
  • LSC其次,因为阴影校正是乘性操作,如果先做DPC,坏点校正的插值结果会被LSC放大误差。
  • DPC最后,因为经过前两步,数据已经比较干净,坏点检测更准确。

我画了一张流程图,方便大家理解:

ISP前端三大模块处理流程 RAW原始数据 黑电平校正 (BLC) 镜头阴影校正 (LSC) 坏点校正 (DPC) 关键说明 1. 顺序不可颠倒 2. BLC是减法操作 3. LSC是乘法操作 4. DPC是替换操作 5. 每个模块都有 自己的参数表 6. 输出仍是RAW格式 7. 为后续模块 提供干净数据 ISP前端预处理 输入:Bayer RAW 输出:校正后RAW 处理单位:像素/块 实时性要求:高 硬件实现:常见

这张图很清楚地展示了数据流向。我建议大家在写代码时,也按照这个顺序来组织流水线。

实际工程中的注意事项

模块 常见问题 我的建议
BLC 温度漂移导致黑电平不准 每帧重新统计OB值,做滑动平均
LSC 增益过大导致边缘噪声 限制最大增益,配合去噪模块
DPC 动态检测误判 结合静态表,设置合理的阈值

最后说一句:这三个模块虽然基础,但调好了,后面的AWB、Demosaic、去噪都会轻松很多。我见过太多人一上来就调高级算法,结果发现是前端数据有问题,白白浪费了时间。

嗯,今天就到这里。大家回去可以拿一张RAW图,自己写代码跑一遍这三个校正,感受一下数据的变化。