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文件,我主要看三点:
- 数据完整性——有没有坏行、坏列?我习惯用暗场图(盖上镜头盖拍一张)来检查。正常应该是均匀的噪声,如果出现亮线,那就是Sensor或者传输有问题。
- 黑电平是否稳定——黑电平如果漂移,暗部颜色就会偏。我曾经遇到一批Sensor,温度一高黑电平就往上跳,后来发现是电源纹波太大。
- Bayer顺序是否正确——这个最简单,对着光源拍一张,看解出来的颜色对不对。如果红色变成蓝色,那就是Bayer顺序反了。
注意:DNG文件里的元数据不一定可信。有些Sensor厂商填的黑电平值是错的。我建议你自己从暗场数据里算一遍,别偷懒。
4.4 避坑指南——我踩过的几个坑
- MIPI信号不稳定——表现为图像有随机条纹。我曾经排查了三天,最后发现是FPC排线太长,信号衰减了。解决办法:降低MIPI速率,或者换屏蔽线。
- Bayer顺序搞混——不同厂商的Sensor,Bayer起始位置可能不同。有的从R开始,有的从G开始。拿到新Sensor,第一件事就是确认Bayer顺序。
- DNG文件打不开——有些工具对DNG版本有要求。我建议用Adobe DNG Converter转一下,或者直接用rawpy库读,兼容性最好。
嗯,这一章的内容差不多就这些。图像采集是ISP的基石,这块做扎实了,后面调起来才顺手。下一章我们讲RAW域的预处理——黑电平校正和去噪,那才是真正开始动刀子的地方。