3、RAW图数据格式:Bayer Pattern、RAW10/RAW12格式解析、数据对齐与存储

好,咱们进入第三章。这一章讲的是RAW图的数据格式,说白了就是传感器吐出来的原始数据长什么样。我刚开始接触这行时,总觉得RAW就是RAW,有啥好讲的?后来踩了坑才明白——格式没搞对,后面所有调试都是白费功夫。

3.1 Bayer Pattern:传感器的“马赛克”世界

先问个问题:为什么传感器拍出来的是黑白灰的马赛克,而不是彩色图像?

原因很简单——每个像素点只能感知光的强度,分辨不了颜色。那怎么得到彩色呢?答案就是在像素表面覆盖一层彩色滤光片阵列,也就是Bayer Pattern。

最常见的Bayer Pattern是RGGB,也就是一个像素点阵里,红色、绿色、绿色、蓝色按2x2排列。为什么绿色有两个?因为人眼对绿色最敏感,传感器就多给绿色一些采样权重。

Bayer Pattern 四种常见排列

  • RGGB:最主流,索尼、三星大部分传感器都用这个
  • BGGR:有些OmniVision传感器用这个
  • GRBG:部分安森美传感器采用
  • GBRG:较少见,某些特殊应用场景

我在项目中遇到过最坑的事:拿到一个模组厂送来的RAW图,怎么调颜色都不对,折腾了两天才发现——他们给的Bayer顺序标错了,实际是BGGR,文档写的是RGGB。你想想看,Bayer顺序搞反,后面ISP的demosaic全乱套,颜色能对吗?

所以拿到新传感器,第一件事就是拍一张均匀光照下的白板,然后看RAW图的像素排列,确认Bayer顺序。别信文档,信眼睛。

3.2 RAW10与RAW12:位深度的选择

Bayer Pattern决定了像素的排列方式,那每个像素用多少bit来表示呢?这就是位深度的问题。

常见的RAW位深度有RAW8、RAW10、RAW12、RAW14、RAW16。手机传感器现在主流是RAW10,高端安防和工业相机用RAW12甚至RAW14。为什么?

说白了,位深度决定了动态范围和信噪比的上限。RAW8只有256个灰度等级,RAW10有1024级,RAW12有4096级。级数越多,暗部细节越丰富,亮部也不容易饱和。

格式 位深度 灰度等级 典型应用
RAW8 8-bit 256 低端摄像头、玩具
RAW10 10-bit 1024 手机主摄、行车记录仪
RAW12 12-bit 4096 安防监控、工业相机
RAW14 14-bit 16384 专业相机、医疗影像

我个人习惯是:如果带宽允许,尽量用RAW12以上。RAW10虽然省带宽,但后期做tone mapping时,暗部提亮很容易出现banding(条带噪声)。

小技巧:调试阶段先用RAW12采集数据,分析清楚噪声和动态范围后,再根据产品需求决定是否压缩到RAW10。这样能避免早期就丢失信息。

3.3 数据对齐与存储:别让位宽坑了你

好,现在我们知道每个像素是10-bit或12-bit了。但问题来了——内存和总线是按8-bit(1字节)对齐的。10-bit数据怎么塞进8-bit的容器里?

这就涉及到数据对齐方式。常见的有两种:

  • 高位对齐(Left Justified):数据放在高bit位,低bit位补0。比如10-bit数据0x3FF,存成16-bit就是0xFFC0。优点是精度损失小,缺点是浪费带宽。
  • 低位对齐(Right Justified):数据放在低bit位,高bit位补0。比如10-bit数据0x3FF,存成16-bit就是0x03FF。优点是计算方便,缺点是高位无效bit会引入噪声。

我遇到过最头疼的事:某次调试一个RAW12的传感器,MIPI抓出来的数据怎么看怎么不对,波形都对,但图像全是条纹。后来发现是驱动里把数据对齐方式搞反了——传感器输出是高位对齐,驱动按低位对齐去解析,结果每个像素都偏移了2个bit。

