3. RAW图数据格式:RAW10/RAW12/RAW14、黑电平与坏点校正、RAW图存储与读取

各位做ISP调优的同行,咱们今天聊聊RAW图。这是整个图像处理管线的起点,也是决定画质上限的关键。我见过不少工程师一上来就调RGB或者YUV,结果发现怎么调都调不好——说白了,根儿上的RAW数据就没处理好。

RAW图是什么?就是Sensor直接输出的原始数据,没经过任何处理。它保留了最完整的场景信息,但也带着Sensor本身的瑕疵。咱们这一章就把RAW的格式、校正和存储讲透。

3.1 RAW数据格式:RAW10 / RAW12 / RAW14

Sensor输出的RAW数据,每个像素用多少比特来表示,这就是位深。常见的位深有10bit、12bit、14bit。你可能会问:为什么不用8bit?嗯,8bit只有256个灰阶,对于安防监控这种需要暗部细节的场景,根本不够用。

位深 灰阶数 动态范围 典型应用
RAW10 1024 约60dB 低端IPC、USB摄像头
RAW12 4096 约72dB 主流安防摄像机
RAW14 16384 约84dB 高端AI摄像机、车载

我个人习惯把位深理解为「精度」。RAW10就像一把毫米尺,RAW14就是一把游标卡尺。在暗光场景下,RAW14能分辨出更细微的亮度差异,后期提亮时不容易出现色阶断层。

经验之谈: 我在项目中遇到过,某款Sensor标称是RAW12输出,但实际有效位只有11bit。怎么发现的?拍一张均匀灰卡,看直方图——如果出现明显的梳状间隙,说明高位有噪声被截断了。这时候就得跟Sensor厂商沟通了。

3.2 黑电平校正

黑电平,英文叫Black Level,简称BL。Sensor在完全无光的情况下,理论上应该输出0,但实际上会有一个偏移值。这个偏移就是黑电平。

为什么会这样?Sensor的像素在暗电流和读出电路噪声的共同作用下,会有一个基础电压。如果不把这个偏移减掉,整个图像会偏灰,暗部细节被淹没。

黑电平校正的公式很简单:

校正后像素值 = 原始像素值 - 黑电平值

但实际做的时候有几个坑:

  • 黑电平不是固定值——它会随温度、增益、曝光时间变化。我建议在每一帧的OB(Optical Black)区域实时采样,动态计算。
  • 不同通道的黑电平可能不同——R、Gr、Gb、B四个通道的暗电流特性有差异,需要分别校正。
  • 黑电平校正后要钳位——减完可能变成负数,必须钳位到0。
避坑指南: 我曾经在调试一款宽动态Sensor时,发现暗部偏紫。查了半天,原来是Gr和Gb通道的黑电平差了2个LSB。分别校正后,色偏问题立刻解决。所以,别偷懒,四个通道分开算。

3.3 坏点校正

Sensor的像素阵列里,总会有一些「坏」的像素。它们要么一直亮(白点),要么一直暗(黑点),要么响应异常。这些坏点如果不处理,在图像上就是固定位置的噪点,非常显眼。

坏点校正分两步:

  1. 坏点检测——找出哪些像素是坏的。
  2. 坏点替换——用周围像素的值把坏点补上。

检测方法我常用两种:

  • 静态检测:在出厂前,用均匀光源拍一张图,找出偏离均值超过阈值的像素,生成坏点表。
  • 动态检测:在运行中,比较当前像素和周围8邻域的差异,如果差异过大,判定为坏点。

替换方法也有讲究:

// 中值替换——对孤立坏点效果好
pixel_out = median(pixel_left, pixel_right, pixel_up, pixel_down)

// 均值替换——对坏点簇效果好
pixel_out = (pixel_left + pixel_right + pixel_up + pixel_down) / 4
关键点: 动态检测的阈值要留余量。阈值设太严,会把正常像素误判为坏点;设太松,坏点漏检。我一般取3倍噪声标准差作为阈值,效果比较平衡。

3.4 RAW图存储与读取

RAW图怎么存?常见的有两种格式:

格式 存储方式 优点 缺点
Packed 连续比特流,无浪费 节省存储空间 读取时需要位操作,速度慢
Unpacked 每个像素对齐到字节 读取快,方便处理 浪费存储空间

举个例子,RAW12的Packed格式:每3个像素占36bit,正好4.5个字节。而Unpacked格式,每个像素占2字节(16bit),浪费了4bit。

我个人习惯在调试阶段用Unpacked格式,方便用文本工具查看。量产时再切到Packed,节省带宽和存储。

读取RAW图时,要注意Bayer Pattern的排列顺序。常见的Bayer格式有BGGR、RGGB、GRBG、GBRG四种。读错顺序,图像颜色就全乱了。

// 以BGGR为例,读取一个像素
uint16_t read_raw_pixel(uint8_t *raw_data, int x, int y, int width) {
    // 计算偏移:y * width + x
    int offset = y * width + x;
    // 如果是RAW12 Unpacked,每个像素占2字节
    return ((uint16_t *)raw_data)[offset];
}
小技巧: 我写了一个小工具,把RAW图转成16位PNG,方便在电脑上预览。转换时注意做线性映射,把RAW的数值范围映射到0-65535。这样能直观看到黑电平校正前后的差异。

好了,RAW图的基础知识就这些。下一节咱们开始讲ISP管线中的第一个处理模块——去噪。不过那是后话了,先把RAW数据吃透,后面的路才好走。

RAW图处理流程 Sensor RAW输出 RAW格式解析 (RAW10/12/14) 黑电平校正 (BL Correction) 坏点校正 (DPC) 校正后RAW数据 注意事项 • 黑电平随温度变化 • 坏点检测阈值要留余量 • 存储格式影响读写速度