第三章 RAW图数据格式:RAW12/RAW10/RAW8格式解析、Bayer模式与黑电平

各位同学,今天我们来聊聊RAW图。很多刚入行的朋友问我,为什么非要搞这么复杂的RAW格式?直接输出RGB不好吗?嗯,这个问题我当年也问过我的导师。

说白了,RAW图就是传感器最原始的“底片”。它记录了每个像素点捕捉到的光子数量,没有任何加工。你想想看,如果一开始就做白平衡、伽马校正,后面再想调整画质,信息已经丢失了。所以,ISP调优的第一步,就是跟RAW图打交道。

3.1 RAW数据格式:RAW12、RAW10、RAW8

传感器输出的数据,每个像素点用多少比特来表示,这就是位深。常见的车载摄像头,位深有8bit、10bit、12bit。我个人的习惯是,能选12bit就别选10bit,能选10bit就别选8bit。为什么?

因为位深决定了动态范围。8bit只能表示0-255的灰度,而12bit可以表示0-4095。在夜间或者隧道这种大光比场景,8bit很容易出现暗部死黑、亮部过曝。我在项目中遇到过,某款车规级摄像头为了省带宽用了RAW8,结果晚上拍出来的车牌根本看不清——后来改成了RAW10,效果立竿见影。

不过,位深越高,数据量也越大。我们来看看实际的数据量对比:

格式 每像素比特数 灰度等级 典型应用场景
RAW8 8bit 256 低端摄像头、玩具
RAW10 10bit 1024 主流车载摄像头
RAW12 12bit 4096 高端ADAS、激光雷达融合

这里有个细节要注意。RAW10和RAW12在存储时,并不是简单地每个像素占10bit或12bit。为了对齐字节,厂商通常会做packing。比如RAW10,4个像素打包成5个字节(40bit)。RAW12则是2个像素打包成3个字节(24bit)。

重要提示:在做ISP调试时,一定要确认好数据格式的packing方式。我曾经见过一个团队,因为搞错了RAW10的字节对齐,整个图像都是错位的,排查了整整两天。

3.2 Bayer模式:RGGB、GBRG、GRBG、BGGR

接下来是Bayer模式。这是彩色图像的基础。传感器上的每个像素只能感知光的强度,不能感知颜色。那怎么得到彩色图像呢?答案是在像素表面覆盖一层彩色滤光片,形成Bayer阵列。

最常见的Bayer模式是RGGB,也就是第一行是R、G、R、G...,第二行是G、B、G、B...。但不同的传感器厂商,排列方式可能不同。比如索尼喜欢用RGGB,而安森美有些型号用GBRG。

你可能会问,为什么绿色像素占了一半?因为人眼对绿色最敏感。这个设计很巧妙,说白了就是模仿人眼的视觉特性。

我建议大家在调试前,先确认好Bayer模式。怎么确认?很简单,拍一张纯色画面,比如蓝色天空。如果图像偏绿,那可能是Bayer模式搞反了。我曾经在调试一个项目时,客户给的文档写的是RGGB,但实际传感器是GBRG。结果我调了一整天白平衡都不对,最后发现是Bayer模式错了——嗯,从那以后我每次都会先做Bayer模式验证。

调试技巧:可以用一个简单的方法验证Bayer模式。拍一张纯红色画面,如果图像中红色像素的位置符合预期,那就对了。否则,尝试其他三种排列。

3.3 黑电平与暗电流

黑电平,英文叫Black Level。这个概念很多人容易忽略,但它直接影响图像的暗部表现。

理想情况下,传感器在没有光照时,输出应该是0。但实际不是这样。由于暗电流的存在,即使完全遮光,传感器也会产生一定的电荷。这个电荷会叠加到信号上,导致暗部发灰。

暗电流是什么?说白了,就是热噪声。温度越高,暗电流越大。车载摄像头工作环境温度范围很宽,从-40°C到85°C甚至更高。夏天暴晒后,车内温度可能达到70°C以上,暗电流会显著增加。

黑电平校正的目的,就是减去这个底噪。通常的做法是,在传感器边缘设置一些遮光像素(OB像素,Optical Black),这些像素不感光,只输出暗电流。然后取这些像素的平均值,作为黑电平值。

注意:黑电平不是固定值。它会随温度、增益、曝光时间变化。我建议在ISP中做动态黑电平校正,而不是用固定值。否则,温度变化时,暗部会出现偏色或噪声。

具体怎么操作?以RAW10为例,假设黑电平是64,那么每个像素值减去64,得到的就是校正后的信号。但要注意,减法后可能出现负值,需要做截断处理。

// 黑电平校正示例(C语言伪代码)
uint16_t raw_pixel = get_raw_pixel();
uint16_t black_level = get_black_level(); // 动态获取
int16_t corrected = (int16_t)raw_pixel - (int16_t)black_level;
if (corrected < 0) corrected = 0;
if (corrected > 1023) corrected = 1023; // RAW10最大值

这里有个坑。有些传感器输出的黑电平不是整数,而是带小数的。比如黑电平是63.5。这时候需要做四舍五入或者用定点数处理。我个人的习惯是,用16位精度做中间计算,最后再截断到10位或12位。

3.4 实战中的注意事项

最后,我总结几个实战中容易踩的坑:

  • Bayer模式搞错:图像会出现严重的伪色。我曾经在调试一个环视系统时,四个摄像头用了不同的Bayer模式,结果拼接出来的图像色彩混乱。后来统一了Bayer模式,问题解决。
  • 黑电平未校正:暗部发灰,动态范围损失。尤其是在夜间,黑电平不准确会导致噪点放大。
  • RAW格式解析错误:比如把RAW10当成RAW8解析,图像会过曝。把RAW12当成RAW10,图像会偏暗。
  • 忽略温度影响:实验室调试好的参数,上车后因为温度变化,黑电平漂移,图像质量下降。

好了,这一章的内容就到这里。RAW图是ISP调优的起点,把基础打牢,后面才能事半功倍。下一章我们会讲去噪算法,到时候再聊。