RAW图格式与传感器特性:从光子到数字的第一次握手

说实话,做ISP这么多年,我见过太多人一上来就调颜色、调锐度,结果发现图像底子就不对。为什么?因为RAW图阶段的信息,决定了整个pipeline的天花板。你想想看,传感器采集到的原始数据,就像做菜的原材料——食材不新鲜,再好的厨艺也白搭。

这一章,我们就来聊聊RAW图格式和传感器那些“脾气”。搞懂了这些,你才算真正入了ISP的门。

Bayer阵列详解:为什么是RGGB?

人眼对绿色最敏感,这是生物进化的结果。传感器厂商也学了这个套路——Bayer阵列里,绿色像素的数量是红蓝的两倍。典型的排列就是RGGB:

标准Bayer 2x2单元:

R  G
G  B

每个像素只感知一种颜色分量,其他两种颜色要靠插值(Demosaic)算出来。

我在项目中遇到过一种情况:客户拿了一颗非标准Bayer排列的传感器,比如RCCB(红-清-清-蓝)或者RYYB(黄黄蓝)。当时团队里有人直接套用标准Demosaic算法,结果颜色全乱套了。嗯,这里要注意——Bayer模式一旦搞错,后面的颜色校正全是白费功夫。

常见的Bayer变种有这些:

模式 排列 典型应用
RGGB R G / G B 主流手机、安防
BGGR B G / G R 部分索尼传感器
GRBG G R / B G 某些工业相机
RCCB R C / C B 低照度监控

你拿到一颗新传感器,第一件事就是确认它的Bayer起始相位。我习惯写一个小工具,直接读RAW文件的前几个像素,通过统计平均值来判断——红色通道均值最高的位置,就是R像素的起点。

RAW数据格式:10bit、12bit、14bit到底差在哪?

说白了,bit数决定了传感器的“听力”有多好。10bit能分辨1024级灰度,12bit是4096级,14bit是16384级。数字越大,暗部细节越丰富,但数据量也越大。

我举个例子你就明白了:

  • 10bit RAW:一个像素占10位,但存储时通常按16位对齐(2字节)。适合高速连拍,但暗部容易有断层。
  • 12bit RAW:目前手机的主流选择。4096级灰度,配合好的降噪算法,暗部表现已经相当不错。
  • 14bit RAW:专业相机和工业检测常用。16384级,后期拉阴影时几乎看不到banding。

我的经验: 如果你在做HDR或者多帧合成,尽量用12bit以上。10bit在多次叠加后,量化噪声会被放大,画面容易出现“水波纹”。

RAW数据的存储格式也值得注意。常见的packing方式有:

// 10bit packed 格式示例(5个像素占5字节)
Pixel 0: [9:2] [1:0]
Pixel 1: [9:2] [1:0]
...
// 实际存储时,每4个像素打包成5字节

我曾经踩过一个坑:读RAW文件时没注意字节序(Endian),结果图像全是雪花。后来加了个字节序检测逻辑,才搞定。

黑电平与动态范围:传感器的“零点”在哪?

黑电平(Black Level)就是传感器在完全无光情况下的输出值。理论上应该是0,但实际因为暗电流、电路偏置等原因,会有一个固定的偏移量。

比如一个12bit传感器,黑电平可能是64,白电平是4095。那么有效动态范围就是:

动态范围(dB) = 20 * log10((白电平 - 黑电平) / 噪声均方根)

我习惯在ISP pipeline的第一步就做黑电平校正:

// 黑电平校正伪代码
for each pixel:
    corrected = raw_pixel - black_level
    if corrected < 0: corrected = 0

注意: 不同颜色通道的黑电平可能不一样。Bayer阵列的R、G、B通道,因为工艺差异,黑电平值可能有1-2个LSB的偏差。我曾经遇到过一台相机,绿色通道的黑电平比红色高了3个LSB,结果暗部偏绿——校正后才正常。

动态范围决定了传感器能同时记录亮部和暗部细节的能力。高动态范围的传感器,在逆光场景下优势明显。但要注意,动态范围不是越大越好——如果噪声控制不好,高动态范围反而会暴露更多噪点。

传感器噪声模型:三大“捣乱分子”

传感器噪声,说白了就是光子到电子的转换过程中,那些“不听话”的随机波动。我把它分成三类:

1. 光子噪声(Shot Noise)

这是物理极限——光子到达传感器的时间是随机的,服从泊松分布。信号越强,噪声也越大(标准差 = √信号)。

你想想看,在暗光环境下,光子数量少,信噪比自然就低。这就是为什么夜景照片总是噪点多。

// 光子噪声模型
signal = 1000 个光子
noise_std = sqrt(1000) ≈ 31.6
SNR = 20 * log10(1000 / 31.6) ≈ 30 dB

2. 读出噪声(Read Noise)

这是传感器电路在读取电荷时引入的噪声。它和信号强度无关,是一个固定底噪。高端传感器的读出噪声可以做到1-2个电子,低端的可能有10个电子以上。

我在项目中测试过一颗工业相机,读出噪声高达15个电子。结果在暗部,画面全是“胡椒盐”噪点。后来换了传感器型号,读出噪声降到3个电子,暗部干净多了。

3. 固定模式噪声(Fixed Pattern Noise, FPN)

这是传感器制造工艺不一致导致的。每个像素的增益、暗电流都有细微差异,表现为图像上的固定条纹或网格。

FPN的特点是:位置固定,不随时间变化。所以可以用标定法去除——拍一张均匀光照的灰卡,记录每个像素的偏移量,然后实时校正。

FPN校正流程:

  1. 盖上镜头盖,拍一张暗场(黑电平标定)
  2. 拍一张均匀光照的灰场(增益标定)
  3. 计算每个像素的校正系数
  4. 实时应用:corrected = (raw - dark) * gain_correction

我曾经在一条产线上发现,同一批次的传感器,FPN模式居然不一样。后来才知道,是晶圆不同位置导致的差异。从那以后,我坚持每颗传感器单独标定,绝不共用校正参数。

知识结构总览

下面这张图,帮你把本章的核心逻辑串起来:

RAW图与传感器特性知识结构 RAW图格式与传感器特性 · 知识结构 传感器原始数据 Bayer阵列 RAW数据格式 黑电平与动态范围 传感器噪声模型 RGGB/BGGR Demosaic起点 10/12/14bit Packing 暗电流 动态范围 光子噪声 读出噪声 固定模式噪声 核心思路:理解传感器的“脾气”,才能在ISP pipeline中做对每一笔校正 Bayer相位 → RAW格式解析 → 黑电平校正 → 噪声抑制,环环相扣

一句话总结: RAW图是传感器的“原生语言”。搞懂Bayer排列、bit深度、黑电平偏移和噪声来源,你才能写出真正鲁棒的ISP算法。别急着调颜色——先把RAW吃透。