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分量会用到。

  1. YUV 4:4:4采样,每一个Y对应一组UV分量。
  2. YUV 4:2:2采样,每两个Y共用一组UV分量。
  3. YUV 4:2:0采样,每四个Y共用一组UV分量。

2.  存储方式

下面我用图的形式给出常见的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)
(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-plane模式,即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

互动百科提供:

(1)    YUV 4:4:4

YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用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

  (2)   YUV 4:2:2

每个色差信道的抽样率是亮度信道的一半,所以水平方向的色度抽样率只是4:4:4的一半。对非压缩的8比特量化的图像来说,每个由两个水平方向相邻的像素组成的宏像素需要占用4字节内存。

  下面的四个像素为: [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]

  (3)   YUV 4:1:1

  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)YUV4:2:0

  4:2:0并不意味着只有Y,Cb而没有Cr分量。它指得是对每行扫描线来说,只有一种色度分量以2:1的抽样率存储。相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0...以此类推。对每个色度分量来说,水平方向和竖直方向的抽样率都是2:1,所以可以说色度的抽样率是4:1。对非压缩的8比特量化的视频来说,每个由2x2个2行2列相邻的像素组成的宏像素需要占用6字节内存。

  下面八个像素为:[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]

yuv420图文详解的更多相关文章

  1. CentOS 6.3下Samba服务器的安装与配置方法(图文详解)

    这篇文章主要介绍了CentOS 6.3下Samba服务器的安装与配置方法(图文详解),需要的朋友可以参考下   一.简介  Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件, ...

  2. Cocos2d-x win7 + vs2010 配置图文详解

    Cocos2d-x win7 + vs2010 配置图文详解 下载最新版的cocos2d-x.打开浏览器,输入cocos2d-x.org,然后选择Download,本教程写作时最新版本为cocos2d ...

  3. zookeeper的安装(图文详解。。。来点击哦!)

    zookeeper的安装(图文详解...来点击哦!) 一.服务器的配置 三台服务器: 192.168.83.133   sunshine 192.168.83.134   sunshineMin 19 ...

  4. Hadoop集群搭建安装过程(三)(图文详解---尽情点击!!!)

    Hadoop集群搭建安装过程(三)(图文详解---尽情点击!!!) 一.JDK的安装 安装位置都在同一位置(/usr/tools/jdk1.8.0_73) jdk的安装在克隆三台机器的时候可以提前安装 ...

  5. Hadoop集群搭建安装过程(二)(图文详解---尽情点击!!!)

    Hadoop集群搭建安装过程(二)(配置SSH免密登录)(图文详解---尽情点击!!!) 一.配置ssh无密码访问 ®生成公钥密钥对 1.在每个节点上分别执行: ssh-keygen -t rsa(一 ...

  6. Linux虚拟机安装(CentOS 6.5,图文详解,需要自查)

    Linux虚拟机的安装(图文详解) 下篇会接续Hadoop集群安装(以此为基础) 一.安装准备 VMWorkstation.linux系统镜像(以下以CentOS6.5为例) 二.安装过程详解 关闭防 ...

  7. 分享我开发的网络电话Android手机APP正式版,图文详解及下载

    分享我开发的网络电话Android手机APP正式版,图文详解及下载 分享我开发的网络电话Android手机APP正式版 实时语音通讯,可广域网实时通讯,音质清晰流畅! 安装之后的运行效果: 第一次安装 ...

  8. 图文详解Unity3D中Material的Tiling和Offset是怎么回事

    图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...

  9. HTML标签----图文详解(二)

    HTML标签超详细的图文演示再来一波~~~ 如果还没有看过昨天的福利的,那可要抓紧喽,传送门:HTML标签----图文详解 本文主要内容 列表标签 表格标签 框架标签及内嵌框架<iframe&g ...

随机推荐

  1. notepad++与ISE/Vivado关联

    转自:http://www.cnblogs.com/ninghechuan/p/6172237.html 1.notepad++与vivado关联 打开vivado软件,选择菜单栏“Tools——&g ...

  2. Scala之集合Collection

    概述 Scala的集合类能够从三个维度进行切分: 可变与不可变集合(Immutable and mutable collections) 静态与延迟载入集合 (Eager and delayed ev ...

  3. quartusii 使用ModelSim do文件实现仿真(Verilog)

    QuartusII从9.1之后的版本都已经取消了内部自带的仿真器,都需要借助第三方仿真软件比如Modelsim才能实现仿真.一般在进行代码编写的时候,如果结合功能仿真,可以很快的验证代码实现的逻辑是否 ...

  4. Effective JavaScript Item 33 让构造函数不再依赖newkeyword

    本系列作为EffectiveJavaScript的读书笔记. 在将function当做构造函数使用时,须要确保该函数是通过newkeyword进行调用的. function User(name, pa ...

  5. IAsyncResult 接口

    IAsyncResult 接口由包含可异步操作的方法的类实现.它是启动异步操作的方法的返回类型,如 FileStream.BeginRead,也是结束异步操作的方法的第三个参数的类型,如 FileSt ...

  6. 常用的Eclipse设置

    每次新建work space的时候,我都要修改一些默认设置,每次都要花一些时间找在哪里设置,总结如下. 启动加速 1. 去掉XML Validataion Windows --> Prefere ...

  7. 三、为什么String在Java中是不可更改的

    String在Java中是个不可更改的类.一个不可更改的类简单来说就是这个类的所有实例是不可以更改的.所有的实例信息在创建的时候被初始化而且信息是不可以更改的.不可更改的类有很多好处.这篇文章总结了为 ...

  8. WPF学习之X名称空间详解

    X名称空间里面的成员(如X:Name,X:Class)都是写给XAML编译器看的.用来引导XAML代码将XAML代码编译为CLR代码. 4.1X名称空间里面到底都有些什么? x名称空间映射的是:htt ...

  9. Eclipse中设置文件编码

    如果你在使用某个editor进行开发的话,文件编码就由改editor解决即可 Eclipse中也有这个功能,帮你设置文件的编码,选择Edit->Set Encoding即可 注意,这个选项针对不 ...

  10. android 使用 sqlite

    SQLiteHelper .class  (升级的时候,做点小技巧) package com.keyue.qlm.util;  import android.content.Context;  imp ...