前言
最近在学习一个开源算法库:libyuv。看到这个名字的时候我很懵逼,“lib”自然是静态链接库的意思,那么“yuv”又是个什么鬼东西?
在本文中你将会看到以下内容:
1、YUV 的含义及历史
2、YUV 的格式及数据存储
3、YUV 与 RBG 的关系
4、本文参考资料
YUV 的含义及历史
在我最初看《计算机程序设计艺术》的时候很不理解为什么高德纳要在开始花费大量力气去探究 "Algorithm" 一词的由来。现在我有点明白了,当人们第一次接触一个概念时,总是竭力想要在脑海中构建一个相关的模型。比如我说“苹果”的时候,你脑海中会浮现一个苹果的样子;当我说“RGB”的时候,你脑海中很快会浮现红、绿、蓝三原色。这样你就能很快明白我要讲的是什么概念。那么,如果我说“埃弗顿”,你知道我要说什么吗?实际上我自己都不知道“埃弗顿”是什么意思,因为这三个字是我随便敲击的 :)
所以为了弄明白“YUV”是什么,我必须知道“YUV”这三个字母组合的由来。
首先是度娘给的答案:
之后在英文缩写网上查到:
最后结合libyuv开源项目指导文档:
我终于明白了我纠结的“YUV”到底是什么了:一种颜色编码方法!
那么为什么需要这种编码方式呢?
YUV的发明是在彩色电视与黑白电视的过渡时期。黑白视频只有Y(Luma,Luminance)视频,也就是灰阶值。到了彩色电视规格的制定,是以YUV/YIQ的格式来处理彩色电视图像,把UV视作表示彩度的C(Chrominance或Chroma),如果忽略C信号,那么剩下的Y(Luma)信号就跟之前的黑白电视频号相同,这样一来便解决彩色电视机与黑白电视机的兼容问题。
好吧,总结一下:
Y:表示颜色的明亮度,即灰阶值
U/V:表示颜色的亮度,其中U是蓝色分量,V是红色分量。
YUV:共同描述了一个点的颜色,和RGB类似。
所以,YUV不是我以为的“三个单词的首字母缩写”!
YUV又被叫做 YCbCr,这里的‘Y’仍然表示亮度或灰度(luminance),‘Cb’表示"blue"部分去掉亮度的色度(Chrominance或Chroma)分量, ‘Cr’表示"red"部分去掉亮度的色度分量。
YUV 的格式及数据存储
YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,YUV 4:4:4,YUV 4:2:2,YUV 4:2:0。我们需要根据其采样格式来从码流中还原每个像素点的YUV值,因为只有正确地还原了每个像素点的YUV值,才能通过YUV与RGB的转换公式提取出每个像素点的RGB值,然后显示出来。
我们用三张图来解释YUV的三种采样方式,黑点表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量:
很容易看出来:
YUV 4:4:4 采样是对每个像素点都进行Y、UV分量采样;每一个Y对应一个UV分量。
YUV 4:2:2 采样是在行 或 列进行Y分量全采,每两个Y分量取一UV分量;每两个Y分量对应一个UV分量。例如图中的A、B像素共用一个UV分量。
YUV 4:2:0 采样是在行 及 列进行Y分量全采,每两个Y分量取一UV分量;这样每4个Y分量对应一个UV分量。例如图中的C、D、E、F像素共用一个UV分量。
我们知道YUV的采样方式了,那么YUV数据在内存中是怎么存储呢?这里需要先了解两个概念:planar、packed。
YUV planar(平面) 格式:先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。
YUV two-planar 格式:先连续存储所有像素点的Y,紧接着存储所有像素点的UV。
YUV packed(打包) 格式:连续存储所有像素点的 YUV。
结合采样方式以及数据存储格式,会有跟多YUV格式,这里简单列举几个YUV格式:
约定:下诉大小针对 m * n 的图片,其中 m 表示图片的高,m表示图片的宽,单位像素。
size、sizeY、sizeU、sizeV 分别表示整幅图片、Y、U、V分量占用的内存大小,单位字节。
1、AYUV
采样方式:4:4:4 存储格式:packed 补充:A表示 Alpha
size = m * n * 4; sizeA = sizeY = sizeU = sizeV = m * n
2、YUYV
采样方式:4:2:2
size = m * n * 3 / 2; sizeY = m * n; sizeU = sizeV = m * n / 2
3、UYVY
采样方式:4:2:2
size = m * n * 3 / 2; sizeY = m * n; sizeU = sizeV = m * n / 2
是的,你没有看错,UYVY 与 YUYV 区别只是UV的排列顺序不一样。
4、YUV422P
采样方式:4:2:2 存储格式:planar
size = m * n * 3 / 2; sizeY = m * n; sizeU = sizeV = m * n / 2
5、YV12,YU12
采样方式:4:2:0 存储格式:planar
size = m * n * 5 / 4; sizeY = m * n; sizeU = sizeV = m * n / 4
6、NV12、NV21
采样方式:4:2:0 存储格式: two-planar
size = m * n * 5 / 4; sizeY = m * n; sizeU = sizeV = m * n / 4
Camera 返回的YUV数据一般是NV21和YV12两种。
Camera 返回的YUV数据一般是NV21和YV12两种。
Camera 返回的YUV数据一般是NV21和YV12两种。
YUV 与 RBG 的关系
对RGB,我们并不陌生,从初中开始接触的色光的三原色,告诉我们我们可以看到的光可以由这三种颜色按一定的比例去混合得到;RGB 模型是目前常用的一种彩色信息表达方式,它使用红、绿、蓝三原色的亮度来定量表示颜色。该模型也称为加色混色模型,是以RGB三色光互相叠加来实现混色的方法,因而适合于显示器等发光体的显示。
而YUV则是根据人眼的视觉特点提出的模型:人眼对亮度更敏感,对位置、色彩相对来说不敏感。
既然RGB、YUV都是对颜色的建模、编码处理,那么他们之间能不能相互转换呢?别急先来看张图:
当我们改变 Y(亮度)值会发生什么变化呢?且看:
这里列一个YUV与RGB的换算公式:
实际上更具不同的标准,YUV和RGB之间的转换会有所不同,更详细请看参考质料《YUV与RGB互转各种公式》。
本文参考质料:
《YUV介绍》
《YUV格式到底是什么?》
《对颜色空间YUV、RGB的理解》
《YUV与RGB互转各种公式》