YUV 是一种彩色编码系统,主要用在视频、图形处理流水线中(pipeline)。相对于 RGB 颜色空间,设计 YUV 的目的就是为了编码、传输的方便,减少带宽占用和信息出错。Y’UV、YUV、YCbCr、YPbPr 几个概念其实是一回事。由于历史关系,Y’UV、YUV 主要是用在彩色电视中,用于模拟信号表示。YCbCr 是用在数字视频、图像的压缩和传输,如 MPEG、JPEG。今天大家所讲的 YUV 其实就是指 YCbCr。Y 表示亮度(luma),CbCr 表示色度(chroma)。Y’UV 不是 Absolute Color Space,只是一种 RGB 的信息编码,实际的显示还是通过 RGB 来显示。Y’,U,V 叫做不同的 component 。
在视频编码系统中为了降低带宽,可以保存更多的亮度信息(luma),保存较少的色差信息(chroma)。这叫做 chrominance subsamping, 色度二次采样。原则: (1) 每一个图形像素都要包含 luma(亮度)值;(2)几个图形像素共用一个 Cb + Cr 值,一般是 2、4、8 个像素。
对于一个 w 宽、h 高的像素图,在水平方向,一行有 w 个像素;在垂直方向,一列有 h 个像素,整个图形有 w * h 个像素。现在来看一下用YUV像素格式来表示像素图,亮度和图形像素的关系,色度和图形像素的关系到底是怎么样的。通常我们对 yuv444,yuv422,yuv420 的解释是后面三个数字分别对应前面三个字母。拿 yuv422 来说,y 对应 4,表示四个图形像素中,每个都有亮度值;u 对应 2,表示四个图形像素中,Cb 只占用两个像素;v 对应 2, 表示四个图形像素中, Cr 占用两个像素。对于 yuv422 模式,这样解释是没有问题。但是对于 yuv420 解释就不对了,不能说四个图形像素中,Cr 占用 0 个像素吧?
现在我们通过下图来理解一下 yuv 各种格式后面数字的含义。
上图所示,左侧一列每一个小矩形表示图形像素,黑框矩形表示有Y分量,小黑点是表示U和V分量(Cb+Cr),H、V和T代表亮度和色度在水平方向、垂直方向和总体的比例关系。比如,4:4:0 水平方向是1/1,垂直方向是1/2,总体比例是两者相乘为1/2,表示一个色度对应了两个亮度。4:2:2 水平方向是1/2,垂直方向是1/1,总体比例为1/2,表示一个色度像素对应了两个亮度像素。4:2:0 水平方向是1/2,垂直方向是1/2,总体比例为1/4,表示一个色度像素对应了四个亮度像素。右侧一列是二次采样模式记号表示, 是 J:a:b 模式,实心黑色圆圈表示包含色度像素(Cb+Cr),空心圆圈表示不包含色度像素。对于 J:a:b 模式,主要是围绕参考块的概念定义的,这个参考块是一个 J x 2 的矩形,J 通常是 4。这样,此参考块就是宽度有 4 个像素、高度有 2 个像素的矩形。a 表示参考块的第一行包含的色度像素样本数,b 表示在参考块的第二行包含的色度像素样本数。
4:4:0 参考块第一行包含四个色度样本,第二行没有包含色度样本。
4:2:2 参考块第一行包含两个色度样本,第二行也包含两个色度样本,他们是交替出现。
4:2:0 参考块第一行包含两个色度样本,第二行没有包含色度样本。
现在我们发现 yuv444,yuv422,yuv420 yuv 等像素格式的本质是:每个图形像素都会包含亮度值,但是某几个图形像素会共用一个色度值(uv),这个比例关系就是通过 4 x 2 的矩形参考块来定的。这样很容易理解类似 yuv440,yuv420 这样的格式了。
因此yuv420的格式不代表没有v分量。我们用ffmpeg将一张图片转为yuv420格式,看看实际大小。
Ffmpeg的安装:Windows安装FFMPEG
第一:下载FFMpeg----https://ffmpeg.zeranoe.com/builds/,自行选择自己需要的多少位的静态程序;
第二:解压到指定文件夹下---d:/ffmpeg
第三:添加到环境变量:d:/ffmpeg/bin
第四:查看FFmpeg版本信息---ffmpeg.exe -version
执行:
ffmpeg.exe -i 1.jpg -s 630x472 -pix_fmt yuvj420p test-yuvj420p.yuv
yuv420 一共有三个平面分别是 Y,U,V,每一个平面都是用 8 bit 二进制数字表示,我们把 8 bit 称作位深度。根据前面的介绍,如果用 yuv420来表示分辨率为 630 * 472 的图片,需要占用多少存储空间呢?每一个像素都需要一个 luma 值,即 y。那么总共需要 630 * 472 = 297360 bytes。每四个像素需要一个 chroma u 值,那么总共需要 630 * 472 / 4 = 74340 bytes。每四个像素需要一个 chroma v 值,那么总共需要 630 * 472 / 4 = 74340 bytes bytes。把 y、u、v 三个 plane 加起来就是:446040 bytes 约等于435.59KB。
最近定位JPEG的问题,遇到从图片提取的采样系数和YUV格式的对应关系,在JPEG图片中,YUV每个分量都有对应的采样系数,每个分量8bit,bit0-3为垂直方向的采样系数,bit4-7为水平方向的采样系数。根据上文水平方向和垂直方向的比例和对应的YUV格式,可以得到常见的采样系数和其对应的YUV格式如下:
采样系数(y_fac,u_fac,v_fac) |
YUV格式 |
备注 |
0x221111 |
YUV420 |
水平方向uv和y的比例为1/2;垂直方向uv和y的比例为1/2;总比例1/4 |
0x211111 |
YUV422 |
水平方向uv和y的比例为1/2;垂直方向uv和y的比例为1/1;总比例1/2 |
0x221212 |
YUV422 |
水平方向uv和y的比例为1/2;垂直方向uv和y的比例为1/1;总比例1/2 |
0x121111 |
YUV440 |
水平方向uv和y的比例为1/1;垂直方向uv和y的比例为1/2;总比例1/2 |
0x222121 |
YUV440 |
水平方向uv和y的比例为1/1;垂直方向uv和y的比例为1/2;总比例1/2 |
0x111111 |
YUV444 |
水平方向uv和y的比例为1/1;垂直方向uv和y的比例为1/1;总比例1/1 |
0x121212 |
YUV444 |
水平方向uv和y的比例为1/1;垂直方向uv和y的比例为1/1;总比例1/1 |
0x212121 |
YUV444 |
水平方向uv和y的比例为1/1;垂直方向uv和y的比例为1/1;总比例1/1 |
0x110000 |
YUV400 |
只有Y分量有采样 |
0x120000 |
YUV400 |
只有Y分量有采样 |
0x210000 |
YUV400 |
只有Y分量有采样 |
0x220000 |
YUV400 |
只有Y分量有采样 |
参考链接:
https://en.wikipedia.org/wiki/YUV
https://wiki.videolan.org/YUV
https://en.wikipedia.org/wiki/Chroma_subsampling