首页 > 其他 > 详细

图文详解 YUV420 数据格式

时间:2015-10-03 06:18:00      阅读:226      评论:0      收藏:0      [点我收藏+]
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 分量会用到。

  • 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 值的方法与上面一样。

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‘01、Y‘10、Y‘11 共用 Cr00、Cb00,其他依次类推。

(5)NV12、NV21(属于 YUV420)

NV12 和 NV21 属于 YUV420 格式,是一种 two-planar 模式,即 Y 和 UV 分为两个 Plane,但是 UV(CbCr)为交错存储,而不是分为三个 plane。其提取方式与上一种类似,即 Y‘00、Y‘01、Y‘10、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 在内存中存放的大小:

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

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

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

YUV420sp 格式如下图           
技术分享      

 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

图文详解 YUV420 数据格式

原文:http://my.oschina.net/jerikc/blog/513273

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!