视频基础-YUV,RGBA

96
DramaScript
2017.12.25 17:13* 字数 2866
矩阵

在先讲颜色编码之前,先回顾一下高数中的矩阵的基本知识《线性代数》:

  • 什么是矩阵

矩阵是指纵横排列的二维数据表格,比如以下表示方式:


图1.jpg
  • 矩阵的加法和减法

相同数字的位置相加或相减


图2.png
  • 矩阵乘法

第一个矩阵第一行的每个数字(2和1),各自乘以第二个矩阵第一列对应位置的数字(1和1),然后将乘积相加( 2 x 1 + 1 x 1),得到结果矩阵左上角的那个值3。


图3png.png

也就是说,结果矩阵第m行与第n列交叉位置的那个值,等于第一个矩阵第m行与第二个矩阵第n列,对应位置的每个值的乘积之和。

  • 矩阵乘法怎么来的?

矩阵的本质就是线性方程式,两者是一一对应关系。如果从线性方程式的角度,理解矩阵乘法就毫无难度。
有三组未知数 x、y 和 t,其中 x 和 y 的关系如下:


图4.png

x 和 t 的关系如下:


图5.png

有了这两组方程式,就可以求 y 和 t 的关系。从矩阵来看,很显然,只要把第二个矩阵代入第一个矩阵即可:
图6.png

从方程式来看,也可以把第二个方程组代入第一个方程组:
图7.png

上面的方程组可以整理成下面的形式:


图8.png

最后那个矩阵等式,与前面的矩阵等式一对照,就会得到下面的关系:
图9.png

矩阵乘法的计算规则,从而得到证明。

希望看完这点,能够唤起大学你高数的那么一点点的回忆。

RGBA
  • RGBA是什么

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。其中A代表alpha通道一般用作不透明度参数。如果一个像素的alpha通道数值为0%,那它就是完全透明的(也就是看不见的),而数值为100%则意味着一个完全不透明的像素(传统的数字图像)。在0%和100%之间的值则使得像素可以透过背景显示出来,就像透过玻璃(半透明性),这种效果是简单的二元透明性(透明或不透明)做不到的。它使数码合成变得容易。alpha通道值可以用百分比、整数或者像RGB参数那样用0到1的实数表示alpha通道一般用作不透明度参数。如果一个像素的alpha通道数值为0%,那它就是完全透明的(也就是看不见的),而数值为100%则意味着一个完全不透明的像素(传统的数字图像)。在0%和100%之间的值则使得像素可以透过背景显示出来,就像透过玻璃(半透明性),这种效果是简单的二元透明性(透明或不透明)做不到的。它使数码合成变得容易。alpha通道值可以用百分比、整数或者像RGB参数那样用0到1的实数表示。

  • 要点

RGB555 用16位存储,三个分量都用5位表示,剩下一位不用。
RGB565用16位存储,R和B5位,G6位。
RGB24用24位存储,每种分配8位。其中分量的排列顺序为BGRBGRBGR...。
RGB32用32为存储,每种8位,并新增8位用于表示alpha通道或者不使用。分量存储顺序为BGRA,BGRA,BGRA...
与ARGB的区别:
ARGB是一种色彩模式,而RGBA是代表Red(红色) Green(绿色) Blue(蓝色)和 Alpha的色彩空间。

YUV
  • YUV是什么

YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。

  • YUV的由来

与我们熟知的RGB类似,YUV也是一种颜色编码方法,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。

  • YUV存储格式
    YUV 4:4:4采样,每一个Y对应一组UV分量8+8+8 = 24bits,3个字节。

下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
存放的码流为: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3
内存大小:表示色度值(UV)没有减少采样。即Y,U,V各占一个字节,加上Alpha通道一个字节,总共占4字节.这个格式其实就是24bpp的RGB格式了

YUV 4:2:2采样,每两个Y共用一组UV分量,一个YUV占8+4+4 = 16bits 2个字节。

下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
存放的码流为: Y0 U0 Y1 V1 Y2 U2 Y3 V3
映射出像素点为:[Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3]
内存大小:w * h * 2

