图文详解 YUV420 数据格式

YUV 格式有两大类:planar 和 packed。
  • 对于 planar 的 YUV 格式,先连续存储全部像素点的 Y,紧接着存储全部像素点的 U,随后是全部像素点的 V。
  • 对于 packed 的 YUV 格式,每一个像素点的 Y, U, V 是连续交*存储的。

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

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

YUV 码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0,关于其详细原理,能够经过网上其它文章了解,这里我想强调的是 如何根据其采样格式来从码流中还原每一个像素点的 YUV 值,由于只有正确地还原了每一个像素点的 YUV 值,才能经过 YUV 与 RGB 的转换公式提取出每一个像素点的 RGB 值,而后显示出来。

用三个图来直观地表示采集的方式吧,以黑点表示采样该像素点的 Y 份量,以空心圆圈表示采用该像素点的 UV 份量算法

先记住下面这段话,之后提取每一个像素的 YUV 份量会用到。
windows

  • YUV 4:4:4 采样,每个 Y 对应一组 UV 份量。
  • YUV 4:2:2 采样,每两个 Y 共用一组 UV 份量。 
  • YUV 4:2:0 采样,每四个 Y 共用一组 UV 份量。

存储方式

下面我用图的形式给出常见的 YUV 码流的存储方式,并在存储方式后面附有取样每一个像素点的 YUV 数据的方法,其中,Cb、Cr 的含义等同于 U、V。

(1) YUVY 格式 (属于 YUV422)

YUYV 为 YUV422 采样的存储格式中的一种,相邻的两个 Y 共用其相邻的两个 Cb、Cr,分析,对于像素点 Y'00、Y'01 而言,其 Cb、Cr 的值均为 Cb00、Cr00,其余的像素点的 YUV 取值依次类推。  编码

(2) UYVY 格式 (属于 YUV422)

UYVY 格式也是 YUV422 采样的存储格式中的一种,只不过与 YUYV 不一样的是 UV 的排列顺序不同而已,还原其每一个像素点的 YUV 值的方法与上面同样。 spa

3) YUV422P(属于 YUV422)

YUV422P 也属于 YUV422 的一种,它是一种 Plane 模式,即平面模式,并非将 YUV 数据交错存储,而是先存放全部的 Y 份量,而后存储全部的 U(Cb)份量,最后存储全部的 V(Cr)份量,如上图所示。其每个像素点的YUV 值提取方法也是遵循 YUV422 格式的最基本提取方法,即两个 Y 共用一个 UV。好比,对于像素点Y'00、Y'01 而言,其 Cb、Cr 的值均为 Cb00、Cr00。 设计

(4)YV12,YU12 格式(属于 YUV420)

YU12 和 YV12 属于 YUV420 格式,也是一种 Plane 模式,将 Y、U、V 份量分别打包,依次存储。其每个像素点的 YUV 数据提取遵循 YUV420 格式的提取方式,即 4 个 Y 份量共用一组 UV。注意,上图中,Y'00、Y'0一、Y'十、Y'11 共用 Cr00、Cb00,其余依次类推。

code

(5)NV十二、NV21(属于 YUV420)

NV12 和 NV21 属于 YUV420 格式,是一种 two-planar 模式,即 Y 和 UV 分为两个 Plane,可是 UV(CbCr)为交错存储,而不是分为三个 plane。其提取方式与上一种相似,即 Y'00、Y'0一、Y'十、Y'11 共用 Cr00、Cb00

YUV420 planar 数据, 以 720×488 大小图象 YUV420 planar 为例, 视频

  • 其存储格式是: 共大小为(720×480×3>>1) 字节,
  • 分为三个部分: Y, U 和 V
  • Y 份量:    (720×480) 个字节  
  • U(Cb) 份量:(720×480>>2) 个字节
  • V(Cr) 份量:(720×480>>2) 个字节

三个部份内部均是行优先存储,三个部分之间是 Y, U, V 顺序存储。 内存

  • 即YUV数据的0--720×480字节是Y份量值,  
  • 720×480--720×480×5/4字节是U份量    
  • 720×480×5/4 --720×480×3/2字节是V份量。

4 :2:2 和4:2:0 转换:

最简单的方式:

