您的位置:首页 > 其它

YUV数据格式解疑

2015-06-26 13:06 337 查看
 一般我们在YUV格式上进行画面的数据进行分析,比如一些视频分析算法。对此,为了对以后该方面的算法做一些知识储备,先总结对自己了解到的相关YUV知识进行总结,认识。

 同样,首先贴出该篇文章的参考连接,如果大家有需要更深入了解的,可以点击进这里的链接:

图文详解YUV420数据格式

YUV(二)-YUV格式转换缩放

YUV格式说明

YUV采样格式与存储格式

 好了,话不多说,接下来YUV的总结。

初识YUV

 首先了解下什么是yuv。

 yuv是一种颜色编码方法,即对摄像头采集到的颜色数据进行编码。

 其中Y代表亮度(灰度值),UV代表色度与浓度(影像色彩饱和度)。

YUV与RGB

 YUV与RGB一样,都可以用于图像的存储,传输(由于这两种格式的数据量对于传输来说还是太大,所以一般不这么做),但YUV比RGB的优势是在哪里呢?

 在于用YUV方式传送占用极少的频宽,因为 一般来说,直接采集到的视频数据是RGB24的格式,RGB24一帧的大小size=width×heigth×3 byte,RGB32的size=width×heigth×4,如果是I420(即YUV的一种标准格式4:2:0)的数据量是 size=width×heigth×1.5 byte。

 由此看出YUV方式传输时能减少大量的数据量传递,但上面又说YUV一般不作为图像传输格式,那这个YUV除了能数据量小点外是不是就跟RGB一样了呢?其实在真正主要使用在YUV格式一般使用在图像处理方面。

YUV的存储格式

 YUV的存储格式分为紧缩格式(packed)平面模式(planar)

紧缩模式(packed):将Y、U、V值储存成Macro Pixels阵列,和RGB的存放方式类似,每个像素点的Y,U,V是连续交错存储的。

平面模式(planar):将Y、U、V的三个分量分别存放在不同的矩阵中,即先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。

YUV的采样方式与存储方式

 说完了yuv的存储格式,接下来对于我们理解yuv的几种不同的采样方式就容易得多了,以下分别简述yuv的三种通用的采样方式:

 同时不管是否理解,应该先知道的是以下几句话,相信带着这几句话去阅读以下的几种采样方式能更方便掌握。

1、YUV 4:4:4采样,每一个Y对应一组UV分量。

2、YUV 4:2:2采样,每两个Y共用一组UV分量。

3、YUV 4:2:0采样,每四个Y共用一组UV分量。

YUV4:4:4

采样方式

 yuv444方式采样即每采样一个Y分量就采样一个UV分量,如下两张图所示,该两张图描述同一个意思,即一个Y对应一组UV。





存储方式

 内存中为:YYYYYYYY UUUUUUUU VVVVVVVV

YUV4:2:2

采样方式

 yuv422是每两个y对应一组uv值。同样这里也引用两张图片进行直观的说明:





存储方式

 同时yuv422又可以分为YUYV,UYVY,YUV422P三种存储模式。下面就来简要地说明这三种模式的区别。

 这里需要说明的是其始终遵循2个y对应一组uv,变的只是在一个单元中这三个分量元素的排列顺序。

YUYV(属于yuv422,紧缩模式):

 与其命名表现出来的意思一样,yuyv的排列方式即为y,u,y,v。下面用一张图来更直观地说明该模式中yuv的排列方式。



 这里的Cb可以认为是u,这里的Cr可以认为是v。所以从图中可以看出YUYV的排列方式为y,u,y,v,对于像素点Y’00、Y’01 而言,其Cb、Cr的值均为 Cb00、Cr00,其他的像素点的YUV取值依次类推。

UYUV(属于yuv422,紧缩模式):

 同样是字面意思的u,y,v,y的排列方式,与yuyv的不同仅仅在于排列方式。下面出图:



 同样,这里的Cb为u,Cr为v。图中的排列方式为u,y,v,y,对于像素点同样是Y’00、Y’01对应Cb00、Cr00,即遵循两个Y一组uv。

YUV422P(属于yuv422,平面模式):

 与前面两种方式不同,并不仅仅是一个元素的y与u,y与v的先后问题。yuv422P的存储格式为平面模式,即不是前面两种的yuv在同一个矩阵且互相交错,而是先存完Y分量,再存U分量,最后存V分量。同样一张图看清其排列:



 虽然存储模式不一样,但既然属于yuv422,那么其yuv的对应关系是不会改变的,所以同样的对于像素点Y’00、Y’01 而言,其Cb、Cr的值均为 Cb00、Cr00。

 该平面模式中所有 Y 样例都会作为不带正负号的char值组成的数组首先显示在内存中。此数组后面紧接着所有 U (Cb) 样例。U 平面的跨距为 Y 平面跨距的一半,V 平面包含的行为 Y 平面包含行的一半。U平面后面紧接着所有 V(Cr) 样例,它的跨距和行数与 U 平面相同。

