YUV颜色详解

2,887 阅读3分钟

RGB颜色编码

RGB 图像中,每个像素点都有红、绿、蓝三个颜色通道,其中每个通道都占用 8 bit,也就是一个字节,那么一个像素点也就占用 24 bit,也就是三个字节。

一张 1280 * 720 大小的图片,就占用 1280 * 720 * 3 / 1024 / 1024 = 2.63 MB 存储空间。

YUV颜色编码

在 YUV空间中,每一个颜色有一个亮度信号 Y,和两个色度信号 U 和V。 如果没有U/V分量,那么显示出来的图像就是黑白的。

对于YUV来说,并不是每个Y分量就对应一个U/V分量,根据不同的采样格式,可以一个Y分量对应一个U/V分量,也可以多个Y分量共享一个U/V分量。

YUV常见采样格式

假设原图像结构为:[Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]

YUV4:4:4: 即 Y:U:V = 4:4:4 ,表示一个Y分量对应一个U/V分量,采样完为:Y0U0V0Y1U1V1Y2U2V2Y3U3V3;这种采样结束后图片大小跟rgb编码方式并无区别。

YUV4:2:2: 即 Y:U:V = 4:2:2 ,表示Y 分量和 UV 分量按照 2 : 1 的比例采样,采样完为:Y0U0Y1V1Y2U2Y3V3;该方式采样结束后图片大小为: (1280 * 720 * 8 + 1280 * 720 * 8/2 + 1280 * 720 * 8/2)/ 8 / 1024 / 1024 = 1.76 MB 。

YUV4:2:0(现在比较常用的): 即 Y:U:V = 4:2:0 ,并不是指只采样 U 分量而不采样 V 分量,而是指,在每一行扫描时,只扫描一种色度分量(U 或者 V),和 Y 分量按照 2 : 1 的方式采样: 原始图像: [Y0 U0 V0]、[Y1 U1 V1]、 [Y2 U2 V2]、 [Y3 U3 V3] [Y4 U4 V4]、[Y5 U5 V5]、 [Y6 U6 V6]、 [Y7 U7 V7] 采样完: Y0U0Y1Y2U2Y3 Y4V4Y5Y6V6Y7 此时图片大小变为: (1280 * 720 * 8 + 1280 * 720 * 0.25 * 8 * 2)/ 8 / 1024 / 1024 = 1.32 MB 。

YUV和RGB的转换:

Y = 0.257R + 0.504G + 0.098B + 16
U = 0.148R - 0.291G + 0.439B + 128
V = 0.439R - 0.368G - 0.071B + 128

B = 1.164(Y - 16) + 2.018(U - 128)
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
R = 1.164(Y - 16) + 1.596(V - 128)

YUV存储格式

YUV的存储格式分为:plannar(平面)和packed(打包)

  • plannar(平面): 先连续存储所有像素点的 Y 分量,然后存储 U 分量,最后是 V 分量。

YU12 和 YV12 格式 YU12 和 YV12 格式都属于 YUV 420P 类型,即先存储 Y 分量,再存储 U、V 分量,区别在于:YU12 是先 Y 再 U 后 V,而 YV12 是先 Y 再 V 后 U 。

YU12 : 也叫做I420(PC端使用) : YYYYYYYY UU VV --> YUV420P

YV12 : YYYYYYYY VV UU --> YUV420P

  • **packed(打包,移动端使用):**每个像素点的 Y、U、V 分量是连续交替存储的.

NV12 和 NV21 格式 NV12 和 NV21 格式都属于 YUV420SP 类型。它也是先存储了 Y 分量,但接下来并不是再存储所有的 U 或者 V 分量,而是把 UV 分量交替连续存储。 NV12 是 IOS 中有的模式,它的存储顺序是先存 Y 分量,再 UV 进行交替存储。 NV21 是 安卓 中有的模式,它的存储顺序是先存 Y 分量,在 VU 交替存储。

NV12 : YYYYYYYY UVUV --> YUV420SP

NV21 : YYYYYYYY VUVU --> YUV420SP

开发过程中,有可能出现iOS端的视频在Android端发生了倒置或者翻转,那么就可能是因为两边的YUV存储格式不一样导致的。