开发中用途
在比如做移动客户端开发中(iOS,安卓),我们在直播中要将本地视频推流到服务器,如何将本地相机采集的数据表示出来,或者比如我们要对采集到视频做旋转,裁剪,美颜等操作,如何能高效的完成以上动作,我们都不得不好好了解清楚图像的结构,以至于我们能用代码的形式将它表示出来。
What is YUV ?
YUV是一种颜色编码方式,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视兼容的问题。
YUV不像传统RGB那样要求三个独立的视频信号同时传输,因此YUV方式传输视频占用较少带宽。
概念区分
Y’UV, YUV, YCbCr, YPbPr, etc.
这几个词乍一看十分相似.
在过去,YUV 和 Y’UV被用作电视系统中颜色信息的特定模拟信息编码。而YCbCr被用作颜色信息的数字编码,通常适用于视频和静态图像的压缩和传输(MPEG, JPEG)。
今天,YUV通常用被用在计算机行业描述使用YCbCr编码的文件格式。
Y:表示明亮度(Luminance,Luma),也就是灰度值
- U和V:色度(Chrominance,Chroma),描述影像色彩及饱和度。
1. 采集方式(实心圆圈代表Y,空心圆圈代表UV)
- YUV4:4:4 (每一个Y对应一组UV分量)
- YUV4:2:2 (每两个Y共用一组UV分量)
- YUV4:2:0 (每四个Y共用一组UV分量)
2.存储方式
了解了以上三幅图的YUV采集方式后,我们来重点说一下YUV的数据是如何存储的。
在以上三张图中,实心圆圈代表一个Y分量,空心圆圈代表一个UV分量,而因为又分三种不同的采集方式,即1个Y对应一组UV分量,2个Y共用一组UV分量,4个Y共用一组UV分量,
以YUV4:2:0为例,它又被分为YUV420P与YUV420SP,它们都是YUV420格式。
- YUV420P, Plane模式(Y,U,V三个plane)将Y,U,V分量分别打包,依次存储。下图为I420.
- I420 : YYYYYYYY UU VV
- YV12 : YYYYYYYY VV UU
- YUV420SP(NV12/NV21): two-plane模式,即Y和UV分为两个Plane,但是UV(CbCr)为交错存储,而不是分为三个plane. 下图为NV12
- NV12: YYYYYYYY UVUV
- NV21: YYYYYYYY VUVU
根据以上两幅图,我们以分辨率为640480的图片为例,则它的大小为 Y : width(640) height(480) 可认为每个Y即为每个像素点,又因为每4个Y共用一组UV,所以,U和V的大小都为: width(640) height(480) (1 / 4 ). 所以图片真正的大小为 Y+U+V = 3 / 2 (width(640) height(480)).
知道了YUV像素的排列方式以及如何求图像真正大小后我们便可以开始我们真正的工作。
在程序中,比如一张图片的分辨率为640*480,如果该图片的格式为YUV420P,则我们可以很轻松的算出这张图片的Y,U,V三个分量。
我们用数组来存储该图像的大小byte[] src
则(I420)1
2
3Y = src[width * height];
U = Y + scr[1/4 * width * height];
V = U + scr[1/4 * width * height];
注意,计算的结果是通过不同格式来求的,所以不再一一介绍。
YUV格式可分为两大类:打包(packed) , 平面(planar)
- 打包(packed) : 将YUV分量存放在同一个数组中,通常是几个相邻的像素组成的一个宏像素(macro-pixel);
- 平面(planar) : 使用三个数组分开存放YUV三个分量,就像一个三维平面。
在以后的开发中,假如我们要对视频流中的图片做一些特殊处理,比如Crop, Rotate, Scale, 美颜等等,如果想高效实现我们必须了解YUV的格式这样我们才能做出正确处理。
总结
本文为YUV的基础知识,帮助初学者或在工作中接触音视频开发后因概念难以理解造成困惑无法继续开发的开发人员,只有我们了解了YUV的组成才能在代码中进行灵活应用,包括使用例如libyuv等优秀的第三方库。