YUV4:2:0

采样方式

 其采样方式为4个y,一组uv,引用如下两张图所示:





存储方式

 yuv420的采样方式是比较常见和常用的,yuv420中也分不同的存储方式,如YV12,I420,NV12,NV21。其中YV12与I420都可以称为yuv420P,两者是同样的平面模式,只是u和v的顺序不同;而NV12与NV21也都可以称为yuv420SP,共同表现的是Y为平面模式,uv为紧缩模式,同样NV12与NV21两者区别为u与v的排列方式。

 再这里再啰嗦一下,yuv420存储格式下虽然分出这些排列模式,但其根本不会变,即4个y对应一组uv。下面开始一 一介绍。

YV12(属于yuv420,yuv420P,平面模式):

 YV12的yuv排列方式为,先排列完y分量,再排列v分量,最后排列u分量,直观展现如下图所示。图中,Y’00、Y’01、Y’10、Y’11共用Cr00、Cb00(需要注意清楚的是哪几个y对应哪几个uv),其他依次类推:



 该平面模式中,在内存中的排列为:

 YYYYYYYY VV UU =>YUV420P。

 具体如下图所示:



I420(属于yuv420,yuv420P,平面模式):

 与YV12基本类似,唯一不同的是Y后面U和V的先后顺序,I420是U紧随其后。

 YYYYYYYY UU VV =>YUV420P

 下面直接上图,就不过多说明了。



NV12(yuv420,yuv420SP,双平面模式):

&esmp;NV12的排列方式有些特殊,他是先将y分量排完,然后剩下的uv分量交错着排列,通常我们会将uv看成一个整体,那么NV12的排列方式就是two-plane模式,即双平面模式。NV12的uv平面中,uv的先后顺序为先u后v。

 下面是其排列顺序的图片:



 对应关系为Y’00、Y’01、Y’10、Y’11共用Cr00、Cb00。

 内存中为:YYYYYYYY UVUV =>YUV420SP (dxva 输出 NV12)

 所有 Y 样例都会作为由不带正负号的char值组成的数组首先显示在内存中,并且行数为偶数。Y 平面后面紧接着一个由不带正负号的char值组成的数组,其中包含了打包的 U (Cb) 和 V (Cr) 样例,如图 所示。



NV21(yuv420,yuv420SP,双平面模式):

 与NV12基本一致,唯一不同的是在排列完y分量后,uv的先后顺序为先v后u。

 内存中为:YYYYYYYY VUVU =>YUV420SP (x264/ffmpeg 输入、输出 I420)

 引用图片如下图所示:



在内存中的yuv420

 引用上面借鉴博客中的一段话就能进行很好的描述。

YUV420 planar数据, 以720×480大小图象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

 为什么内存所占大小是(720×480×3/2)字节,即width * hight * 3 / 2字节呢,原因就在于4个y对应一组uv。

 即Y部分所占大小为width * hight =Y(总和);U部分所占大小为 U = Y / 4 ;V部分所占大小为 V = Y / 4。将这三个量加起来就可以得到yuv420在内存中所占的大小为width * hight * 3 / 2。

yuv420P与yuv420SP区别

 最后为了收个尾,再引用两张图片说明yuv420P与yuv420SP的区别。



yuv的采集,理论上的传输和显示流程

 为什么是理论上的传输呢,因为一般不这么干,yuv还是太大了,一般采取再一次编码压缩(H264,H265等等)。

 OK,下面引用上面博客的一段话以及一张图片进行说明yuv的这一系列流程。

一般来说,直接采集到的视频数据是RGB24的格式,RGB24一帧的大小size=width×heigth×3 byte,RGB32的size=width×heigth×4,如果是I420(即YUV标准格式4:2:0)的数据量是 size=width×heigth×1.5 byte。在采集到RGB24数据后,需要对这个格式的数据进行第一次压缩。即将图像的颜色空间由RGB2YUV。因为,X264在进行编码的时候需要标准的YUV(4:2:0)。

经过第一次数据压缩后RGB24->YUV(I420)。这样,数据量将减少一半。同样,如果是RGB24->YUV(YV12),也是减少一半。但是,虽然都是一半,如果是YV12的话效果就有很大损失。然后,经过X264编码后,数据量将大大减少。将编码后的数据打包,通过RTP实时传送。到达目的地后,将数据取出,进行解码。完成解码后,数据仍然是YUV格式的,所以,还需要一次转换,这样windows的驱动才可以处理,就是YUV2RGB24。

关于yuv的代码计算

yuv420与yuv422的转换

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

yuv420sp旋转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;
}
}
}


缩放扩大方法

 yuv缩放一般是进行倍数的缩放和扩大,这样才能尽可能地保持原有图像内容。

 对于缩放,则可以通过隔点采样的方式进行,即隔一个倍数点,采一个;对于扩大可以复制的方式进行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: