第2章:Sensor数据采集与RAW域处理

各位工程师好,我是老周。今天咱们聊聊ISP Pipeline的起点——Sensor数据采集和RAW域处理。这部分看似基础,但说实话,很多图像问题的根子就出在这里。你想想看,源头数据如果脏了,后面再怎么调也是白费功夫。

2.1 Sensor工作原理——光电转换的“第一公里”

Sensor的核心任务,就是把光信号变成电信号。这个过程我习惯分成三步:

  1. 光电转换:光子打到像素点的感光二极管上,产生电子
  2. 电荷积累:曝光时间内,电子不断积累,形成电压信号
  3. 模数转换:ADC把模拟电压量化为数字值(通常是10bit、12bit或14bit)

我在项目中遇到过一个问题:同一款Sensor,白天效果很好,晚上全是噪点。后来发现是ADC的增益档位没选对。Sensor的模拟增益和数字增益,对信噪比的影响完全不同。模拟增益放大的是信号+噪声,数字增益只放大数字噪声。所以我的建议是:优先用模拟增益,数字增益能不用就不用。

关键指标:Sensor的动态范围 = 满阱电荷数 / 读出噪声。这个值决定了暗部细节和亮部过曝的平衡能力。安防监控场景下,动态范围最好做到70dB以上。

2.2 Bayer Pattern——彩色世界的“马赛克”

单个像素只能感知亮度,那颜色怎么来?答案是Bayer Pattern。Sensor表面覆盖了一层彩色滤光片阵列(CFA),每个像素只允许一种颜色通过。

最常见的Bayer Pattern是RGGB,也就是一个像素点阵里:

  • 50%是绿色像素(G)——人眼对绿色最敏感
  • 25%是红色像素(R)
  • 25%是蓝色像素(B)

为什么绿色多一倍?说白了,人眼对亮度信息最敏感,而绿色通道贡献了大约60%的亮度信息。Sensor厂商这么设计,是为了模拟人眼的视觉特性。

Bayer类型 排列方式 常见应用
RGGB R G / G B 最主流,安防、手机、相机
RCCC R C / C C 低照度监控,牺牲色彩换亮度
RCCB R C / C B 兼顾亮度和色彩,部分安防Sensor在用

我的经验:调试时一定要确认Sensor的Bayer排列顺序。我曾经因为搞错了Bayer顺序,导致整个画面偏紫,折腾了两天才发现是配置问题。建议在初始化代码里显式指定Bayer顺序,不要依赖默认值。

下面这张图展示了Bayer Pattern的数据采集流程:

Bayer Pattern 数据采集与RAW域处理流程 场景光线 CFA滤光片 像素阵列 ADC转换 RAW 黑电平校正 (BLC) 镜头阴影校正 (LSC) 去马赛克 (Demosaic) RGB 说明: 1. 场景光线经过CFA滤光片后,每个像素只记录一种颜色分量 2. ADC将模拟信号转换为数字RAW数据(通常10-14bit) 3. RAW域处理包括BLC、LSC等,在去马赛克之前完成 4. 去马赛克后得到完整的RGB图像,进入后续ISP Pipeline

2.3 黑电平校正(BLC)——把“零”找回来

黑电平校正,说白了就是找到Sensor在完全无光情况下的输出值。理想情况下,没光应该输出0。但实际Sensor有暗电流,即使盖上镜头盖,像素也会读出一些数值,比如64(12bit RAW下)。

这个偏移量就是黑电平。校正公式很简单:

// 黑电平校正示例代码
uint16_t blc_value = 64;  // 从Sensor寄存器读取或标定得到
for (int i = 0; i < frame_size; i++) {
    raw_data[i] = (raw_data[i] > blc_value) ? (raw_data[i] - blc_value) : 0;
}

注意:黑电平不是固定不变的。它会随温度、增益、曝光时间变化。我曾经在夏天调试一款Sensor,白天标定的BLC值,到了晚上温度降了10度,画面暗部就偏绿了。建议做温度补偿,或者用OB(Optical Black)像素实时计算BLC值。

BLC校正不到位,会带来两个问题:

  • BLC偏大:暗部被裁切,细节丢失,画面发黑
  • BLC偏小:暗部有偏色,整体画面发灰,动态范围被压缩

2.4 镜头阴影校正(LSC)——让画面“亮”得均匀

镜头阴影,也叫亮度衰减。说白了,就是镜头中心比边缘亮。原因有两个:

  • 光学原因:镜头边缘的光线入射角大,到达Sensor的光量少
  • 像素原因:边缘像素的微透镜收集效率下降

校正方法是用一个增益矩阵去补偿边缘像素。每个像素位置乘以一个对应的增益值:

// 镜头阴影校正示例(简化版)
// gain_table 是预先标定好的增益矩阵
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        float gain = gain_table[y][x];
        raw_data[y * width + x] = raw_data[y * width + x] * gain;
    }
}

我的建议:LSC的增益不要超过2.5倍。增益太大,边缘的噪声会被放大得很明显。如果镜头阴影超过3dB,建议先换镜头,而不是靠算法硬拉。

LSC标定通常分两步:

  1. 采集平场图像:用均匀光源(积分球或灯箱)拍摄一张全白画面
  2. 计算增益矩阵:以图像中心为基准,计算每个像素需要补偿的增益
校正维度 描述 典型值
亮度阴影 亮度从中心到边缘的衰减 中心100%,边缘70%~85%
颜色阴影 不同颜色通道衰减不一致导致的偏色 边缘可能偏红或偏蓝

颜色阴影比亮度阴影更棘手。因为不同波长的光在镜头边缘的衰减率不同,导致画面边缘偏色。我遇到过一款镜头,边缘偏红很严重,单独做亮度LSC根本没用,必须分通道做LSC——R、G、B各一张增益表。

避坑指南:我曾经在量产时发现,同一批镜头的光学中心位置有偏差。如果LSC增益表是以Sensor中心为基准,镜头装偏了,校正效果就会变差。建议在产线做镜头中心校准,或者用自适应LSC算法。