4、图像采集与输入模块:RAW图数据格式解析

好,咱们进入第四章。这一章讲的是整个ISP调试流程的起点——图像怎么进来的,进来之后长什么样,我们怎么确认它没坏。

说白了,你后面所有的调色、降噪、锐化,都是建立在RAW数据正确的基础上的。源头错了,后面全是白费功夫。我在项目里见过有人调了三天颜色,最后发现是Bayer顺序搞反了……嗯,那感觉,你懂的。

4.1 RAW图到底是什么?

RAW不是一张“图片”,它是一堆原始电荷信号。每个像素只记录一种颜色——要么红,要么绿,要么蓝。这就是Bayer阵列的由来。

最常见的Bayer模式是RGGB。你想想看,四个像素一组,一个红,两个绿,一个蓝。为什么绿色多一个?因为人眼对绿色最敏感。这个设计很巧妙,对吧?

Bayer阵列示意(RGGB):

R  G  R  G  ...
G  B  G  B  ...
R  G  R  G  ...
G  B  G  B  ...
...

还有一种叫RGBIR,就是多了一个红外通道。我在对接安防摄像头时遇到过这种。四个像素分别是R、G、B、IR。白天用RGB,晚上切IR。但要注意,IR通道会串扰到RGB,需要做校正。

4.2 Sensor驱动对接——这一步最容易翻车

Sensor驱动对接,说白了就是让主控芯片能跟Sensor“说话”。一般通过I2C或SPI配置寄存器,MIPI传数据。

我个人习惯,第一步先读Sensor的ID寄存器。如果ID都对不上,后面就不用聊了。我曾经遇到一个项目,Sensor型号贴错了标签,读出来的ID跟手册不一样,排查了两天才发现是硬件焊错了片子。

驱动对接检查清单:

  • I2C地址是否正确?有些Sensor有多个地址可选
  • MIPI Lane数、速率是否匹配?
  • PCLK极性、HSYNC/VSYNC极性对不对?
  • 曝光和增益的寄存器地址确认了吗?

还有一点,很多Sensor默认输出的是10bit或12bit数据。但主控可能只支持8bit。这时候就要配置Sensor的压缩模式,或者主控端做截位。我建议尽量用高位宽,后期处理空间更大。

4.3 DNG文件读取与校验

DNG是Adobe推出的RAW通用格式。调试时我们经常用DNG来保存Sensor的原始数据,方便在PC上分析。

读取DNG,我一般用libraw或者直接解析TIFF结构。DNG本质上就是TIFF,里面包含RAW数据、元数据、以及一些校正参数。

用Python读取DNG的简单示例:

import rawpy
import numpy as np

# 读取DNG文件
raw = rawpy.imread('test.dng')
# 获取Bayer原始数据
bayer = raw.raw_image  # 形状为 (H, W)
# 获取黑电平、白电平
black_level = raw.black_level_per_channel
white_level = raw.white_level
print(f'黑电平: {black_level}, 白电平: {white_level}')

校验DNG文件,我主要看三点:

  1. 数据完整性——有没有坏行、坏列?我习惯用暗场图(盖上镜头盖拍一张)来检查。正常应该是均匀的噪声,如果出现亮线,那就是Sensor或者传输有问题。
  2. 黑电平是否稳定——黑电平如果漂移,暗部颜色就会偏。我曾经遇到一批Sensor,温度一高黑电平就往上跳,后来发现是电源纹波太大。
  3. Bayer顺序是否正确——这个最简单,对着光源拍一张,看解出来的颜色对不对。如果红色变成蓝色,那就是Bayer顺序反了。

注意:DNG文件里的元数据不一定可信。有些Sensor厂商填的黑电平值是错的。我建议你自己从暗场数据里算一遍,别偷懒。

4.4 避坑指南——我踩过的几个坑

  • MIPI信号不稳定——表现为图像有随机条纹。我曾经排查了三天,最后发现是FPC排线太长,信号衰减了。解决办法:降低MIPI速率,或者换屏蔽线。
  • Bayer顺序搞混——不同厂商的Sensor,Bayer起始位置可能不同。有的从R开始,有的从G开始。拿到新Sensor,第一件事就是确认Bayer顺序。
  • DNG文件打不开——有些工具对DNG版本有要求。我建议用Adobe DNG Converter转一下,或者直接用rawpy库读,兼容性最好。

嗯,这一章的内容差不多就这些。图像采集是ISP的基石,这块做扎实了,后面调起来才顺手。下一章我们讲RAW域的预处理——黑电平校正和去噪,那才是真正开始动刀子的地方。