DSP

常见视频原始数据格式分析 — RGB

2019-07-13 20:16发布

1. RGB 简介

1.1 RGB {MOD}彩模式

RGB {MOD}彩模式是工业界的一种颜 {MOD}标准,是通过对红®、绿(G)、蓝(B)三个颜 {MOD}通道的变化以及它们相互之间的叠加来得到各式各样的颜 {MOD}的。 Red、Green、Blue 每一种颜 {MOD}值的范围是 0~255,所以每一个颜 {MOD}用 1 个字节 = 8 个 bit 便可完全在计算机内部表示出来。而 R、G、B 不同的组合几乎产生了所有的颜 {MOD},当然自然界中的颜 {MOD}比这些要远远丰富很多,采用 R、G、 B 的方式,如果以 24 {MOD}深表示的话,在计算机中可表示的颜 {MOD}数量有 2^8 * 2 ^8 * 2 ^8 = 16777216 种颜 {MOD},虽没有自然界丰富,但也足以表示这个世界了。

1.2 RGB 的应用

目前的显示器大都是采用了RGB颜 {MOD}标准。 电脑屏幕上的所有颜 {MOD},都由这红 {MOD}绿 {MOD}蓝 {MOD}三种 {MOD}光按照不同的比例混合而成的。一组红 {MOD}绿 {MOD}蓝 {MOD}就是一个最小的显示单位。屏幕上的任何一个颜 {MOD}都可以由一组 RGB 值来记录和表达。 在电脑中,RGB 的所谓 “多少” 就是指亮度,并使用整数来表示。通常情况下,RGB 各有 256 级亮度,用数字 0~255 表示。

1.3 RGB 原理

RGB 是从颜 {MOD}发光的原理来设计定的,通俗点说它的颜 {MOD}混合方式就好像有红、绿、蓝三盏灯,当它们的光相互叠合的时候, {MOD}彩相混,而亮度却等于两者亮度之总和,越混合亮度越高,即加法混合。 有 {MOD}光可被无 {MOD}光冲淡并变亮。 加法混合的特点:越叠加越明亮。 红、绿、蓝三个颜 {MOD}通道每种 {MOD}各分为 255 阶亮度,在 0 时 “灯” 最弱是关掉的,而在 255 时 “灯” 最亮。当三 {MOD}数值相同时为无 {MOD}彩的灰度 {MOD},而三 {MOD}都为 255 时为最亮的白 {MOD},都为 0 时为黑 {MOD}。

2. RGB 格式

简单来讲,RGB 在计算机中的表示主要分为两大类,一种是索引形式,一种是像素形式。 (1) 索引
诸如 RGB1、RGB4、RGB8,分别表示每个像素用 1 个 bit,、4 个 bit、 8 个 bit 来表示,那么,这些 bit 存储的并非是实际的 R、G、B 值,而是对应点的像素在调 {MOD}板的索引。 (2) 像素形式
诸如 RGB565、RGB555、 RGB24、RGB32、ARGB32 这些格式,存储的是每一个像素点的 R、G、B 值。比如 RGB24,分别用 8 个 bit 去表示 R、G、B。

2.1 RGB 索引格式

RGB 索引格式是比较老的格式,比较节省空间,在计算机发展的初期存储的成本还是很高的,但是表现的 {MOD}彩很有限,而随着存储成本的不断降低,以及用户越来越高的视觉体验需求,这些格式也就基本被抛弃,不再被使用了,所以深入研究的意义也并不很大。只做简单介绍。 常用的 RGB 索引格式有:RGB1、GRB4、RGB8
关于调 {MOD}板,可以简单理解为通过编号映射到颜 {MOD}的一张二维表。如 01 索引,表示红 {MOD}。采用索引格式的 RGB,红 {MOD}的像素对应存储的值便是索引 01。

1) RGB1

每个像素用 1 个 bit 表示,可表示的颜 {MOD}范围为双 {MOD},即最传统的黑和白。 1 个 bit 只能表示 0、1两种值。需要调 {MOD}板,不过调 {MOD}板只包含两种颜 {MOD}。

2)RGB4:

每个像素用 4 个 bit 表示,4 个 bit 所能够表示的索引范围是 0-15 共 16 个。也就是可以表示 16 种颜 {MOD}。即调 {MOD}板中包含 16 种颜 {MOD}。

3)RGB8

每个像素用 8 个 bit 表示。8 个 bit 所能够表示的索引范围是 0-255 ,共 256 个。也就是可以表示 256 种颜 {MOD}。即调 {MOD}板中包含 256 种颜 {MOD}。

2.2 RGB 像素格式

比较常用的 RGB 像素格式包括:RGB565、RGB555、RGB24、RGB32、 ARGB32 等,不同的格式本质便是对于每一种单 {MOD}的不同存储和表示方法。 下面每一种格式按照简介、存储示意图以及获取具体像素的方法来讲解

1) RGB565

