LV01-图像-02-色彩空间-02-RGB
本文主要是色彩编码——YUV的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
PC端开发环境 | Windows | Windows11 |
Ubuntu | Ubuntu20.04.6的64位版本 | |
VMware® Workstation 17 Pro | 17.0.0 build-20800274 | |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) | |
Win32DiskImager | Win32DiskImager v1.0 | |
Linux开发板环境 | Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) | |
linux内核 | linux-4.15(NXP官方提供) |
点击查看本文参考资料
- 通用
参考资料 | 相关链接 |
RGB | 图解RGB565、RGB555、RGB16、RGB24、RGB32、ARGB32等格式的区别 |
视音频数据处理 | 视音频数据处理入门:RGB、YUV像素数据处理 |
点击查看相关文件下载
--- | --- |
一、RGB是什么?
1. 简介
百度百科RGB(颜色系统)_百度百科 (baidu.com)是这样说的:RGB 色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB 即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
RGB是从颜色发光的原理来设计定的,通俗点说它的颜色混合方式就好像有红、绿、蓝三盏灯,当它们的光相互叠合的时候,色彩相混,而亮度却等于三者亮度之总和,越混合亮度越高,即加法混合。
红、绿、蓝三盏灯的叠加情况,中心三色最亮的叠加区为白色,加法混合的特点:越叠加越明亮。红、绿、蓝三个颜色通道每种色各分为256阶亮度,在0时“灯”最弱——是关掉的,而在255时“灯”最亮。当三色灰度数值相同时,产生不同灰度值的灰色调,即三色灰度都为0时,是最暗的黑色调;三色灰度都为255时,是最亮的白色调。
RGB 颜色称为加成色,因为我们通过将 R、G 和 B 添加在一起(即所有光线反射回眼睛)可产生白色。加成色用于照明光、电视和计算机显示器。例如,显示器通过红色、绿色和蓝色荧光粉发射光线产生颜色。绝大多数可视光谱都可表示为红、绿、蓝 (RGB) 三色光在不同比例和强度上的混合。这些颜色若发生重叠,则产生黄、青和紫。
任何基于RGB颜色模型的加色色彩空间都属于RGB色彩空间。RGB色彩空间由红绿蓝三原色的色度定义,借此可以定义出相应的色三角(英语:Color triangle),生成其它颜色。完整的RGB色彩空间定义还需要给出白点的色度和伽玛校正曲线。目前最常见的RGB色彩空间是sRGB色彩空间。
在CIE1931色彩空间的色度图上比较不同RGB色彩空间的色域
2. 分类
RGB 格式目前主要有两类:
- 像素格式
这是我们比较常用的格式,R,G,B 分别分开,用N个位来表示。例如 RGB24格式 中 R 占 8位,G 占 8位,B 占8 位,所以一个像素占 24位。这种格式可以混合生成 256 * 256 * 256 = 16,777,216
种颜色,但缺点是占用空间大。
- 索引格式
RGB 的值是一个索引,不是真正的颜色值,例如 RGB 的值 占 1位,那只有两个值 0 跟 1,通常用于黑白颜色,这种情况下 一个像素只占 1位,大大节省了空间。0 跟 1 到底是什么颜色,是通过 索引表(也叫调色板)来定位的,不一定是 黑白,也可以是其他的颜色。所以叫索引格式。只占 1 位的 RGB 称为 RGB1,还有 RGB4 占 4 位,索引表有 16 种颜色, RGB8 占 8 位,索引表有 256 种颜色。
不需要 索引表/调色板 的 RGB 模式 称为 真彩色。
二、RGB的格式
RGB三种颜色在进行编码的时候,根据位数有RDB16、RGB24和RGB32三种。
1. RGB16 格式
RGB16就是每个像素点占16位,也就是R、G和B三种颜色一共占16位,那这三者各多少位呢?有两种:RGB565和RGB555。
1.1 RGB565
RGB565的每个像素用 16 bits 表示,占 2 个字节,R,G,B 分量分别使用 5 位、6 位、5 位。
从上面排列格式,我们使用C语言得到 RGB565 各分量的值:
1 |
|
1.2 RGB555
RGB555每个像素用 16 bits 表示,占 2 个字节,R,G,B 分量都使用 5 位(最高位不用)。
从上面排列格式,我们使用C语言得到 RGB555 各分量的值:
1 |
|
2. RGB24 格式
RGB24格式也可以叫RGB888,每个像素用 24 bits 表示,占 3 个字节,R,G,B 分量都使用 8 位。
从上面排列格式,我们使用C语言得到 RGB888 各分量的值:
1 |
|
注意:在内存中RGB各分量的排列顺序为:BGR BGR BGR ……,主要还是看大小端。
3. RGB32 格式
3.1 一般格式
一般来说,RGB32格式每个像素用 32 比特位表示,占 4 个字节,R,G,B,X 分量都使用 8 位(X表示不使用)。
从上面排列格式,我们使用C语言得到 RGB32 各分量的值:
1 |
|
注意:在内存中RGB各分量的排列顺序为可能是BGRX BGRX BGRX ……这样,具体可能是跟大小端有关。
3.2 ARGB32
很多时候我们也会使用ARGB32,它与RGB32的区别在于保留的 8 个 bit 用来表示透明度,也就是 alpha 的值。需要注意的是,虽然名字是ARGB,但是实际A分量是使用的低8位,也就是说ARGB格式在内存中是RGBA RGBA … 这样排列的(但也可能反过来,主要是大小端的原因导致)
从上面排列格式,我们使用C语言得到 ARGB32 各分量的值:
1 |
|
三、ARGB格式
上边我们学习RGB格式的时候了解到了ARGB32这种格式,其实我们经常还会看到ARGB4444、ARGB1555、ARGB8888等,这些又是什么格式?我们也来了解一下吧。
1. 简介
一种色彩模式,也就是RGB(Alpha,Red,Green,Blue)色彩模式附加上Alpha(透明度)通道,常见于32位位图的存储结构。如,8位(#1e000000)ARGB 头两位是透明度,00是完全透明,ff是完全不透明,后6位是RGB值,比较适中的透明度值。
2. ARGB1555
每个像素用16比特位表示,占2个字节,透明通道用1位来表示,RGB分量都使用5位:
3. ARGB4444
每个像素用16比特位表示,占2个字节,透明通道用4位来表示,RGB分量都使用4位:
3. ARGB8888
每个像素用32比特位表示,占4个字节,Alpha和RGB分量都使用8位:
四、RGB颜色格式转换
我们使用的LCD屏幕可能使用的是RGB565这样的数据格式,而我们一般给颜色值都是给一个RGB888格式的,所以很多时候我们还需要对颜色格式进行转换。
1. RGB888转RGB565
1.1 转换思路
我们将RGB888转换为RGB565的主要思路就是:
- R:将RGB888的(R)高5位(R7 R6 R5 R4 R3)与RGB565(r7 r6 r5 r4 r3)相对应,即R值&0x1F(取高5位),然后左移11位→(R & 0x1F)<<11;
- G:将RGB888的(G)高6位(G7 G6 G5 G4 G3 G2)与RGB565(g7 g6 g5 g4 g3 g2)相对应,即G值&0x3F(取高6位),然后左移5位→ (G & 0x3F)<<5;
- B:将RGB888的(B)高5位(B7 B6 B5 B4 B3)与RGB565(b7 b6 b5 b4 b3)相对应,即B值&0x1F(取高5位)→(B & 0x1F) << 0;
1.2 宏实现
我们可以定义一个宏,也可以在函数内实现,这里写一下宏定义的方式:
1 |
1.3函数实现
1 |
|