第二章:图像传感器与RAW数据

各位工程师,咱们今天聊聊ISP调试的根基——图像传感器和RAW数据。说实话,我见过太多调试新手一上来就调色彩、调锐度,结果发现源头数据就有问题。嗯,这就像盖楼不打地基,迟早要塌。

2.1 传感器工作原理:光电转换的奥秘

图像传感器说白了就是个光电转换器。光照射到像素上,产生电子,电子数量跟光强成正比。这个过程叫光电效应,没什么神秘的。

我刚开始接触传感器时,总觉得它像个黑盒子。后来拆开一个老款CMOS传感器,才真正理解它的结构。每个像素其实就是一个光电二极管加一个放大器。

传感器的工作流程大致分三步:

  • 曝光:快门打开,光进入像素,产生光生电子
  • 读出:逐行扫描,把电荷转换成电压信号
  • 量化:ADC把模拟电压转成数字值

这里有个关键点——满阱容量。每个像素能容纳的电子数有限,满了就溢出了。我在项目中遇到过一款传感器,满阱容量只有30000个电子,拍高光场景时一片惨白。后来换了满阱容量80000的传感器,动态范围明显改善。

核心参数速查表

参数含义典型值
满阱容量像素能容纳的最大电子数30000-100000 e-
量子效率光子转电子的效率50%-80%
读出噪声读出过程中的噪声2-10 e-
暗电流无光照时产生的电子0.1-10 e-/s

2.2 Bayer阵列格式:为什么是RGGB?

你想想看,传感器只能感知光的强度,不能区分颜色。那彩色图像怎么来的?答案就是Bayer阵列。

Bayer阵列在像素上覆盖彩色滤光片,每个像素只允许一种颜色通过。最常见的排列是RGGB——一个红色、两个绿色、一个蓝色。为什么绿色有两个?因为人眼对绿色最敏感,多采样绿色能提升视觉分辨率。

我记得第一次调试Bayer图像时,看到原始数据吓了一跳——全是灰蒙蒙的,根本看不出颜色。后来才明白,每个像素只有一种颜色信息,其他颜色要靠插值算出来。

常见的Bayer排列有几种:

  • RGGB:最常用,索尼、三星主流传感器都用这个
  • BGGR:有些老款传感器用,比如某些OV传感器
  • GRBG:部分安森美传感器采用
  • GBRG:较少见,但偶尔会遇到

避坑指南:我曾经因为Bayer排列搞错,调试了三天色彩都不对。后来发现是传感器手册上写的排列和实际输出不一致。建议拿到新传感器后,先拍一张纯白画面,看看四个像素的数值关系,确认排列方式。

2.3 RAW数据格式解析:从像素到数字

RAW数据就是传感器直接输出的原始数字信号,没经过任何处理。它保留了最完整的信息,也是ISP调试的起点。

RAW数据的格式取决于ADC的位数。常见的有:

  • 8-bit:0-255,老款传感器或低端产品用
  • 10-bit:0-1023,主流手机传感器常用
  • 12-bit:0-4095,高端相机和工业相机用
  • 14-bit:0-16383,专业级传感器

我调试过一款12-bit的传感器,RAW数据范围是0-4095。但实际有效数据往往只用到中间一段,比如200-3800。为什么?因为暗部有噪声,亮部接近饱和,两端的数据质量都不好。

RAW数据的存储格式也需要注意:

// 常见的RAW数据打包方式
// 10-bit数据,每4个像素打包成5个字节
// 像素0: bits[9:2] 占1字节
// 像素0: bits[1:0] + 像素1: bits[9:4] 占1字节
// 像素1: bits[3:0] + 像素2: bits[9:6] 占1字节
// 像素2: bits[5:0] + 像素3: bits[9:8] 占1字节
// 像素3: bits[7:0] 占1字节

嗯,这个打包方式我第一次看时也头疼。后来写了个小工具,把RAW数据转成16-bit的PPM格式,才方便可视化调试。

注意事项:RAW数据中每个像素的数值是线性关系,但人眼对亮度的感知是非线性的。所以直接看RAW数据会觉得暗部太暗、亮部太亮。这是正常的,别慌。

2.4 黑电平与暗电流补偿

传感器在没有光照时,理论上应该输出0。但实际上会有暗电流和读出噪声,导致输出一个非零值。这个值就是黑电平。

我调试过一款传感器,黑电平是64(12-bit数据)。如果不做补偿,暗部会偏绿——因为绿色像素的暗电流比红色和蓝色大。嗯,这里要注意,不同颜色通道的黑电平可能不一样。

黑电平补偿的公式很简单:

// 黑电平补偿
// raw_data: 原始RAW值
// black_level: 黑电平值
// compensated_data = max(raw_data - black_level, 0)

// 实际项目中,黑电平可能随温度变化
// 我习惯在每帧图像中预留一些光学黑像素
// 用这些像素的平均值作为动态黑电平

经验之谈:我曾经遇到一个项目,黑电平补偿没做好,导致暗部出现条纹。排查了两天才发现,是传感器温度升高后黑电平漂移了。从那以后,我坚持用光学黑像素做动态补偿,再也没出过问题。

2.5 RAW数据的预处理流程

拿到RAW数据后,不能直接做色彩处理。需要先做几步预处理:

  1. 黑电平补偿:减去黑电平值
  2. 坏点校正:替换死像素和过热像素
  3. 增益调整:乘以模拟增益和数字增益
  4. 去马赛克:插值得到RGB图像

我个人习惯在预处理阶段就做坏点校正。因为坏点如果不处理,后续的插值会把坏点扩散到周围像素,影响更大。

坏点检测的方法很简单:如果一个像素的值明显偏离周围像素,比如超过3倍标准差,就标记为坏点。替换方法可以用周围像素的中值。

// 坏点校正示例
// 检测3x3窗口中的坏点
// 如果中心像素与周围8个像素的中值差异超过阈值
// 则用中值替换

uint16_t median = getMedian(window, 9);
if (abs(center - median) > threshold) {
    output = median;
} else {
    output = center;
}

小技巧:阈值怎么设?我一般用传感器读出噪声的3倍。比如读出噪声是5个电子,12-bit下就是5个DN,阈值设为15。太严了会把正常像素误判为坏点,太松了又漏检。

好了,这一章的内容就到这里。RAW数据是ISP调试的起点,理解透了才能做好后续的每一步。下一章咱们聊聊去马赛克算法,那可是个有意思的话题。