a) 概述
RGB565 格式每一个像素用 16 个 bit 来表示,也就是 2 个字节, 1 个 WORD。 R、G、B 分别用 5、6、5 个 bit 来表示,格式也因此而得名。
b) 存储示意图
image
c) 获取具体像素值方法
根据 RGB565 的存储方式,即可得到获取 R、G、B 分量的值。现假设计算机中存储某一个像素点的变量为 color, 数据类型为 short. 那么则有: R = color & 0xF800, (获取高字节的 5 个 bit) G = color & 0x07E0, (获取中间 6 个 bit) B = color & 0x001F, (获取低字节 5 个 bit)

2) RGB55

a) 概述
RGB55 格式每一个像素用 16 个 bit 来表示,也就是 2 个字节, 1 个 WORD。但是最高位不用,R、G、B 分别用 5 个 bit 来表示。
b) 存储示意图
image
c) 获取具体像素值方法
根据 RGB55 的存储方式,即可得到获取 R、G、B 分量的值。现假设计算机中存储某一个像素点的变量为 color, 数据类型为 short. 那么则有: R = color & 0x7C00, (获取高字节的 5 个 bit) G = color & 0x03E0, (获取中间 5 个 bit) B = color & 0x001F, (获取低字节 5 个 bit)

3) RGB24(RGB888)

a) 概述
RGB24 格式每一个像素用 24 个 bit 来表示,也就是 3 个字节。R、G、B 分量分别用 8 个 bit 来表示。
RGB24 也常被叫做 RGB888。
b) 存储示意图
image
c) 获取具体像素值方法
根据 RGB24 的存储方式,即可得到获取 R、G、B 分量的值。现假设计算机中存储某一个像素点的变量为 color, 数据类型为 short. 那么则有: R = color & 0x000000FF, G = color & 0x0000FF00, B = color & 0x00FF0000,

4) RGB32

a) 概述
RGB32 格式每一个像素用 32 个 bit 来表示,也就是 4 个字节。R、G、B 分量分别用 8 个 bit 来表示,存储顺序为 B、G、R,最后 8 个字节保留。
b) 存储示意图
image
c) 获取具体像素值方法
根据 RGB32 的存储方式,即可得到获取 R、G、B 分量的值。现假设计算机中存储某一个像素点的变量为 color, 数据类型为 short. 那么则有: R = color & 0x0000FF00 G = color & 0x00FF0000, B = color & 0xFF000000,

3. 几种常用 RGB 格式处理例子

3.1 RGB565 转 RGB888 的实现

16 bit RGB565 -> 24 bit RGB888 的转换由于精度不同,故需要做量化补偿。 下面简单介绍下量化补偿的原理: 量化补偿的方法: 1. 将原数据填充至高位 2. 对于低位,用原始数据的低位进行补偿 3. 如果仍然有未填充的位,继续使用原始数据的低位进行循环补偿 例子: 16 bit RGB565 -> 24 bit RGB888 的转换 16 bit RGB656: R4 R3 R2 R1 R0 G5 G4 G3 G2 G1 G0 B4 B3 B2 B1 B0 24 bit RGB888: R4 R3 R2 R1 R0 0 0 0 G5 G4 G3 G2 G1 G0 0 0 B4 B3 B2 B1 B0 0 0 0 24 bit RGB888: R4 R3 R2 R1 R0 R2 R1 R0 G5 G4 G3 G2 G1 G0 G1 G0 B4 B3 B2 B1 B0 B2 B1 B0 其中,第三行的 24 bit RGB888 数据是经过量化补偿的数据,对低位做了量化补偿。 代码实现: void rgb565_to_rgb888(unsigned char *image, unsigned char *image888) { unsigned char R, G, B; R = *(image + 1) & 0xF8; // 补齐成:RRRRR000 G = (*(image + 1) << 5) | (*image & 0xe0 >> 3); // 补齐成:GGGGGG00 B = *image << 3 ; // 补齐成: BBBBB000 // 补偿 *(image888) = B | ((B & 0x38) >> 3); *(image888 + 1) = G | ((G & 0x0c) >> 2); *(image888 + 2) = R | ((R & 0x38) >> 3); }

3.2 RGB888 转 RGB565 的实现

同上,如果是 RGB888-> RGB565,在精度上减少了,故需要做量化压缩 下面简单介绍下量化压缩的原理: 量化压缩的方法: 三个字取高位 例子: 24 bit RGB888 -> 16 bit RGB565 的转换 24 bit RGB888:R7 R6 R5 R4 R3 R2 R1 R0 G7 G6 G5 G4 G3 G2 G1 G0 B7 B6 B5 B4 B3 B2 B1 B0 16 bit RGB656: R7 R6 R5 R4 R3 G7 G6 G5 G4 G3 G2 B7 B6 B5 B4 B3 unsigned short rgb_24_to_565(unsigned short r, unsigned short g, unsigned short b) { return ((r << 8) & 0xF800) | ((g << 3) & 0x07E0) | ((b >> 3) & 0x001f); } 待添加…