YUV,是一种颜色编码方法。“Y” 表示明亮度(Luminance、Luma),“U” 和 “V” 则是色度、浓度(Chrominance、Chroma)。Y’UV、YUV、YCbCr、YPbPr 几个概念其实是一回事儿。由于历史关系,Y’UV、YUV 主要是用在彩色电视中,用于模拟信号,YCbCr 用于数字视频、图像的压缩和传输,如 MPEG、JPEG。Y’UV 设计的初衷是为了使彩色电视能够兼容黑白电视。对于黑白电视信号,没有色度信息也就是(UV),那么在彩色电视显示的时候指显示亮度信息。将一张图片的Y、U、V数据单独显示就会如下图所示:
由于人眼对色度的敏感度不及对亮度的敏感度,图像的色度分量不需要有和亮度分量相同的清晰度,所以许多视频系统在色差通道上进行较低(相对亮度通道)清晰度(例如,抽样频率)的抽样。这样在不明显降低画面质量的同时降低了影像信号的总带宽。因抽样而丢失的色度值用内插值,或者前一色度值来替代。在压缩影像中,以 4:2:2 Y’CbCr作例,它只需R’G’B’(4:4:4)三分之二的带宽,但是在视觉效果上几乎没有影响。
视频系统的抽样系统通常用一个三分比值表示:J : a : b(例如 4:2:2 ),形容一个以 J 个像素宽及两个像素高的概念区域,有时候会以四分比值表示(例如4:2:2:4),依序列出为:
为节省带宽起见,大多数 YUV 格式平均使用的每像素位数都少于24位。主要的抽样(subsample)格式有 YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1 和 YCbCr 4:4:4。YUV 的表示法称为 A:B:C 表示法:
YUV 存储分成两种格式:
常见的两种压缩格式:YUYV 、UYVY
每个像素点都采样 Y 分量,但是每隔一个像素采样它的 UV 分量,每两个 Y 共用一组 UV 分量。如图 Y0 和 Y1 公用 U0 V0 分量,Y2 和 Y3 公用 U2 V2 分量,依次类推。
顺序和 YUYV 相反,如图 Y0 和 Y1 公用 U0 V0 分量,Y2 和 Y3 公用 U2 V2 分量,依次类推。
常见的四种平面格式:YV12、I420、NV12、NV21
许多软件MPEG编解码器都采用这种格式。它包括一个大小为 N x M的 Y 平面,和大小为(N / 2)x(M / 2)的 V 平面 与 U 平面。
分量顺序为 Y V U。
与YV12基本相同,只是分量顺序变成了为 Y U V。所以 这种格式也被称为 YU12 。
NV12 是 iOS 中有的格式,它的存储顺序是先存 Y 分量,再 U V 进行交替存储。
NV21 是 安卓 中有的格式,它的存储顺序是先存 Y 分量,再 V U 交替存储。
Y = 0.299 ∗ R + 0.587 ∗ G + 0.114 ∗ B U = − 0.169 ∗ R − 0.331 ∗ G + 0.5 ∗ B + 128 V = 0.5 ∗ R − 0.419 ∗ G − 0.081 ∗ B + 128 \begin{array}{rll} Y &= 0.299 * R + 0.587 * G + 0.114 * B \\ U &= -0.169 * R - 0.331 * G + 0.5 * B + 128 \\ V &= 0.5 * R - 0.419 * G - 0.081 * B + 128 \end{array} YUV=0.299∗R+0.587∗G+0.114∗B=−0.169∗R−0.331∗G+0.5∗B+128=0.5∗R−0.419∗G−0.081∗B+128
[ Y U V ] = [ 0.299 0.587 0.114 − 0.169 − 0.331 0.5 0.5 − 0.419 − 0.081 ] [ R G B ] + [ 0 128 128 ] \begin{bmatrix} Y \\ U \\ V \end{bmatrix} =\begin{bmatrix} 0.299 & 0.587 & 0.114 \\ -0.169 & -0.331 & 0.5 \\ 0.5 & -0.419 & -0.081 \end{bmatrix} \begin{bmatrix} R \\ G \\ B \end{bmatrix} + \begin{bmatrix} 0 \\ 128 \\ 128 \end{bmatrix} ⎣⎡YUV⎦⎤=⎣⎡0.299−0.1690.50.587−0.331−0.4190.1140.5−0.081⎦⎤⎣⎡RGB⎦⎤+⎣⎡0128128⎦⎤
R = Y + 1.13983 ∗ ( V − 128 ) G = Y − 0.39465 ∗ ( U − 128 ) − 0.58060 ∗ ( V − 128 ) B = Y + 2.03211 ∗ ( U − 128 ) \begin{array}{rll} R & = Y + 1.13983 * (V - 128) \\ G & = Y - 0.39465 * (U - 128) - 0.58060 * (V - 128) \\ B & = Y + 2.03211 * (U - 128) \end{array} RGB=Y+1.13983∗(V−128)=Y−0.39465∗(U−128)−0.58060∗(V−128)=Y+2.03211∗(U−128)
[ R G B ] = [ 1 − 0.00093 1.401687 1 − 0.3437 − 0.71417 1 1.77216 0.00099 ] [ Y U − 128 V − 128 ] \begin{bmatrix} R \\ G \\ B \end{bmatrix} =\begin{bmatrix} 1 & -0.00093 & 1.401687 \\ 1 & -0.3437 & -0.71417 \\ 1 & 1.77216 & 0.00099 \end{bmatrix} \begin{bmatrix} Y \\ U - 128 \\ V - 128 \end{bmatrix} ⎣⎡RGB⎦⎤=⎣⎡111−0.00093−0.34371.772161.401687−0.714170.00099⎦⎤⎣⎡YU−128V−128⎦⎤
参考资料:
https://docs.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering
https://docs.microsoft.com/zh-cn/previous-versions/ms867704(v=msdn.10)?redirectedfrom=MSDN
https://en.wikipedia.org/wiki/Chroma_subsampling
https://en.wikipedia.org/wiki/YUV
https://glumes.com/post/ffmpeg/understand-yuv-format/
https://www.fourcc.org/yuv.php