第二章 RAW图与Bayer格式:Bayer Pattern详解、RAW图存储格式、黑电平与白平衡基础

各位同学好,我是你们的ISP调优讲师。今天咱们来聊聊ISP pipeline里最源头、也最容易被忽视的部分——RAW图和Bayer格式。

说实话,我见过不少工程师,算法调得飞起,但连sensor出来的RAW数据长什么样都没搞清楚。结果呢?调试时各种奇怪现象,查半天发现是Bayer排布搞反了,或者黑电平没扣对。嗯,这种坑我自己也踩过,所以今天咱们把地基打牢。

2.1 什么是Bayer Pattern?

先问一个问题:一个像素点,怎么同时感知红、绿、蓝三种颜色?

答案很简单——它做不到。单个像素只能感知光的强度,分不清颜色。那怎么办?

1976年,柯达的工程师Bryce Bayer想了个办法:在每个像素前面盖一个彩色滤光片,只让特定波长的光通过。然后把这些滤光片按一定规律排列,这就是Bayer Pattern。

核心思想:用牺牲分辨率的方式,换取彩色信息。每个像素只记录一种颜色,缺失的颜色靠周围像素插值得到。

典型的Bayer Pattern长这样:

G R G R G R
B G B G B G
G R G R G R
B G B G B G

你发现没?绿色像素占了总数的一半,红蓝各占四分之一。为什么?因为人眼对绿色最敏感。我当年第一次看到这个分布时,觉得Bayer真是个天才——用最少的资源,骗过了人眼。

2.2 常见的Bayer排列方式

实际项目中,Bayer排列不止一种。我列个表,大家对照着看:

排列名称 第一个像素 典型应用
BGGR 蓝 Sony部分sensor
RGGB 红 OmniVision常用
GRBG 绿(左) 三星部分sensor
GBRG 绿(上) 安森美部分sensor

注意:我曾经在一个项目里,sensor datasheet写的是RGGB,但实际输出是BGGR。结果整幅图像偏色严重,查了三天才发现是Bayer顺序搞反了。所以拿到sensor后,第一件事就是拍一张纯色图,验证Bayer排列。

2.3 RAW图的存储格式

RAW图说白了,就是sensor直接输出的原始数据,没经过任何处理。它有几个关键参数:

  • 位深:常见的有8bit、10bit、12bit、14bit。位深越高,动态范围越大。
  • 存储方式:packed(紧凑)或unpacked(对齐)。
  • 数据顺序:按Bayer排列逐行存储。

举个例子,一个10bit的RAW图,如果用unpacked方式,每个像素占2字节(16bit),高6位补0。如果用packed方式,5个像素占8字节,没有浪费。我个人的习惯是:调试阶段用unpacked,方便查看;量产阶段用packed,节省带宽。

下面是一个读取RAW图的伪代码:

// 假设sensor输出10bit RAW,BGGR排列,分辨率1920x1080
uint16_t raw_image[1080][1920];

for (int y = 0; y < 1080; y++) {
    for (int x = 0; x < 1920; x++) {
        // 根据Bayer排列,判断当前像素的颜色
        if (y % 2 == 0 && x % 2 == 0) {
            // B像素
        } else if (y % 2 == 0 && x % 2 == 1) {
            // G像素
        } else if (y % 2 == 1 && x % 2 == 0) {
            // G像素
        } else {
            // R像素
        }
    }
}

小技巧:调试时,我经常把RAW图直接保存成PGM格式(灰度图),用ImageJ打开。虽然看起来是灰蒙蒙的,但能直观看到Bayer pattern的纹理——如果看到棋盘格状的明暗变化,说明数据没问题。

2.4 黑电平(Black Level)

黑电平是什么?说白了,就是sensor在完全无光的情况下,输出的像素值。

理想情况下,没光应该输出0。但实际sensor有暗电流、有噪声,所以输出值不会是0。比如一个10bit的sensor,黑电平可能是64。这意味着:

  • 像素值0~64之间,都是“黑”的
  • 真正的有效信号,从64开始算起

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

corrected_pixel = raw_pixel - black_level

但要注意,不同sensor的黑电平可能不同,甚至同一颗sensor在不同增益下黑电平也会漂移。我遇到过最坑的一次,某款sensor在低增益下黑电平是64,高增益下变成了72。如果不做动态校正,暗部细节全丢了。

避坑指南:我曾经在调试一款安防摄像头时,发现夜间图像偏紫。查了三天,最后发现是黑电平没扣干净,导致暗部偏色。从那以后,我每次拿到新sensor,第一件事就是拍全黑图,统计黑电平的均值和标准差。

2.5 白平衡基础(AWB)

白平衡,说白了就是让白色物体在任何光源下都显示为白色。

为什么需要白平衡?因为不同光源的色温不同。日光灯偏蓝(色温高),白炽灯偏黄(色温低)。sensor本身没有“色温概念”,它只是忠实地记录每个像素的R、G、B值。如果不做校正,同一张白纸在不同光源下拍出来颜色完全不同。

白平衡的数学原理很简单:

R_out = R_in * R_gain
G_out = G_in * G_gain
B_out = B_in * B_gain

其中R_gain、G_gain、B_gain就是白平衡增益。通常以G通道为基准,所以G_gain=1.0,R_gain和B_gain根据光源调整。

举个例子,在日光灯下(色温约5000K),白平衡增益可能是:

R_gain = 1.2
G_gain = 1.0
B_gain = 1.5

为什么B_gain这么大?因为日光灯偏蓝,sensor的B通道响应强,需要压低B通道(或者说提升R和G来平衡)。

关键点:白平衡是在RAW域做的,还是在RGB域做的?答案是——都可以。但我的经验是:在RAW域做白平衡,效果更好,因为避免了插值带来的误差放大。

2.6 本章知识体系

为了让大家更直观地理解本章的知识结构,我画了一张图:

第二章:RAW图与Bayer格式知识体系 RAW图与Bayer格式 Bayer Pattern • 单像素只能感知亮度 • 滤光片排列规则 • 绿色占50%的原因 Bayer排列方式 • BGGR / RGGB • GRBG / GBRG • 验证方法:纯色图 RAW存储格式 • 位深:8/10/12/14bit • Packed vs Unpacked • 逐行存储规则 黑电平 (Black Level) • 无光时的输出值 • 暗电流与噪声 • 动态校正的必要性 白平衡 (AWB) • 色温与光源 • R/G/B增益计算 • RAW域 vs RGB域 基础不牢,地动山摇 — 从RAW开始打好ISP基础

这张图把本章的核心知识点串起来了。你看,从Bayer Pattern出发,延伸到排列方式、存储格式,再到黑电平和白平衡——这些都是ISP pipeline最前端的处理环节。任何一个环节出问题,后面的算法再牛也救不回来。

我的建议:初学者不要急着调AWB、调去噪。先把RAW图读出来,看看Bayer排列对不对,黑电平扣没扣干净。这些基本功,决定了你后续调试的天花板。


可可精品资料库