3、传感器与RAW图基础:Bayer阵列、CFA模式、黑电平校正(BLC)、线性化
好,咱们进入第三章。这一章聊的是ISP管线的起点——传感器和RAW图。说白了,就是相机“眼睛”看到的东西,以及怎么把它变成我们能处理的数字信号。
很多做AI算法的人,一上来就对着RGB图像调模型,却忽略了RAW图这个“金矿”。我个人习惯是,不管做什么任务,先看一眼RAW图,心里才有底。因为所有后续处理的质量,都取决于你从传感器拿到的原始数据干不干净。
3.1 从光子到数字:传感器的工作流程
先简单过一遍物理过程。光照射到传感器上,每个像素点(photosite)收集光子,转换成电子,再通过模数转换器(ADC)变成数字值。这个数字值,就是RAW图里的一个像素。
但这里有个关键问题:传感器本身是“色盲”的。它只能感知光的强度,分不清颜色。那彩色照片是怎么来的?
答案就是——在传感器表面盖一层彩色滤光片阵列,也就是CFA(Color Filter Array)。
3.2 Bayer阵列与CFA模式
最常见的CFA模式就是Bayer阵列。它用红、绿、蓝三种滤光片,按特定规律排列在像素上。为什么绿色占一半?因为人眼对绿色最敏感,这样设计能模拟人眼的亮度感知。
我刚开始做ISP时,总觉得Bayer阵列很简单。直到有一次调试一个偏色问题,折腾了两天才发现——我搞错了CFA的排列顺序。有的传感器是BGGR,有的是GBRG,还有RGGB。你想想看,如果解马赛克时用错了模式,整个颜色通道都错位了,那画面能对吗?
所以,拿到一个新传感器,第一件事就是确认它的CFA模式。通常厂商会提供文档,或者你可以通过读取RAW图的元数据(比如EXIF)来获取。
| CFA模式 | 2x2单元排列 | 常见传感器 |
|---|---|---|
| RGGB | R G / G B | Sony IMX系列 |
| BGGR | B G / G R | 部分OmniVision |
| GBRG | G B / R G | 部分三星传感器 |
| GRBG | G R / B G | 较少见,需确认 |
3.3 黑电平校正(BLC)
传感器在完全没有光照的情况下,输出的数字值并不是0。为什么?因为电路本身有暗电流、热噪声,还有ADC的偏移。这个非零的基准值,就叫黑电平(Black Level)。
黑电平校正的目的,就是把RAW图中每个像素减去这个基准值,让“纯黑”对应到0。
我记得有一次做夜景算法,发现暗部区域总是偏绿。排查了很久,最后发现是黑电平没校正对。传感器厂商给的黑电平值是64(12-bit RAW),但我用的RAW图是经过裁剪的,黑电平已经变了。嗯,这里要注意:黑电平值可能随增益、温度、甚至像素位置变化。
黑电平校正的公式很简单:
// 假设黑电平为 black_level
for each pixel in RAW:
pixel = pixel - black_level
if pixel < 0:
pixel = 0
但实际工程中,黑电平可能不是整数,或者不同通道的黑电平不同。这时候就需要查表或插值了。
3.4 线性化
传感器输出的RAW值,理论上应该与入射光强成线性关系。但实际情况是,很多传感器在低光或高光区域存在非线性响应。线性化的目的,就是把这个非线性关系校正回线性。
为什么一定要线性?因为后续的白平衡、颜色校正、去马赛克等操作,都是基于线性模型的。如果输入是非线性的,那结果就会乱套。
线性化通常有两种方法:
- 查表法(LUT):厂商会提供一条校正曲线,把输入值映射到线性值。
- 多项式拟合:用一条曲线(比如二次或三次多项式)来拟合非线性响应。
我个人更倾向于查表法,因为它能精确处理任意形状的非线性。但查表法需要存储一个256或4096项的数组,对内存有要求。如果你在嵌入式平台上做,可能得用分段线性近似来压缩。
// 假设 lut 是一个 4096 长度的数组,由厂商提供
for each pixel in RAW:
pixel = lut[pixel]
你可能会问:黑电平校正和线性化,谁先谁后?答案是:先做黑电平校正,再做线性化。因为黑电平校正是减一个固定偏移,而线性化是映射关系。如果先做线性化,黑电平偏移会被非线性放大,导致校正不准。
3.5 本章知识体系
下面这张图,把传感器到RAW图的核心流程串起来了。你可以看到,从光子到数字,每一步都有坑,每一步都需要校正。
3.6 实战建议
最后,给你几个实战中的建议:
- 拿到新传感器,先拍一张全黑图(盖上镜头盖)。看看黑电平是多少,不同通道的黑电平是否一致。这是最直接的验证方法。
- 线性化验证:拍一组不同曝光时间的灰阶图,检查RAW值是否与曝光时间成线性关系。如果不成线性,说明线性化没做好。
- 注意位深:常见的RAW图有10-bit、12-bit、14-bit。黑电平和线性化LUT的精度要匹配位深。比如12-bit RAW,LUT就需要4096个条目。