YUV 4:2:0采样,每四个Y共用一组UV分量一个YUV占8+2+2 = 12bits 1.5个字节。

下面八个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
[Y5 U5 V5] [Y6 U6 V6] [Y7U7 V7] [Y8 U8 V8]
存放的码流为:Y0 U0 Y1 Y2 U2 Y3
Y5 V5 Y6 Y7 V7 Y8
映射出的像素点为:[Y0 U0 V5] [Y1 U0 V5] [Y2 U2 V7] [Y3 U2 V7]
[Y5 U0 V5] [Y6 U0 V5] [Y7U2 V7] [Y8 U2 V7]
内存则是:yyyyyyyyuuvv
需要占用的内存:w * h * 3 / 2

YUV 4:1:1采样:是在水平方向上对色度进行4:1抽样。对于低端用户和消费类产品这仍然是可以接受的。对非压缩的8比特量化的视频来说,每个由4个水平方向相邻的像素组成的宏像素需要占用6字节内存

下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
存放的码流为: Y0 U0 Y1 Y2 V2 Y3
映射出像素点为:[Y0 U0 V2] [Y1 U0 V2] [Y2 U0 V2] [Y3 U0 V2]
内存大小:可以参考4:2:2分量,是进一步压缩,每隔四个点才采一次U和V分量。一般是第1点采Y,U,第2点采Y,第3点采YV,第4点采Y,依次类推。

除了4:4:4采样,其余采样后信号重新还原显示后,会丢失部分UV数据,只能用相临的数据补齐,但人眼对UV不敏感,因此总体感觉损失不大。

YUV转RGB的方法:
这里的转换就需要用到前面说的矩阵的加法了,公式如下:


rgb.jpg

UV(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
反过来,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)
代码的话,有一个C代码库(libyuv),这个库完整的实现了所有转换。
libyuv for android

  • YUV的分类

YUV格式有两大类:planar和packed。
planar:YUV的存储中与RGB格式最大不同在于,RGB格式每个点的数据是连继保存在一起的。即R,G,B是前后不间隔的保存在2-4byte空间中。而YUV的数据中为了节约空间,U,V分量空间会减小。每一个点的Y分量独立保存,但连续几个点的U,V分量是保存在一起的.这几个点合起来称为macro-pixel, 这种存储格式称为Packed(打包)格式。对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。

packed:对于packed的YUV格式,每个像素点的Y,U,V是连续交*存储的

YUV420p:又叫planer平面模式,Y ,U,V分别再不同平面,也就是有三个平面。

I420:又叫YU12,安卓的模式。存储顺序是先存Y,再存U,最后存V。YYYYUUUVVV
YV12:存储顺序是先存Y,再存V,最后存U。YYYVVVUUU

YUV420sp:又叫bi-planer或two-planer双平面,Y一个平面,UV在同一个平面交叉存储

NV12:IOS只有这一种模式。存储顺序是先存Y,再UV交替存储。YYYYUVUVUV
NV21:安卓的模式。存储顺序是先存Y,再存U,再VU交替存储。YYYYVUVUVU

YCbCr :

YCbCr 则是在世界数字组织视频标准研制过程中作为ITU - R BT.601 建议的一部分,其实是YUV经过缩放和偏移的翻版。其中Y与YUV 中的Y含义一致,Cb,Cr 同样都指色彩,只是在表示方法上不同而已。在YUV 家族中,YCbCr 是在计算机系统中应用最多的成员,其应用领域很广泛,YCbCr 有许多取样格式,如4∶4∶4,4∶2∶2,4∶1∶1 和4∶2∶0。
可以参考如下表格:


yuv.png

最后我们经常看到的Android或者IOS摄像头采集到的NV12或者NV21数据,其实本质上是YUV,只不过是由Intel创造的格式,与RGB转换是类似的。

总结:因为颜色可以通过不同方式来拆解,所以出现了不同的颜色编码方式。RGB通过R,G,B三个分量来分解,YUV通过Y和UV三个分量来分解。RGB来自于颜色发光原理,而YUV主要用于优化颜色视频信号的传输,优点在于占用宽带少以及更符合人类视觉系统观感

视频开发