前言:近期有接触到YUV和RGB两种颜色编码格式,稍稍做了个了解,整理了网上的一些资料然后整理了一下,方便自己以后查阅,有描述不正确的地方麻烦大家多多指正。
通俗点来理解的话,YUV与RGB都是一种颜色编码方法。当我们采集到图像数据后,一般输出的就是YUV格式的数据流,然后再去进行压缩编码等其他步骤来进行数据传输或保存。而最终显示在我们屏幕面前,通常又是以RGB格式来展现的。
YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。YUV格式的出现正是为了解决历史上彩色与黑白电视过渡期而产生的,若将Y和UV分量分离开来只留下Y分量同样可以显示一幅完整的图像,只是没了色彩变成黑白了而已。
从网上找到张图,直观的展现出不同YUV格式的采集方式,其中黑点表示该像素点的Y分量, 空心圆圈为该像素点的UV分量。
从上图可以看出不同格式的YUV采样分别有以下规律:
YUV格式总体分为两大类:一个是planar,另一个是packed。
(1)YUV422存储方式
存储格式:内存布局=>所属存储类型=>planes
YUY2: Y0U0Y1V0Y2U1Y3V1 =>YUV422SP =>1 planes
UYVY: U0Y0V0Y1U1Y2V1Y3 =>YUV422SP =>1 planes
YVYU: Y0V0Y1U0Y2V1Y3U1 =>YUV422SP =>1 planes
(2)YUV420存储方式
存储格式:内存布局=>所属存储类型=>planes
IYUV: YYYYYYYY UU VV =>YUV420P =>3 planes
YV12: YYYYYYYY VV UU =>YUV420P =>3 planes
NV12: YYYYYYYY UVUV =>YUV420P =>2 planes
NV21: YYYYYYYY VUVU =>YUV420P =>2 planes
(1)映射像素点
在了解YUV不同格式之间的转换关系前,需要了解一下转换的原理;一个像素点对于YUV结构来说需要完整的Y、U和V分量构成。而对于YUV422和YUV420而言,并不是每个像素点都像YUV444一样拥有完整的三个分量,那么这个时候就需要进行相邻像素点之间U、V分量的互补。这时候需要就了解到映射像素点这个概念。直接解释这个概念可能不太好理解,来看个例子可能就很容易明白了:
例1:如缺失U、V变量的YUV422来说,构成完整的YUV需要响铃的两个像素相互作用,如下图:
可以看出第一个像素点共用下一个像素掉的v,第二个像素点则会共用前一个像素掉的u;
例2:如缺失U、V变量的YUV422来说, 相邻两行每两个像素之间来互相共用u、v,如下图:
从上图可以看出YUV422中,一行的两个像素点和相邻下一行的相同位置的两个像素点之间u、v共用,缺啥补啥。
(2)、YUV4:2:2-->YUV4:2:0
保持Y分量不变,将U和V值在行(垂直方向)再进行一次隔行抽样。
(3)、YUV4:2:0-->YUV4:2:2
保持Y不变,将U和V值得每一行分别拷贝一份形成两行数据。
RGB,其实就是R(red:红色)+G(green:绿色)+B(blue:蓝色);像彩色电视或者计算机显示屏都是通过这三种颜色按照不同比例混合叠加而构成图像而显示的。红色、绿色和蓝色又称为三基色。之所以称为‘基色’是因为这三种颜色按照不同比例混合后几乎可以变成人类示例所能感知的所有颜色。
RGB格式若按照编码存储方式可以分为RGB555、RGB565、RGB24(RGB888)和RGB32。格式不同是因为在构成一个像素的不同颜色所占的位数以及位数比例不同。具体不同可以参照下面的RGB存储格式;
1)RGB555(高彩色)
RGB555是一种16位的RGB格式,R、G、B分量都用5位来表示,剩下的一位不用,存储格式如下图:
假设计算机中存储某一个像素点的变量为color, 数据类型为short.,那么则有:
R = color & 0x7C00, (获取高字节的5个bit)
G = color & 0x03E0, (获取中间5个bit)
B = color & 0x001F, (获取低字节5个bit)
2)RGB565(高彩色)
RGB565同样是一种16位的RGB格式,R和B分量用5位来表示,G分量用6位标志。存储格式如下图:
假设计算机中存储某一个像素点的变量为color, 数据类型为short, 那么则有:
R = color & 0xF800, (获取高字节的5个bit)
G = color & 0x07E0, (获取中间6个bit)
B = color & 0x001F, (获取低字节5个bit)
3)RGB24(真彩色)
RGB24是一种24位的RGB格式,R、G、B分量都用8位来表示,每位取值范围都为0-255。存储格式如下图:
假设计算机中存储某一个像素点的变量为color, 数据类型为int, 那么则有:
R = color & 0x000000FF,
G = color & 0x0000FF00,
B = color & 0x00FF0000,
4)RGB32(真彩色)
RGB32使用32位来表示一个像素,RGB分量各用去8位,剩下的8位用作Alpha通道或者不用。Alpha通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明、不透明和半透明区域,其中白表示不透明,黑表示透明,灰表示半透明。其结构如下:
假设计算机中存储某一个像素点的变量为color, 数据类型为int,那么则有:
a、低8位保留
R = color & 0x0000FF00
G = color & 0x00FF0000,
B = color & 0xFF000000,
b、低8位为ALPHA值
R = color & 0x0000FF00,
G = color & 0x00FF0000,
B = color & 0xFF000000,
A = color & 0x000000FF,
关于RGB与YUV之间的关联性,并不是特别了解,但是从网上找到了这么一句话感觉很合理:“基本上所有图像算法都是基于yuv的;而所有显示面板都是接收rgb数据”,侧面的理解是在进行颜色数据运算时使用的是YUV颜色编码,而对图像经过后期处理进行显示时则用的是RGB编码。暂时记录这么多,后续了解更清楚再进行补充。
关于RGB与YUV之间的转换,有如下一条公式:
1)、YUV(256 级别) 可以从8位 RGB 直接计算:
Y = 0.299 R + 0.587 G + 0.114 B
U = - 0.1687 R - 0.3313 G + 0.5 B + 128
V = 0.5 R - 0.4187 G - 0.0813 B + 128
2)、反过来,RGB 也可以直接从YUV (256级别) 计算:
R = Y + 1.402 (Cr-128)
G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
B = Y + 1.772 (Cb-128)
参考资料:
图文详解YUV420数据格式:http://www.cnblogs.com/Sharley/p/5595768.html
RGB像素格式:https://baijiahao.baidu.com/s?id=1589371935820142680&wfr=spider&for=pc
https://blog.csdn.net/aiwangtingyun/article/details/79077536