4、黑电平校正(BLC):从暗电流到图像纯净度

黑电平校正,圈内人常叫 BLC(Black Level Correction)。说白了,就是让传感器在完全没光的时候,输出值归零。听起来简单,但这里面的门道,我做了这么多年 ISP,踩过的坑真不少。

你可能会问:传感器没光不就是 0 吗?哪有这么理想。CMOS 传感器在暗场下,每个像素都会读出一个小信号,这个信号就是黑电平。如果不把它减掉,整张画面会发灰发雾,暗部细节全被埋掉。

核心目标: 让传感器在零光照条件下,输出数字值严格为 0(或目标黑电平)。

4.1 黑电平是怎么产生的?

黑电平的源头,主要是两个:暗电流和读出电路偏移。

  • 暗电流: 硅基半导体在无光照时,热激发产生的电子-空穴对。温度每升高 6-8°C,暗电流翻一倍。我在做安防相机时,夏天户外 60°C 的机壳温度,暗电流能飙到室温的 8 倍以上。
  • 读出电路偏移: 像素的复位电压、源跟随器、列放大器,每个环节都会引入固定的直流偏置。不同列、不同通道的偏移还不一样。
  • ADC 偏移: 模数转换器自身的零点偏移,通常是个固定值。

这些因素叠加,最终在暗场下读出的数字值可能是 64、128,甚至更高(取决于传感器位数和设计)。

我的经验: 拿到一颗新 sensor,第一件事就是盖上镜头盖,拍一张全黑图。看直方图峰值在哪,看不同行、不同列有没有条纹。这能帮你快速判断黑电平问题的严重程度。

4.2 全局黑电平校正 vs 局部黑电平校正

校正策略分两种:全局和局部。选哪个,取决于你的 sensor 质量和应用场景。

类型 方法 适用场景 优缺点
全局 BLC 从整帧图像减去一个固定值 低端 sensor、暗电流均匀的 sensor 简单快速,但无法处理行/列差异
局部 BLC 按行、按列、甚至按像素减去不同值 高精度应用、大靶面 sensor、长曝光 效果好,但需要校准数据存储

全局校正,就是算一个全图的平均黑电平,然后一刀切。我早期做手机摄像头时,sensor 质量好,暗电流均匀,全局校正就够了。但后来做工业相机,发现画面左边和右边亮度不一样,全局校正根本搞不定。

局部校正,需要提前采集暗场数据。通常的做法是:

  1. 盖上镜头盖,在不同增益、不同曝光时间下拍多张暗场图。
  2. 对每张图,计算每行(或每列)的平均值。
  3. 把这些值存成查找表(LUT),运行时按行/列查表减去。
注意: 局部校正的 LUT 会占用存储空间。一个 1920x1080 的 sensor,如果按行存储 16bit 校正值,需要 1920×2 = 3840 字节。如果按像素存储,那就是 4MB。嵌入式系统里,存储和带宽都是成本。

4.3 暗电流补偿:温度与增益的联动

暗电流不是一成不变的。它随温度和增益变化。我见过不少方案,只做了一组暗场校准,结果冬天和夏天的画面效果差很多。

暗电流的数学模型可以近似为:

I_dark(T) = I_0 × 2^((T - T_0) / T_doubling)

其中:
  I_dark(T)  = 温度 T 下的暗电流
  I_0        = 参考温度 T_0 下的暗电流
  T_doubling = 暗电流翻倍的温度增量(通常 6-8°C)

实际工程中,我们不会用这么复杂的公式实时算。更常见的做法是:

  • 多温度点校准: 在 -20°C、0°C、25°C、60°C 等温度点采集暗场数据,存多组 LUT。
  • 线性插值: 运行时根据当前温度,在相邻两组 LUT 之间线性插值。
  • 增益补偿: 暗电流经过模拟增益放大后,在数字域的表现是:黑电平偏移 = 暗电流 × 模拟增益。所以校正值也要乘以当前增益。
避坑指南: 我曾经在一个项目中,只做了 25°C 的暗场校准。结果冬天户外 -10°C,黑电平偏低,画面暗部被裁成了负值,出现大量死黑。后来加了温度传感器和查表插值,才解决。

4.4 温度对黑电平的影响:实测数据

下面是一组我在实验室实测的数据,用的是某款 1/2.3 英寸 CMOS sensor,曝光时间 30ms,增益 0dB:

温度 (°C) 暗场均值 (12bit) 暗电流 (e-/s) 备注
-10 32 8 低温,暗电流很低
25 64 32 室温参考点
45 112 96 明显上升
60 192 256 高温,暗电流翻了好几倍

你看,从 -10°C 到 60°C,暗场均值从 32 跳到了 192。如果不做温度补偿,60°C 时画面会整体偏灰,暗部噪声也大得吓人。

4.5 BLC 在 ISP Pipeline 中的位置

黑电平校正是 ISP 流水线的第一步。它必须在去噪、去马赛克、白平衡之前做。为什么?因为后面的模块都假设黑电平已经是 0,如果带着偏移进去,整个颜色和亮度都会算错。

下面这张图,是我习惯用的 BLC 处理流程:

黑电平校正处理流程 黑电平校正(BLC)处理流程 RAW 图像输入 获取当前温度 & 增益 查表 / 线性插值得到校正值 全局校正 or 局部校正? 全局:减去固定值 局部:按行/列查表减 校正后 RAW 输出 说明:校正值 = 暗场参考值 × 当前增益 / 参考增益,再根据温度插值修正 局部校正需要额外存储行/列 LUT,全局校正只需一个标量值

4.6 工程实现要点

最后,分享几个我在工程落地时总结的要点:

  • 校准时机: 产线校准、开机自校准、或者每隔一段时间自动校准。我建议至少做一次产线校准,存下 baseline。
  • 暗帧平均: 采集暗场数据时,多帧平均(比如 16 帧)可以降低随机噪声对校准值的影响。
  • 边界处理: 校正后可能出现负值,需要做 clamp 到 0。但 clamp 会丢失信息,所以有些方案会保留一个很小的黑电平偏移(比如 16),不硬减到 0。
  • 与去噪的配合: BLC 之后,暗部噪声会被放大(因为信号被减掉了,噪声还在)。所以 BLC 后面通常紧跟着一个暗部去噪模块。
一个小技巧: 如果你发现 BLC 之后画面出现横条纹,大概率是行与行之间的黑电平不一致。这时候可以试试按行校正,或者检查一下 sensor 的读出时序有没有问题。

嗯,黑电平校正看起来是个小模块,但做扎实了,能显著提升画面的纯净度和一致性。尤其是暗光、高温场景,BLC 做得好不好,直接决定图像能不能用。