第二章:图像传感器与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数据后,不能直接做色彩处理。需要先做几步预处理:
- 黑电平补偿:减去黑电平值
- 坏点校正:替换死像素和过热像素
- 增益调整:乘以模拟增益和数字增益
- 去马赛克:插值得到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调试的起点,理解透了才能做好后续的每一步。下一章咱们聊聊去马赛克算法,那可是个有意思的话题。