3. 黑电平校正(BLC):从物理根源到高通实战
黑电平校正,圈里人常叫 BLC(Black Level Correction)。
这步看着简单,不就是减个值嘛。但我见过不少团队,BLC 没做对,后面整条流水线都跟着偏色。说白了,这是 RAW 域的第一道关卡,搞不好,后面白平衡、去马赛克全得跟着遭殃。
3.1 黑电平是怎么来的?
先问个问题:你把镜头盖盖上,全黑环境,传感器输出应该是 0 吗?
答案是否定的。传感器输出的不是 0,而是一个大于 0 的底数。这个底数,就是黑电平。
为什么会这样?我总结了几点物理原因:
- 暗电流:硅基半导体在无光照时,热激发也会产生电子-空穴对。温度每升高 6-8°C,暗电流翻倍。我在做手机摄像头调试时,夏天户外和冬天室内,黑电平能差出十几个 DN(Digital Number)。
- 像素复位噪声:每个像素在曝光前需要复位,复位过程会引入 KTC 噪声,这部分噪声叠加在信号上,抬高了底数。
- ADC 偏移:模数转换器本身有固定的 offset,不同通道(R/Gr/Gb/B)的 offset 还不一样。
- 电路串扰:传感器内部驱动时钟、电源走线对像素区的耦合干扰。
关键认知:黑电平不是噪声,是信号中的固定偏置。它和噪声的区别在于——噪声是随机的,黑电平是确定的(或缓慢变化的)。
3.2 BLC 算法原理
BLC 的核心逻辑很简单:校正后像素值 = 原始像素值 - 黑电平值。
但难点在于——这个黑电平值怎么取?
3.2.1 全局校正
全局校正,就是整张图用一个固定的黑电平值去减。
做法:传感器通常会在像素阵列边缘预留一些 光屏蔽像素(Optically Black Pixels, OB Pixels)。这些像素被金属层遮住,不接收光线,只输出暗电流+噪声。取这些 OB 像素的平均值,作为全局黑电平。
| 项目 | 说明 |
|---|---|
| 优点 | 实现简单,计算量小,适合硬件流水线 |
| 缺点 | 无法处理传感器行间/列间的黑电平差异 |
| 适用场景 | 低端传感器、光照均匀的环境 |
我的经验:全局校正最大的坑在暗光场景。暗光下信号本身很弱,如果黑电平估计偏了 1-2 个 DN,暗部细节就全丢了。我曾经遇到过一个案子,夜景模式拍出来偏紫,查了两天,最后发现是全局黑电平没跟上温度变化。
3.2.2 局部校正
局部校正更精细。它把图像分成多个区域,每个区域独立计算黑电平。
常见做法有两种:
- 行/列级校正:利用每行/每列末尾的 OB 像素,逐行或逐列计算黑电平。这能消除行噪声(Row Noise)。
- 网格校正:将图像分成 M×N 网格,每个网格内统计 OB 像素均值,然后做双线性插值,得到每个像素位置的黑电平。
| 方法 | 精度 | 硬件开销 | 典型应用 |
|---|---|---|---|
| 全局校正 | 低 | 极低 | 低端 CIS、监控 |
| 行级校正 | 中 | 低 | 手机主摄 |
| 网格校正 | 高 | 中 | 高端旗舰、车载 |
注意:局部校正不是越细越好。网格太密,OB 像素样本数不足,统计结果反而抖动大,引入新的噪声。我一般建议每个网格至少包含 50-100 个 OB 像素。
3.3 高通平台 BLC 配置实战
在高通 CamX 架构里,BLC 属于 ISP 流水线的早期模块,在 IFE(Image Front End)中完成。配置通过 XML 文件实现。
3.3.1 核心 XML 节点
BLC 配置主要在 sensor 模块的 black_level_correction 节点下。我贴一段实际项目中用过的配置:
<sensor>
<black_level_correction>
<enable>1</enable>
<mode>0</mode>
<black_level>
<channel>R</channel>
<value>64</value>
</black_level>
<black_level>
<channel>Gr</channel>
<value>66</value>
</black_level>
<black_level>
<channel>Gb</channel>
<value>65</value>
</black_level>
<black_level>
<channel>B</channel>
<value>63</value>
</black_level>
</black_level_correction>
</sensor>
这里 mode=0 表示全局校正模式。四个通道的 black level 分别配置,因为 Bayer 阵列中 R/Gr/Gb/B 的暗电流特性不同。
3.3.2 局部校正配置
如果要用局部校正,需要配置 mode=1,并增加 ob_region 节点:
<black_level_correction>
<enable>1</enable>
<mode>1</mode>
<ob_region>
<rows>4</rows>
<cols>6</cols>
<row_start>0</row_start>
<row_end>3</row_end>
<col_start>0</col_start>
<col_end>5</col_end>
</ob_region>
</black_level_correction>
这个配置的意思是:取图像左上角 4 行 × 6 列的 OB 像素区域,分成 4×6 网格,每个网格独立统计黑电平。
避坑指南:我曾经在调试一款 48M 传感器时,发现画面左侧偏暗。查了半天,原来是 OB 区域配置错了——row_start 和 col_start 写反了,导致黑电平取到了有效像素区。嗯,这种低级错误,排查起来最费时间。
3.3.3 动态黑电平跟踪
高通平台还支持动态 BLC,即黑电平随帧实时更新。配置如下:
<black_level_correction>
<enable>1</enable>
<mode>2</mode>
<dynamic_blc>
<update_interval>30</update_interval>
<alpha>0.125</alpha>
</dynamic_blc>
</black_level_correction>
update_interval=30 表示每 30 帧更新一次黑电平。alpha=0.125 是 IIR 滤波系数,控制更新速度。系数越大,响应越快,但容易受噪声干扰。
3.4 BLC 效果验证
配置完怎么验证对不对?我一般做三步检查:
- 全黑图检查:盖上镜头盖,拍一张 RAW 图。直方图应该集中在 0 附近,且四个通道的均值差异在 1-2 个 DN 以内。
- 暗部线性度:用均匀光源拍不同亮度的灰阶卡,检查暗部区域的响应是否线性。如果 BLC 不准,暗部会明显弯曲。
- 温度漂移测试:让设备连续工作 30 分钟,每隔 5 分钟拍一张全黑图,看黑电平是否稳定。我见过有些方案,温漂能到 10 个 DN。
一句话总结:BLC 不是简单的减法,它决定了整条 ISP 流水线的暗部精度。全局校正保下限,局部校正提上限,动态跟踪保稳定。