【音视频】YUV

什麼是yuv YUV 颜色编码采用的是 明亮度 和 色度 来指定像素的颜色。
其中,Y 表示明亮度(Luminance、Luma),而 U 和 V 表示色度、浓度(Chrominance、Chroma)。
和 RGB 表示图像类似,每个像素点都包含 Y、U、V 分量。但是它的 Y 和 UV 分量是可以分离的,如果没有 UV 分量一样可以显示完整的图像,只不过是黑白的,所以yuv图像可以兼容於黑白影像和彩色影像。
为什么yuv更省空间
RGB像素表示法很简单,如果你没做过数字图像和视频的开发,可能很少听说过YUV。但在数字图像和视频编码里领域,YUV像素表示法非常流行,有几个原因造成。首先,人眼对亮度更敏感,对颜色的敏感度稍弱,所以使用YUV来表示图像可以节省存储资源。其次由于数字摄像机传感器不能直接采样三原色,所以RGB也不适合硬件处理。因此YUV才如此应用广泛。
用RGB表示像素需要用3个字节。但YUV表示一个像素,可能是3个字节,也可能是2个字节(丢掉U或者丢掉V),还可能只有1个字节(丢掉U和V)。占用字节大小的不同因为采用不同的采样方式。
YUV采样格式 YUV 图像的主流采样方式有如下三种:

  • YUV 4:4:4采样
  • YUV 4:2:2采样
  • YUV 4:2:0采样
YUV 4:4:4 采样
【音视频】YUV
文章图片

YUV 4:4:4 采样,意味着 Y、U、V 三个分量的采样比例相同,一个像素点,都是(Y、U、V)3个字节组成
举个例子 :假如图像像素为:[Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]那么采样的码流为:Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3 最后映射出的像素点依旧为 [Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]

YUV 4:2:2采样
【音视频】YUV
文章图片

YUV 4:2:2 采样,意味着 UV 分量是 Y 分量采样的一半,Y 分量和 UV 分量按照 2 : 1 的比例采样。如果水平方向有 10 个像素点,那么采样了 10 个 Y 分量,而只采样了 5 个 UV 分量。
举个例子 : 假如图像像素为:[Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3] 那么采样的码流为:Y0 U0 Y1 V1 Y2 U2 Y3 V3 其中,每采样过一个像素点,都会采样其 Y 分量,而 U、V 分量就会间隔一个采集一个。 最后映射出的像素点为 [Y0 U0 V1]、[Y1 U0 V1]、[Y2 U2 V3]、[Y3 U2 V3]

YUV 4:2:0 采样
【音视频】YUV
文章图片

举个例子 :假设图像像素为:[Y0 U0 V0]、[Y1 U1 V1]、 [Y2 U2 V2]、 [Y3 U3 V3] [Y5 U5 V5]、[Y6 U6 V6]、 [Y7 U7 V7] 、[Y8 U8 V8]那么采样的码流为:Y0 U0 Y1 Y2 U2 Y3 Y5 V5 Y6 Y7 V7 Y8其中,每采样过一个像素点,都会采样其 Y 分量,而 U、V 分量就会间隔一行按照 2 : 1 进行采样。最后映射出的像素点为:[Y0 U0 V5]、[Y1 U0 V5]、[Y2 U2 V7]、[Y3 U2 V7] [Y5 U0 V5]、[Y6 U0 V5]、[Y7 U2 V7]、[Y8 U2 V7]

YUV存储格式 采样之后,就是YUV的存储,往往我们操作的都是存储格式的二进制,所以要理解YUV存储的排列方式。才能正常解析YUV图像。
YUV 的存储格式,有两种:
  • planar 平面格式
    • 指先连续存储所有像素点的 Y 分量,然后存储 U 分量,最后是 V 分量。
  • packed 打包模式
    • 指每个像素点的 Y、U、V 分量是连续交替存储的。
这里篇幅关系,只介绍YUV420的存储格式(比较常用)
YUV 420P 和 YUV 420SP 都是基于 Planar 平面模式 进行存储的,先存储所有的 Y 分量后, YUV420P 类型就会先存储所有的 U 分量或者 V 分量,而 YUV420SP 则是按照 UV 或者 VU 的交替顺序进行存储了,具体查看看下图:
YUV420SP 的格式:
【音视频】YUV
文章图片

YUV420P 的格式:
【音视频】YUV
文章图片

為什麼yuv要轉換成rgb? 浏览器不能直接识别输出yuv图像,需要转成rgb格式。
YUV与RBG的转换 为了实现格式转换,我们首先要明确待转换格式和目标格式的特点和相互转换关系,这是编程实现转换的核心。
YUV转RGB的公式,我查阅到的不少于3个,但我不明白原理,需要查阅下:
Y = 0.298R + 0.612G + 0.117B; U = -0.168R - 0.330G + 0.498B + 128; V = 0.449R - 0.435G - 0.083B + 128; R = Y + 1.4075( V - 128); G = Y - 0.3455( U - 128) - 0.7169( V - 128); B = Y + 1.779( U - 128);

比如YUV图像转RGB图像,需要逐个遍历像素所需的YUV字节,通过公式转换为每个像素对应的RGB字节即可
YUV中的stride stride可以翻译为:跨距、步长
stride指在内存中每行像素所占的空间。如下图所示,为了实现内存对齐,每行像素在内存中所占的空间并不是图像的宽度。
【音视频】YUV
文章图片

一般stride都是等于图像的width,除非有内存对齐的需要,不过我还没遇到这种情况。
JS实现YUV转RGB渲染图像 【【音视频】YUV】在线预览地址
Document - 锐客网【音视频】YUV
文章图片

参考文章
  • yuv 图像里的stride和plane的解释
  • 一文读懂 YUV 的采样与格式
  • 音视频平凡之路之YUV像素介绍

    推荐阅读