注意:不同传感器厂商的对齐方式可能不同。Sony IMX系列默认高位对齐,OmniVision有些型号默认低位对齐。拿到新传感器,先看datasheet里的数据格式说明,再用已知的RAW图验证一遍。

3.4 RAW10的打包格式:10-10-10-2模式

RAW10如果每个像素都占16-bit,带宽浪费40%。所以MIPI CSI-2定义了一种打包方式:4个10-bit像素打包成5个字节(40-bit)。

具体怎么打包的?我画个图你就明白了。

RAW10 打包格式:4个像素 → 5字节 原始10-bit数据: Pixel 0 [9:0] Pixel 1 [9:0] Pixel 2 [9:0] Pixel 3 [9:0] 打包后5字节: Byte 0 P0[9:2] Byte 1 P1[9:2] Byte 2 P2[9:2] Byte 3 P3[9:2] Byte 4 P3[1:0]|P2[1:0]|P1[1:0]|P0[1:0] 说明:每个像素的高8-bit([9:2])分别存入Byte0~Byte3, 4个像素的低2-bit([1:0])合并存入Byte4,顺序为P0[1:0]→P1[1:0]→P2[1:0]→P3[1:0]。

这种打包方式在MIPI CSI-2的RAW10模式下是标准做法。你写驱动时,解包逻辑就是反过来:从5个字节里拆出4个10-bit像素。

调试经验:验证解包是否正确,可以拍一张均匀灰卡,然后看RAW图的直方图。如果解包正确,直方图应该是平滑的;如果出现周期性的尖峰或空洞,大概率是解包时bit偏移了。

3.5 RAW12的存储:16-bit对齐还是12-bit打包?

RAW12的情况稍微复杂一些。有两种主流存储方式:

  • 16-bit对齐存储:每个12-bit像素占用16-bit(2字节),高4-bit补0或保留。优点是访问简单,缺点是带宽浪费25%。
  • 12-bit打包存储:类似RAW10的打包方式,但这里是2个像素打包成3字节(24-bit)。带宽利用率100%,但解包逻辑复杂一些。

我个人建议:在调试阶段用16-bit对齐存储,省心。等产品定型、需要优化带宽时,再改成12-bit打包。别一开始就搞复杂打包,出了问题排查起来很痛苦。

3.6 实战:如何从RAW图中验证格式正确性

好,理论讲完了,说点实际的。你拿到一张RAW图,怎么确认它的格式是对的?

我一般按这个步骤来:

  1. 看文件头:有些RAW文件有头信息,里面会写位深度、Bayer顺序、分辨率。没有头信息的,就靠猜了。
  2. 看直方图:RAW10的直方图最大值应该是1023,RAW12是4095。如果看到最大值是255,那可能是被截断成RAW8了。
  3. 看Bayer顺序:拍一张边缘清晰的黑色物体在白色背景上,然后放大看RAW图的像素值。沿着边缘看R、G、B通道的响应,就能推断出Bayer排列。
  4. 看数据对齐:如果图像整体偏暗,但某些像素异常亮,可能是对齐方式搞反了,高位数据被当成了低位。

避坑指南:我曾经拿到一个模组厂的RAW图,直方图显示最大值是1023,但图像看起来就是不对。后来发现他们用的是RAW10,但MIPI传输时用了RAW8的D-PHY速率,导致高2-bit被截断了。所以不仅要看RAW格式,还要确认传输链路没有丢bit。

3.7 本章小结

RAW图的数据格式,说白了就是三件事:Bayer Pattern决定颜色排列,位深度决定动态范围,数据对齐决定怎么存怎么读。这三件事任何一个搞错,后面的ISP pipeline全是白搭。

我做了这么多年传感器调试,最深的体会就是:拿到新传感器,别急着调3A,先把RAW格式吃透。花半天时间验证Bayer顺序、位深度、对齐方式,能省后面几天的排查时间。