这段时间在做一些关于yuv格式的操作,于是查资料找yuv是什么,搜了很多文章,但是看的很混乱特别是各种存储方式,所以按照自认为容易理解的顺序整理了下,如有错误请及时指正:-)
一、简介
yuv是一中类似于RGB的像素数据编码格式,只不过RGB是用Red、Green、Blue三种颜色编码的,而yuv是用Y(亮度)、U(色度)、V(浓度)进行编码,由于相邻的两个像素,数据差异不大,所以丢弃相邻像素的部分数据对于整体影响不大,同时丢弃数据还节省空间便于存储。人们对亮度比对色彩更加敏感,所以每个每个像素的亮度Y不动,而对UV数据进行丢弃。没有UV信息,一样更可以完整的显示图像,只不过是黑白的,所以在数据的存储上,根据数据丢弃的方式(即采样方式)不同,YUV出现了不同的格式
二、采样方式
既然它是一种像素编码方式,那就要搞清楚它是如何表现一个像素的,即采样方式。主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0。
如果还没有懂,就先记住下面的规则
-
YUV 4:4:4采样,每一个Y对应一组UV分量
-
YUV 4:2:2采样,每两个Y共用一组UV分量 U = Y / 2 V = Y / 2
-
YUV 4:2:0采样,每四个Y共用一组UV分量 U = Y / 4 V = Y /4
看到一个非常有助于理解的例子,看完应该就懂了:
YUV的分量数据各占用8位(各占1字节),在不丟失数据的情況下,4个像素(12字节)的数据依次为,
Y0U0V0 Y1U1V1 Y2U2V2 Y3U3V3
1)YUV444
存储时,数据为Y0U0V0 Y1U1V1 Y2U2V2 Y3U3V3
即YUV444,4个像素有4个Y,4个U,4个V,为丢弃任何数据。
2)YUV422
存储时,数据为Y0U0 Y1U1 Y2V2 Y3V3
即YUV422,4个像素有4个Y,2个U,2个V,横向丢弃数据。
由于临近像素的相似性不仅局限于横向,数据还可以进一步纵向丢弃,以减少存储空间,因此YUV420便出现了
3)YUV420
YUV420为横向纵向同时丢弃的采样方式。以一个YUV444格式的4x4数据为例
Y00U00V00 Y01U01V01 Y02U02V02 Y03U03V03
Y10U10V10 Y11U11V11 Y12U12V12 Y13U13V13
Y20U20V20 Y21U21V21 Y22U22V22 Y23U23V23
Y30U30V30 Y31U31V31 Y32U32V32 Y33U33V33
以YUV420格式丢弃数据后,将变为
Y00U00 Y01 Y02U02 Y03
Y10V10 Y11 Y12V12 Y13
Y20U20 Y21 Y22U22 Y23
Y30V30 Y31 Y32V32 Y33
YUV420的采样方式为:
(i)偶数像素丢弃UV。
(ii)在(i)的基础上,奇数行进一步丢弃V,偶数行进一步丢弃U
三、存储方式
在了解存储方式之前,先了解下格式:
planar(平面格式)的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V
packed(紧缩格式)的YUV格式,每个像素点的Y,U,V是连续交叉存储的
Semi-planar(半平面格式),即Y单独占一块地方,但其后U、V又紧挨着排在一起
1)YUV422
-
紧缩格式(Packed),即YUV是按像素点存储的,即YUYVYUYVYUYV这样顺序存储。
-
平面格式(Planar),即Y、U、V是分开存储的,每个分量占一块地方,即YYYYYYY.......UUUU....VVVV...,根据U、V的顺序,又有2种,U前V后即YUV422P,也叫I422,又叫YU16。V前U后,叫YV16(YV表示Y后面跟着V,16表示16bit)
-
半平面格式(Semi-planar),即Y单独占一块地方,但其后U、V又紧挨着排在一起,即YYYYYYY.......UVUVUVUV...... 根据U、V的顺序,又有2种,U前V后叫NV16,在国内好像很多人叫它为YUV422SP格式;V前U后叫NV61。
(下面的图很多资料中都有,但是直接看会有点混乱,所以我放到后面当作辅助理解,其实看到这里应该懂了)
a)YUYV格式
相邻的两个Y共用其相邻的两个Cb、Cr,分析,对于像素点Y'00、Y'01 而言,其Cb、Cr的值均为 Cb00、Cr00,其他的像素点的YUV取值依次类推
b)UYVY格式
只是UV的排列顺序不一样而已,还原其每个像素点的YUV值的方法与上面一样
c)YUV422P格式
先存放所有的Y分量,然后存储所有的U(Cb)分量,最后存储所有的V(Cr)分量,如上图所示。其每一个像素点的YUV值提取方法也是遵循YUV422格式的最基本提取方法,即两个Y共用一个UV。比如,对于像素点Y'00、Y'01 而言,其Cb、Cr的值均为 Cb00、Cr00。
2)YUV420
-
planar格式,Y , U , V分别在不同平面,也就是有三个平面,、U、V是分开存储的,每个分量占一块地方,其中Y为 width*height,而U、V合占Y的一半,该种格式每个像素占8+2+2 = 12bits。根据U、V的顺序,分出2种格式,U前V后即YUV420P,也叫 I420,V前U后,叫YV12(YV表示Y后面跟着V,12表示12bit);
-
半平面格式(Semi-planar),即Y单独占一块地 方,但其后U、V又紧挨着排在一起,根据U、V的顺序,又有2种,U前V后叫NV12,在国内好像很多人叫它为YUV420SP格式;V前U后叫 NV21
(图的作用同上)
a)YUV420P/I420
在android平台下
也叫作I420格式
,首先是所有Y值
,然后是所有U值
,最后是所有V值,U在前V在后
b)YV12
首先是所有Y值
,然后是所有V值
,最后是所有U值,V在前U在后
c)NV12/YUV420SP
NV12与NV21类似,也属于YUV420SP
格式,NV12
存储顺序是先存Y值
,再UV
交替存储:YYYYUVUVUV
,以 4 X 4
图片为例子,占用内存为 4 X 4 X 3 / 2 = 24
个字节
d)NV21
android手机从摄像头采集的预览数据一般都是NV21,存储顺序是先存Y,再VU交替存储,YYYYVUVUVU
,以 4 X 4
图片为例子,占用内存为 4 X 4 X 3 / 2 = 24
个字节
【总结】
1、YUV444
(1)YUV444p:YYYYYYYYY VVVVVVVVV UUUUUUUU
2、YUV422
(1)YUV422p:
YV16: YYYYYYYY VVVV UUUU (V前U后)
YUV422p或I422或YU16: YYYYYYYY UUUU VVVV (U前V后)
(2)YUV422sp:
NV61:YYYYYYYY VUVUVUVU (V前U后)
NV16:YYYYYYYY UVUVUVUV (U前V后)
(2)YUVY:YUYV YUYV YUYV YUYV
(3)UYVY:UYVY UYVY UYVY UYVY
3、YUV420
(1)YUV420p:
YV12:YYYYYYYY VV UU
I420:YYYYYYYY UU VV
(2)YUV420sp:
NV12:YYYYYYYY UVUV
NV21:YYYYYYYY VUVU
【参考】
https://blog.****.net/sinat_29891353/article/details/100975238
https://blog.****.net/xjhhjx/article/details/80291465