Quiet
  • 主页
  • 归档
  • 分类
  • 标签
  • 链接
  • 关于我

bajiu

  • 主页
  • 归档
  • 分类
  • 标签
  • 链接
  • 关于我
Quiet主题
  • 流媒体
  • WebRTC

音视频系列 --- yuv

bajiu
前端

2021-08-04 14:02:05

一般的视频采集芯片输出的码流一般都是 YUV 格式数据流, 后续视频处理也是对 YUV 数据流进行编码和解析. 所以, 了解 YUV 数据流对做视频领域的人而言, 至关重要

在介绍 YUV 格式之前, 首先介绍一下我们熟悉的 RGB 格式

RGB

RGB 分别表示红 (R)、绿 (G)、蓝 (B), 也就是三原色, 将它们以不同的比例叠加, 可以产生不同的颜色

那么,一张 1920 * 1280 大小的图片, 就占用 1920 * 1280 * 3 / 1024 / 1024 = 7.03MB 存储空间

YUV

YUV 编码采用了明亮度和色度表示每个像素的颜色。

其中 Y 表示明亮度 (Luminance 、Luma), 也就是灰阶值

U、V 表示色度 (Chrominance 或 Chroma), 描述的是色调和饱和度

YCbCr 其实是 YUV 经过缩放和偏移的翻版. 其中 Y 与 YUV 中的 Y 含义一致,Cb,Cr 同样都指色彩, 只是在表示方法上不同而已. YCbCr 其中 Y 是指亮度分量, Cb 指蓝色色度分量, 而 Cr 指红色色度分量

YUV 优点

对于 YUV 所表示的图像, Y 和 UV 分量是分离的. 如果只有 Y 分量而没有 UV 分离,那么图像表示的就是黑白图像. 彩色电视机采用的就是 YUV 图像, 解决与和黑白电视机的兼容问题, 使黑白电视机也能接受彩色电视信号

人眼对色度的敏感程度低于对亮度的敏感程度. 主要原因是视网膜杆细胞多于视网膜锥细胞, 其中视网膜杆细胞的作用就是识别亮度, 视网膜锥细胞的作用就是识别色度. 所以, 眼睛对于亮度的分辨要比对颜色的分辨精细一些

利用这个原理, 可以把色度信息减少一点, 人眼也无法查觉这一点

所以, 并不是每个像素点都需要包含了 Y、U、V 三个分量, 根据不同的采样格式, 可以每个 Y 分量都对应自己的 UV 分量, 也可以几个 Y 分量共用 UV 分量. 相比 RGB, 能够节约不少存储空间

YUV 采样格式

YUV 图像的主流采样方式有如下三种

  • YUV 4:4:4 采样
  • YUV 4:2:2 采样
  • YUV 4:2:0 采样

YUV 4:4:4

YUV 4:4:4 表示 Y、U、V 三分量采样率相同,即每个像素的三分量信息完整,都是 8bit, 每个像素占用 3 个字节, 如图所示:

yuv_01

四个像素为: [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]

可以看到这种采样方式与 RGB 图像大小是一样的

YUV 4:2:2

YUV 4:2:2 表示 UV 分量的采样率是 Y 分量的一半, 如图所示:

yuv_02

四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
采样的码流为: Y0 U0 Y1 V1 Y2 U2 Y3 U3
映射出的像素点为:[Y0 U0 V1]、[Y1 U0 V1]、[Y2 U2 V3]、[Y3 U2 V3]

其中, 每采样一个像素点, 都会采样其 Y 分量, 而 U、V 分量都会间隔采集一个, 映射为像素点时, 第一个像素点和第二个像素点共用了 U0、V1 分量, 以此类推… 从而节省了图像空间

可以看出, 比 RGB 节省了三分之一的存储空间

YUV 4:2:0 (主流 + 划重点)

YUV 4:2:0 并不意味着不采样 V 分量. 它指的是对每条扫描线来说, 只有一种色度分量以 2:1 的采样率存储, 相邻的扫描行存储不同的色度分量. 也就是说, 如果第一行是 4:2:0, 下一行就是 4:0:2, 在下一行就是 4:2:0 ,以此类推:

yuv_03

图像像素为:
[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
​
映射出的像素点为:
[Y0 U0 V5]、[Y1 U0 V5]、[Y2 U2 V7]、[Y3 U2 V7]
[Y5 U0 V5]、[Y6 U0 V5]、[Y7 U2 V7]、[Y8 U2 V7]

其中, 每采样一个像素点, 都会采样 Y 分量, 而 U、V 分量都会隔行按照 2:1 进行采样

相比 RGB, 节省了一半的存储空间

其中YUV420P和YUV420SP根据U、V的顺序, 又可分出2种格式:

  • YUV420P: U前V后即 YUV420P, 也叫 I420, V前U后, 叫 YV12
  • YUV420SP: U前V后叫 NV12, V前U后叫 NV21

数据排列如下:

I420: YYYYYYYY UU VV =>YUV420P

YV12: YYYYYYYY VV UU =>YUV420P

NV12: YYYYYYYY UV UV =>YUV420SP

NV21: YYYYYYYY VU VU =>YUV420SP

为啥会有这么多格式,经过大量搜索发现原因是为了适配不同的电视广播制式和设备系统, 比如 ios 下只有这一种模式 NV12, 安卓的模式是 NV21, 比如 YUV411、YUV420 格式多见于数码摄像机数据中, 前者用于 NTSC 制, 后者用于 PAL 制 (NTSC、PAL、SECAM三大制式简介)

YUV 存储格式

YUV 数据有两种存储格式: 平面格式 (planar format) 和打包格式 (packed format)

  • planar format: 先连续存储所有像素点的 Y, 紧接着存储所有像素点的 U, 随后是所有像素点的 V
  • packed format: 每个像素点的 Y、U、V 是连续交错存储的

因为不同的采样方式和存储格式, 就会产生多种 YUV 存储方式, 这里只介绍基于 YUV422 和 YUV420 的存储方式

YUV420P 和 YUV420SP

YUV420P 是基于 planar 平面模式进行存储,先存储所有的 Y 分量,然后存储所有的 U 分量或者 V 分量

yuv_04

YUV 与 RGB 转换

YUV 与 RGB 之间的转换, 就是将 图像所有像素点的 R、G、B 分量和 Y、U、V 分量相互转换

常规转换: (YUV转换RGB)

YUV420 转换 RGB:

R = Y + 1.402 * 0.5V
G = Y -0.34413 * 0.5U - 0.71414 * 0.5V
B = Y + 1.772 * 0.5U

YUV420P 转换 RGB:

fYmul = y * 1.1643828125;
r = fYmul + 1.59602734375 * v - 0.870787598;
g = fYmul - 0.39176171875 * u - 0.81296875 * v + 0.52959375;
b = fYmul + 2.01723046875 * u - 1.081389160375;

参考资料:

  • YUV - RGB 转换算法
  • 一文理解YUV
  • WEBGL YUV渲染图像实践
上一篇

vite中预加载模块 `modulepreload`

下一篇

音视频系列 --- 视频编码格式(拓展向)

©2024 By bajiu.