图像 Sensor 输出格式与 Raw 数据详解

1. 图像 Sensor 输出格式

Sensor 输出主要分两大类:

Raw 格式(原始数据) — 大多数 sensor 默认输出

  • 每个像素只输出一个值,需要后端 ISP 处理才能变成彩色图
  • OV5647 就是这种

YUV/RGB 格式(处理后数据) — 有些 sensor 内置 ISP

  • 每个像素直接输出颜色信息,拿来就能显示
  • 比如一些手机 sensor 可以直接输出 YUV422

OV5647 内部虽然有简单的 ISP,但在 Linux 驱动中通常配置为 Raw 输出,让树莓派的 ISP 来做后处理。

2. 为什么 Raw 每个像素只有一个值?

这是由 sensor 的物理结构决定的。每个像素上面覆盖了一个颜色滤镜,只能感知一种颜色的光:

实际的 sensor 芯片表面(放大看):

  ┌───┬───┬───┬───┬───┬───┐
  │ 绿 │ 蓝 │ 绿 │ 蓝 │ 绿 │ 蓝 │  ← 每个格子是一个物理像素
  │滤镜│滤镜│滤镜│滤镜│滤镜│滤镜│    上面贴了一片彩色玻璃
  ├───┼───┼───┼───┼───┼───┤
  │ 红 │ 绿 │ 红 │ 绿 │ 红 │ 绿 │
  │滤镜│滤镜│滤镜│滤镜│滤镜│滤镜│
  ├───┼───┼───┼───┼───┼───┤
  │ 绿 │ 蓝 │ 绿 │ 蓝 │ 绿 │ 蓝 │
  │滤镜│滤镜│滤镜│滤镜│滤镜│滤镜│
  └───┴───┴───┴───┴───┴───┘

红色滤镜的像素只能感受红光强度,输出一个数值,比如 850。它不知道这个位置的绿光和蓝光是多少。所以 Raw 数据就是每个像素一个数值。

ISP 做的 demosaic(去马赛克)就是根据周围像素来”猜”缺失的颜色,把每个像素补全成 RGB 三个值。

3. Bayer 排列顺序

颜色滤镜的排列方式叫 Bayer Pattern,2x2 为一个重复单元。根据左上角 2x2 的排列不同,有 4 种:

RGGB:          BGGR:          GRBG:          GBRG:
┌───┬───┐      ┌───┬───┐      ┌───┬───┐      ┌───┬───┐
│ R │ G │      │ B │ G │      │ G │ R │      │ G │ B │
├───┼───┤      ├───┼───┤      ├───┼───┤      ├───┼───┤
│ G │ B │      │ G │ R │      │ B │ G │      │ R │ G │
└───┴───┘      └───┴───┘      └───┴───┘      └───┴───┘

OV5647 是 GBRG(左上角第一个像素是 G,右边是 B,下面是 R)。

为什么绿色占了一半?因为人眼对绿色最敏感,多采样绿色可以提高感知清晰度。

4. 位深(bit depth)

位深决定每个像素能表达多少级亮度:

位深 值范围 亮度级数 常见 sensor
8bit 0-255 256 老旧/低端 sensor
10bit 0-1023 1024 OV5647, IMX219
12bit 0-4095 4096 IMX477, IMX708
14bit 0-16383 16384 高端单反 sensor
16bit 0-65535 65536 科学/工业相机

位深越高,亮度过渡越细腻,暗部细节越丰富。OV5647 是 10bit,算是入门级。

注意你之前 raw 数据里看到的值是 65535 而不是 1023,那是因为 DNG 文件把 10bit 数据左移到了 16bit 存储(1023 « 6 = 65472 ≈ 65535)。

5. 存储方式

同样是 10bit 数据,存到文件里有不同方式:

Packed(紧凑存储):

4个像素(40bit) 存进 5个字节(40bit),不浪费空间

像素:  P0=0x3A2  P1=0x1B5  P2=0x0FF  P3=0x2C8

字节0: [P0的高8位] = 0xE8
字节1: [P1的高8位] = 0x6D
字节2: [P2的高8位] = 0x3F
字节3: [P3的高8位] = 0xB2
字节4: [P0低2|P1低2|P2低2|P3低2] = 0x 10 01 11 00 = 0x5C

文件大小 = 2592 × 1944 × 10 / 8 ≈ 6.3MB

Unpacked(对齐存储,DNG 常用):

每个像素用 16bit(2字节) 存,高位补零或左移

像素 P0=0x3A2 → 存为 uint16: 0x3A2 (或左移6位: 0xE880)

文件大小 = 2592 × 1944 × 2 ≈ 10MB

Packed 省空间,Unpacked 方便处理(直接当 uint16 数组读)。

6. 完整的数据流

光线 → sensor 像素(带颜色滤镜) → ADC(模数转换,10bit) → Raw Bayer 数据
                                                              │
                                                              ▼
                                                    ┌─────────────────┐
                                                    │  Raw 文件/流     │
                                                    │  每像素1个值     │
                                                    │  GBRG排列       │
                                                    │  10bit          │
                                                    └────────┬────────┘
                                                             │
                                                             ▼
                                                    ┌─────────────────┐
                                                    │  ISP 处理        │
                                                    │  1.黑电平校正    │
                                                    │  2.坏点校正      │
                                                    │  3.去噪          │
                                                    │  4.demosaic      │ ← 关键步骤:1值→RGB三值
                                                    │  5.白平衡        │
                                                    │  6.色彩校正(CCM) │
                                                    │  7.gamma         │
                                                    │  8.锐化          │
                                                    └────────┬────────┘
                                                             │
                                                             ▼
                                                    ┌─────────────────┐
                                                    │  JPG/PNG 图片    │
                                                    │  每像素RGB三个值 │
                                                    │  8bit per channel│
                                                    └─────────────────┘