第二章 图像传感器与RAW域基础
各位同学,今天我们来聊聊ISP流水线的起点——RAW域。说白了,图像传感器就是相机的「视网膜」,而RAW数据就是它最原始、最诚实的「记忆」。我做了这么多年ISP,发现很多算法工程师对RAW域的理解不够深,上来就调RGB图,结果效果总差一口气。嗯,这一章我们就把底层的这些东西讲透。
2.1 CMOS传感器工作原理
CMOS传感器怎么工作的?简单说就是「光电转换」四个字。每个像素点上的光电二极管接收光子,产生电子,然后通过模数转换器(ADC)变成数字信号。
我当年刚入行时,总觉得传感器就是个黑盒子。直到有一次调试夜景模式,发现暗部全是条纹噪声,查了三天才发现是传感器读出电路的问题。从那以后,我再也不敢小看传感器物理特性了。
核心指标:
- 量子效率(QE):光子转电子的效率,越高越灵敏
- 满阱容量(FWC):一个像素能装多少电子,决定动态范围
- 读出噪声:读出电路引入的噪声,影响暗部画质
- 暗电流:没光照时也会产生的电子,导致热噪点
这里有个关键点:传感器输出的信号是线性的。光强翻倍,数字值也翻倍。这和人的视觉感知完全不同——人眼是对数响应的。所以后面做Gamma校正、色调映射,本质上都是在做「线性→感知」的转换。
2.2 Bayer阵列与CFA插值
单颗像素只能感知亮度,分不清颜色。怎么办?在传感器表面盖一层彩色滤光片阵列(CFA),让不同像素只通过特定波长的光。最常见的Bayer阵列,就是RGGB模式。
为什么是RGGB而不是RGRG?因为人眼对绿色最敏感,所以绿色像素占一半,红色和蓝色各占四分之一。你想想看,这样设计是不是很巧妙?
| 像素位置 | R | G | B |
|---|---|---|---|
| 奇数行奇数列 | R | - | - |
| 奇数行偶数列 | - | G | - |
| 偶数行奇数列 | - | G | - |
| 偶数行偶数列 | - | - | B |
每个像素只有一种颜色信息,要得到全彩图,就得做CFA插值(也叫去马赛克)。常用的方法有:
- 最近邻插值:最快,但锯齿严重,基本不用
- 双线性插值:简单,但边缘模糊
- 边缘导向插值:先检测边缘方向,沿边缘插值,效果好很多
- 自适应插值:根据局部纹理复杂度动态选择插值策略
我的经验:插值算法不是越复杂越好。在夜景场景下,复杂插值反而容易放大噪声。我一般建议在RAW域先做降噪,再做插值,顺序不能乱。
2.3 黑电平校正与LSC
这两个是RAW域预处理的标准动作,不做的话后面全是错的。
黑电平校正(BLC)
传感器在完全无光时,输出并不是0。因为电路有偏置电压,ADC也有偏移。这个偏移值就是黑电平。校正方法很简单:
// 黑电平校正伪代码
for each pixel:
corrected_pixel = raw_pixel - black_level
if corrected_pixel < 0:
corrected_pixel = 0
黑电平值怎么获取?传感器厂商会提供,或者从传感器边缘的遮光像素(OB像素)中统计得到。我遇到过一台手机,黑电平随温度漂移严重,最后不得不做实时OB像素统计校正。
注意:黑电平校正必须在其他所有处理之前做。如果先做增益再减黑电平,暗部噪声会被放大,而且黑电平偏移会导致颜色偏色。
镜头阴影校正(LSC)
镜头中心光线垂直入射,边缘光线斜入射,导致边缘亮度下降(也叫暗角)。另外,不同波长的光折射率不同,还会导致边缘偏色。
LSC的原理很简单:给每个像素乘一个增益系数。系数通常用网格形式存储,运行时做双线性插值。
// LSC校正伪代码
for each pixel (x, y):
gain = interpolate_gain(x, y, lsc_table)
corrected_pixel = raw_pixel * gain
我个人习惯在实验室用均匀光源拍一张灰卡,然后反推出增益网格。注意,LSC系数和镜头焦距、光圈都有关系,变焦镜头需要多组系数。
2.4 RAW域数据格式解析
RAW数据不是普通的图像文件。它有几个关键参数:
| 参数 | 说明 | 常见值 |
|---|---|---|
| 位深 | 每个像素的比特数 | 10bit, 12bit, 14bit |
| Bayer模式 | CFA排列方式 | RGGB, GRBG, BGGR |
| 数据排列 | 像素在内存中的存储顺序 | 连续、交错、MIPI格式 |
| 黑电平 | 暗电流偏移值 | 64@10bit, 256@12bit |
| 白电平 | 饱和值 | 1023@10bit, 4095@12bit |
举个例子,高通平台的RAW数据通常以MIPI CSI接口传输,10bit数据用16bit对齐存储,每个像素占2字节,高6位补0。解析时要注意字节序和位对齐。
实战要点:
- 拿到RAW文件第一件事:确认Bayer模式和位深
- 第二件事:检查黑电平是否已经减去
- 第三件事:看数据是否有坏点(死像素)
我曾经接手过一个项目,RAW图看起来全是条纹,排查了半天才发现是数据解析时Bayer模式搞反了。嗯,这种低级错误,犯过一次就再也不会忘了。
本章知识体系
下面这张图总结了RAW域处理的核心流程和关键节点,我建议你把它记在脑子里:
这张图把RAW域处理的几个关键步骤串起来了。你注意看,BLC和LSC是并行的,做完之后才能做CFA插值。顺序错了,后面再怎么调也救不回来。
好了,这一章的内容就到这里。RAW域是ISP的根基,理解透了,后面讲降噪、讲夜景增强,你才能知道为什么要在RAW域做、怎么做效果最好。