Camera - 数据格式 RAW、RGB
- Camera 数据格式-RAW、RGB
- 从摄像头工作的基本原理说起
- 回归本质-图像色彩的几种表示方法
- RGB 三原色
- RAW RGB 格式诞生
- RAW8 VS RAW10
- 真彩色-RGB888、BGR888 格式的引入
- 数据量小点的 RGB 格式-RGB565、RGB555
- 用位数表示的 RGB 格式
- RGB24:
- RGB32
- RGB4、RGB16
- 当3D效果、或者阴影变得重要-RGBA
- 总结
Camera 数据格式-RAW、RGB
概述:
本文主要讲述与 Camera 输出数据格式相关的基础知识,通过本文,你可以了解关于相机项目中摄像头输出格式的选择与原理。
从摄像头工作的基本原理说起
摄像头是一个包含感光芯片的光学器件。如下所示是一个典型的摄像头元器件的组成。其整体结构类似一个凸透镜成像原理。当相机的快门按下时,光线经过镜头组、滤光片,将收集到的光线照射在 CMOS 感光芯片的的感光矩阵上,感光芯片记录此时的光照情况。
摄像头组成(图片来自网络wiki)
回归本质-图像色彩的几种表示方法
RGB 三原色
物理老师告诉我们。自然界的颜色都可以通过红色、绿色、蓝色,即 Red、Green、Blue 三原色组合得到:
三原色(图片来自网络wiki)
如何记录每个像素点的 RGB 值?
RAW RGB 格式诞生
这需要用到上述相机组成中的一个元器件-滤光片。物理老师告诉我们,指定颜色的透镜只能通过与其颜色相同的。比如,红色透镜只能透过红色光:
(红色透镜只能通过红色光线-图片来自网络wiki)
为了恢复坐标(0,0)处实际的颜色,其需要 R\G\B 三个值,但是坐标(0,0)处只有红色滤光片,只能得到此处的红色数据。怎么办?
因此在生成该像素点的颜色值时其需要借用坐标(0,1)的像素点的绿色、借用坐标(1,1)处的蓝色,这样就组合成了R、G、B 三个值(不用担心啦,这种借用是经过考证的,恢复该点的颜色虽然有小小的误差,但完全没问题的)。
这里我们就引出了第一种数据格式的定义-RAW RGB。RAW RGB 是指经过上述滤光片过滤后形成的采样数据,即每个像素点只输出一种颜色对应的值,这种原始的R\G\B 数据称为 RAW RGB 格式。此时每个像素点对应的 RAW RGB 值为:
- 坐标(0,0): R00(后缀为横纵坐标)
- 坐标(0,1): G01
- 坐标(1,1): B11
RAW8 VS RAW10
如果上述 R00 用 8bit 的数值来表示,就是 RAW8。类似的,如果上述 R00 用 10bit 的数值来表示,就是 RAW10.
对于 8bit 数据的取值范围,也有不同的标准。
- 如果是 0~255,就是 full range 标准。
- 如果是 16 ~240,就是 limited range 标准。
真彩色-RGB888、BGR888 格式的引入
在这样的原始数据 RAW-RGB 生成后,摄像头可以通过软件或者硬件对其进行组合,还原该像素点的颜色。典型的采样是每个R、G或B 值用 8bit 的数据进行表示。这就引出了 RGB888 格式,即每个像素点的输出其对应的三原色的值(借用其他像素点的颜色喽)此时坐标(0,0)像素点对应的值为:
- 像素坐标(0,0)处用的 R\G\B 值为: R00+G01+B11
当然,你可以改变R\G\B 数据的排列顺序,比如: B11+G01+R00,这样就变成了 BGR888 格式的数据。
一些专业工具可以从图像中提取R、G、B三个分量的值:
(从图像中分离R、G、B-图片来自网络wiki)
数据量小点的 RGB 格式-RGB565、RGB555
在 RGB888 格式下,一个像素对应的数据大小是 8bit +8bit + 8bit,其可以形成 2^8*3 种颜色。尽管色彩更加无损,但数据量太大了。
允许一点误差,来减小下数据的大小吧。
每个像素的低 bit 位相比高 bit 位对整体数据的影响较小。比如舍掉 8bit 位的最后两位,对于该 8bit 位整体数据的误差不过是加减 {0,4} 。准寻这种规则,因此有了 RGB565 格式,它的数据相比与 RGB888 作了裁剪,但整体的数据量,从 24bits/pixel 降低到 16bits/pixel。后台在使用这种作了裁剪的数据时可以根据这种约定的裁剪规则,再恢复出 24bits 的 RGB888 值:
RGB888与 RGB565 对应的 bit 图(图片来自网络wiki)
不管哪种方式,我们再应用这些RGB数据类型时,都可以根据约定的规则,还原出其对应的 R、G、B 颜色。比如根据 RGB555 的存储方式,提取得到获取R,G,B分量的值。可以使用:
R = color & 0x7C00, (获取高字节的5个bit)
G = color & 0x03E0, (获取中间5个bit)
B = color & 0x001F, (获取低字节5个bit)
再比如根据 RGB888中的8bit R、G、B 分量转换得到 RGB565:
short int rgb565_pixel;
rgb565_pixel = ((R >> 3) << 11) | ((G >> 2) << 5) | (B >> 3);
用位数表示的 RGB 格式
除了上述的 RGB888、RGB555、RGB565 这种按照颜色对应的 Bit 位来描述的方法外,也有一些国家喜欢用总的位数来表示对应的 RGB 值(世界这么大,大家提一个自己喜欢的格式称呼也OK啦)。
RGB24:
RGB24, 一个像素用24个bit == 3个字节来表示,R, G,B分量分别用8个bit来表示。典型的就是上述 RGB888了。
RGB32
一些处理器在处理数据时需要 32bits 对齐,以快速处理图像数据。因此便有了 RGB32:
RGB4、RGB16
有的拍摄场景需要识别的颜色本来就不多,其表示颜色的方法,可以通过缺省一些颜色的 bit,来减小数据量。这些类型的方法与上述表示方法的原理类似。具体的表示方法可以咨询摄像头厂商来进一步确认。
当3D效果、或者阴影变得重要-RGBA
一些游戏设计或者图像处理时,会使用到带物体轮廓的颜色格式。典型的就是 ARGB 格式,其中:
ARGB 数据组成(图片来自网络wiki)
确切地说,ARGB 格式是 ARGB8888 格式(也称为 ARGB32)。ARGB 其分别是Alpha、Red、Green、Blue的缩写,因为其包含了该像素附近的4个信息,也被称为 4通道 表示方法。其中 alpha 是物体轮廓、透明度的意思。只有 alpha 的图像是灰度图像(灰度图像的示例我们将在下面的讨论中讲到),这在一些 3D 游戏或者图像处理中有额外的用处。比如使用 RGB888,与使用 ARGB8888 的图像区别:
ARGB 数据与 RGB 数据的比较(图片来自网络wiki)
小问题:了解 ARGB8888 后,相信大家应该知道 RGBA32 代表的意思了。牛皮!
总结
1)本文从摄像头工作的基本原理说起,Camera sensor 通过滤光片采集不同颜色的数据,生成 RAW 数据。
2)RAW 格式的数据,根据对每种颜色的表示使用几个 bit,也可以分为 RAW8、RAW10、RAW12 等类型。
3)RGB 数据是 RAW 数据组合得到的,根据组合顺序,可以组合得到 RGB、BGR 等格式的数据。
4)一些应用场景需要的数据带宽小、或者需要采集的颜色类型不多,这种情况下可以使用数据量更小的 RGB565、RGB555 等格式。
5)一些以总的数据长度命名的 RGB 格式的数据有 RGB24、RGB16、RGB32 等。
6)一些特别的应用场景还带有 Alpha 值,因此有 ARGB、RGBA 这种类型的 RGB 数据。
(码字不易,感谢点赞或收藏,谢绝未经授权的转载)