1. RAW图像基础:理解Bayer阵列与CFA模式

做图像处理这些年,我见过不少新手一上来就对着RAW文件发懵——这玩意儿怎么是绿的?其实说白了,RAW图像就是传感器最原始的“底片”。今天咱们就从最基础的Bayer阵列讲起。

1.1 什么是CFA?为什么需要它?

图像传感器本身是色盲的。每个像素只能感知光的强度,分不清红绿蓝。那彩色照片怎么来的?

答案就是——在传感器表面盖一层彩色滤光片阵列(Color Filter Array,简称CFA)。每个像素上方只允许特定波长的光通过。这样,每个像素就只记录一种颜色分量。

核心概念:CFA让单色传感器具备了感知色彩的能力。代价是每个像素只采集一种颜色,缺失的两种颜色要靠后续插值算法补回来。

1.2 Bayer阵列——最经典的CFA模式

1976年,柯达公司的Bryce Bayer提出了这个方案。直到今天,市面上90%以上的相机还在用这个模式。为什么?因为它简单、高效、效果好。

Bayer阵列的排列规律:

  • 绿色像素占50%——人眼对绿色最敏感
  • 红色和蓝色各占25%
  • 排列方式:RGGB(最常见)或BGGR、GRBG、GBRG

我刚开始做ISP时,总记不住这四种排列顺序。后来有个老工程师教我一招:看传感器数据手册里第一行前两个像素的颜色,就能确定整个阵列的排布。这招我用了十几年,从来没出过错。

排列模式 第一行 第二行 常见于
RGGB R G R G ... G B G B ... Sony、Nikon多数机型
BGGR B G B G ... G R G R ... 部分Canon机型
GRBG G R G R ... B G B G ... 部分手机传感器
GBRG G B G B ... R G R G ... 部分工业相机

注意:读取RAW文件时,必须先确认Bayer排列顺序。我曾经接手过一个项目,前任工程师把RGGB当成了BGGR处理,结果整批照片颜色都是反的。排查了三天才找到问题——就是Bayer顺序搞反了。

1.3 Bayer阵列的变体

除了标准的2×2 Bayer,这些年也出现了一些改进方案:

  • X-Trans(富士):6×6排列,减少摩尔纹,但解马赛克算法更复杂
  • Quad Bayer(三星、索尼):2×2同色像素合并,用于高像素手机传感器
  • RGBW:加入白色像素,提升低光灵敏度

不过说实话,这些变体在底层逻辑上和标准Bayer是一样的——每个像素只记录一种颜色,后续都需要插值。所以咱们先把标准Bayer吃透,其他的自然就通了。

1.4 从RAW数据到可视图像

你想想看,传感器输出的RAW数据长什么样?

就是一个二维数组,每个元素是12bit或14bit的整数。但这个数组里,相邻像素记录的是不同颜色。要变成我们能看的彩色图像,需要三步:

  1. 黑电平校正:减去暗电流带来的固定偏移
  2. 白平衡:调整RGB通道增益,还原真实色彩
  3. 解马赛克(Demosaic):插值补全每个像素缺失的两种颜色

咱们这门课,就是从第一步开始讲起。

1.5 知识结构总览

下面这张图,把本章的核心知识点串起来了。我建议你多看几遍,脑子里先搭好框架。

RAW图像基础:Bayer阵列与CFA模式 RAW图像 CFA彩色滤光片阵列 Bayer阵列 Bayer变体 每个像素只记录一种颜色 缺失颜色靠插值补全 RGGB / BGGR / GRBG / GBRG 绿色占50%,红蓝各25% 2×2最小重复单元 X-Trans(富士6×6) Quad Bayer(2×2合并) RGBW(加入白色像素) 从RAW到彩色图像的基本流程 RAW数据 → 黑电平校正 → 白平衡 → 解马赛克 → 彩色图像 本课程从第一步开始,逐层深入

1.6 动手验证:读取Bayer排列信息

光说不练假把式。咱们写一小段Python代码,看看怎么从RAW文件头里读出Bayer排列。

import struct

def get_bayer_pattern(raw_file_path):
    """
    从RAW文件头读取Bayer排列信息
    这里以常见的.DNG格式为例
    """
    with open(raw_file_path, 'rb') as f:
        # 跳过文件头,定位到CFA Pattern标签
        # 实际项目中需要解析TIFF IFD
        # 这里简化演示
        f.seek(0x100)
        data = f.read(4)
        
    # Bayer排列编码
    patterns = {
        0: 'RGGB',
        1: 'BGGR', 
        2: 'GRBG',
        3: 'GBRG'
    }
    
    pattern_code = struct.unpack('<I', data)[0]
    return patterns.get(pattern_code, 'Unknown')

# 使用示例
# pattern = get_bayer_pattern('sample.dng')
# print(f'Bayer排列: {pattern}')

小技巧:如果你手头没有RAW文件,可以用OpenCV的cv2.COLOR_BayerBG2BGR这类枚举值来验证。枚举名里的BG就是Bayer排列的前两个字母。

1.7 本章小结

嗯,到这里咱们把RAW图像的基础打好了。记住三个要点:

  • CFA是传感器获取色彩的“眼镜”,Bayer是最主流的戴法
  • Bayer有四种排列顺序,搞错了颜色就全乱套
  • RAW到彩色图像需要黑电平校正、白平衡、解马赛克三步