YUV4:2:2 ---> YUV4:2:0  Y 不变,将 U 和 V 信号值在行(垂直方向)在进行一次隔行抽样。 YUV4:2:0 ---> YUV4:2:2  Y 不变,将 U 和 V 信号值的每一行分别拷贝一份造成连续两行数据。

在 YUV420 中,一个像素点对应一个 Y,一个 4X4 的小方块对应一个 U 和 V。对于全部 YUV420 图像,它们的 Y 值排列是彻底相同的,由于只有 Y 的图像就是灰度图像。YUV420sp 与 YUV420p 的数据格式它们的 UV 排列在原理上是彻底不一样的。420p 它是先把 U 存放完后,再存放 V,也就是说 UV 它们是连续的。而 420sp 它是 UV、UV这样交替存放的。(见下图) 有了上面的理论,我就能够准确的计算出一个 YUV420 在内存中存放的大小: it

 width * hight = Y(总和) U = Y / 4   V = Y / 4

因此 YUV420 数据在内存中的长度是 width * hight * 3 / 2,

假设一个分辨率为 8X4 的 YUV 图像,它们的格式以下图:

YUV420sp 格式以下图           
       class

 YUV420p 数据格式以下图

旋转 90 度的算法:


public static void rotateYUV240SP(byte[] src, byte[] des, int width, int height)
{
    
  int wh = width * height;
  //旋转Y
  int k = 0;
  for(int i = 0; i < width; i++) {
   for(int j = 0; j < height; j++) 
   {
      des[k] = src[width*j + i];   
      k++;
   }
  }
  
  for(int i = 0; i < width; i+ = 2) {
   for(int j = 0; j < height/2; j++) 
   { 
      des[k] = src[wh+ width*j + i]; 
      des[k+1]=src[wh + width*j + i+1];
      k+ = 2;
   }
  }
  
 }




YV12和I420的区别        

通常来讲,直接采集到的视频数据是 RGB24 的格式,RGB24 一帧的大小 size=width×heigth×3 Bit,RGB32 的 size=width×heigth×4,若是是 I420(即 YUV 标准格式 4:2:0)的数据量是 size=width×heigth×1.5 Bit。       

在采集到 RGB24 数据后,须要对这个格式的数据进行第一次压缩。即将图像的颜色空间由 RGB2YUV。由于,X264在进行编码的时候须要标准的 YUV(4:2:0)。可是这里须要注意的是,虽然 YV12 也是(4:2:0),可是 YV12 和 I420 的倒是不一样的,在存储空间上面有些区别。以下: 

YV12 : 亮度(行×列) + U(行×列/4) + V(行×列/4)
I420 : 亮度(行×列) + V(行×列/4) + U(行×列/4)

能够看出,YV12 和 I420 基本上是同样的,就是 UV 的顺序不一样。

继续咱们的话题,通过第一次数据压缩后 RGB24->YUV(I420)。这样,数据量将减小一半,为何呢?呵呵,这个就太基础了,我就很少写了。一样,若是是 RGB24->YUV(YV12),也是减小一半。可是,虽然都是一半,若是是 YV12 的话效果就有很大损失。而后,通过 X264 编码后,数据量将大大减小。将编码后的数据打包,经过 RTP 实时传送。到达目的地后,将数据取出,进行解码。完成解码后,数据仍然是 YUV 格式的,因此,还须要一次转换,这样 windows 的驱动才能够处理,就是 YUV2RGB24。

YUY2  是 4:2:2  [Y0 U0 Y1 V0]

yuv420p 和 YUV420的区别 

在存储格式上有区别

yuv420p: yyyyyyyy uuuuuuuu vvvvv 

yuv420: yuv yuv yuv

YUV420P,Y,U,V 三个份量都是平面格式,分为 I420 和 YV12。I420 格式和 YV12 格式的不一样处在 U 平面和V 平面的位置不一样。在 I420 格式中,U 平面紧跟在 Y 平面以后,而后才是 V 平面(即:YUV);但 YV12 则是相反(即:YVU)。
YUV420SP, Y 份量平面格式,UV 打包格式, 即 NV12。 NV12 与 NV21 相似,U 和 V 交错排列,不一样在于 UV 顺序。

I420: YYYYYYYY UU VV    =>YUV420P
YV12: YYYYYYYY VV UU    =>YUV420P
NV12: YYYYYYYY UVUV     =>YUV420SP
NV21: YYYYYYYY VUVU     =>YUV420SP

相关文章
相关标签/搜索