第三章 RAW图基础与Bayer格式解析

做ISP流水线调试,第一关就是跟RAW图打交道。很多刚入行的工程师拿到RAW文件就懵了——这灰蒙蒙的一片,到底该怎么看?

我个人习惯把RAW图比作相机的"原始底片"。它记录了传感器感受到的最原始的光强信息,还没经过任何美化处理。你想想看,如果连底片都看不懂,后面那些复杂的ISP调试就更无从下手了。

3.1 Bayer Pattern:传感器的马赛克世界

为什么RAW图看起来是灰的?因为每个像素只记录一种颜色。传感器表面覆盖了一层彩色滤光片阵列,这就是Bayer Pattern。

最常见的Bayer格式有四种:

Pattern名称 第一行 第二行 常见传感器
RGGB R G R G ... G B G B ... Sony IMX系列
GRBG G R G R ... B G B G ... OmniVision多数型号
GBRG G B G B ... R G R G ... 部分三星传感器
BGGR B G B G ... G R G R ... 老款CCD传感器

关键点:绿色像素数量是红色或蓝色的两倍。因为人眼对绿色最敏感,传感器厂商故意这么设计的。说白了,这就是仿生学的体现。

我在项目中遇到过最坑的事——拿到一个平台的RAW图,默认以为是RGGB,结果调试了一整天颜色都不对。后来dump出原始数据一看,人家是GRBG。就这一个Pattern搞错,整个颜色矩阵全乱套。

3.2 黑电平校正:把"假黑"去掉

RAW图里有个隐藏的陷阱——黑电平。传感器在完全无光的情况下,输出的并不是0,而是一个固定的偏移值。这个偏移就是黑电平。

为什么会这样?因为传感器电路本身有暗电流,加上ADC的偏置电压,导致"纯黑"变成了"灰黑"。

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

// 黑电平校正
// ob: 光学黑区平均值
// raw_in: 原始像素值
// raw_out: 校正后像素值

uint16_t black_level_correction(uint16_t raw_in, uint16_t ob) {
    if (raw_in < ob) {
        return 0;  // 防止下溢
    }
    return raw_in - ob;
}

我的经验:黑电平值不是固定不变的。温度升高、增益变大,黑电平都会漂移。我曾经在调试一款安防摄像头时,白天和晚上的黑电平差了8个LSB。如果不做动态校正,暗部细节全没了。

高通平台通常会在传感器驱动里配置黑电平参数,但实际调试时我建议你这样做:

  1. 先读光学黑区——传感器边缘有被遮挡的像素,取它们的平均值作为OB值
  2. 做逐行校正——有些传感器每行的黑电平都不一样,需要逐行处理
  3. 注意饱和保护——校正后的值不能超过ADC最大量程

3.3 RAW图dump与验证方法

调试ISP流水线,最基础也最重要的技能就是dump RAW图。没有原始数据,你根本不知道问题出在哪一步。

我常用的dump方法有三种:

方法 工具 适用场景 数据量
寄存器级dump ICE/ADB + 寄存器读写 底层驱动调试 小(单帧)
ISP pipeline dump 高通CamX工具链 ISP各模块调试 中(多帧)
应用层dump Camera HAL + 文件IO 效果调试 大(视频流)

注意:dump RAW图时一定要确认数据格式。是10bit还是12bit?是packed还是unpacked?格式搞错了,后面分析全是白费功夫。

验证RAW图是否正确,我有一套标准流程:

  • 第一步:看直方图——正常的RAW图直方图应该是连续的,没有断档或尖峰
  • 第二步:检查黑电平——盖上镜头盖,看暗区像素值是否稳定在OB附近
  • 第三步:验证Bayer Pattern——拍一张纯白画面,看R/G/B通道的比例是否合理
  • 第四步:检查坏点——用暗场和亮场对比,找出异常像素

我曾经遇到一个案例:某款传感器在低温下RAW图出现条纹噪声。一开始以为是Bayer Pattern读错了,后来dump出原始数据才发现,是传感器PLL在低温下锁相不稳,导致ADC采样时序偏移。这种问题,没有RAW图根本定位不了。

3.4 本章知识体系

下面这张图总结了RAW图相关的核心知识点和它们之间的关系:

RAW图知识体系 RAW图基础 Bayer Pattern 黑电平校正 dump与验证 RGGB GRBG GBRG BGGR OB值提取 逐行校正 饱和保护 寄存器级 Pipeline级 应用层 核心原则:先读懂RAW图,再谈ISP调试 Bayer Pattern决定颜色基础,黑电平校正影响暗部质量,dump验证是问题定位的起点

避坑指南:我曾经在调试一款4K摄像头时,发现RAW图暗部有奇怪的条纹。折腾了两天,最后发现是dump时数据位宽设置错了——传感器输出12bit,但工具默认按10bit解析。就这2bit的差异,让整个画面出现了量化噪声。从那以后,我每次dump都会先确认三个参数:位宽、Pattern、像素顺序。

RAW图调试没有捷径。你花在理解Bayer Pattern和黑电平上的时间,后面都会加倍还给你。记住一句话:RAW图的质量,决定了ISP流水线的上限。