• YUV数据格式


    1. YUV的原理

    YUV 的原理是把亮度(Luma)与色度(Chroma)分离。 “Y”表示亮度,也就是灰度值。 “U”表示蓝色通道与亮度的差值。 “V”表示红色通道与亮度的差值。

    其中 Y 信号分量除了表示亮度信号外,还含有较多的绿色通道量,单纯的 Y 分量可以显示出完整的黑白图像。 U、V 分量分别表示蓝 (blue)、红 (red) 分量信号,只含有色度信息,所以 YUV 也称为 YCbCr,其中,Cb、Cr的含义等同于U、V,C 可以理解为 component 或者 color。

    RGB 转 YUV 的公式能更好地反应 YUV 与 RGB 的关系,以及为什么称为 YCbCr:

    yuv1.png

    RGB与YUV的变换公式如下:

    yuv_rgb.jpg

    在RGB色彩空间中,三个颜色的重要程度相同,所以需要使用相同的分辨率进行存储,最多使用RGB565这样的形式减少量化的精度,但数据量还是很大的。

    研究发现人眼对亮度的敏感超过色度。将图像的亮度信息和颜色信息分离,并使用不同的分辨率进行存储,这样在对主观感觉影响很小的前提下,可以更加有效地存储图像数据。

    2. YUV的取值范围

    与RGB每个像素点的每个分量取值范围为0-255不同(每个分量占8bit),YUV取值范围有两种:

    1. 以Rec.601为代表(还包括BT.709 / BT.2020)的广播电视标准中,Y的取值范围是16-235,U、V的取值范围是16-240。FFmpeg中称之为“mpeg”范围。

    2. 以JPEG为代表的标准中,Y、U、V的取值范围都是0-255。FFmpeg中称之为“jpeg” 范围。

    实际中最常见的是第1种取值范围的YUV(可以自己观察一下YUV的数据,会发现其中亮度分量没有取值为0、255这样的数值)。很多人在这个地方会有疑惑,为什么会去掉“两边”的取值呢?

    原因:

    • 在广播电视系统中不传输很低和很高的数值,实际上是为了防止信号变动造成过载,因而把这“两边”的数值作为“保护带”[4]。

    下面这张图是数字电视中亮度信号量化后的电平分配图。从图中可以看出。

    • 对于8bit量化来说,信号的白电平为235,对应模拟电平为700mV。

    • 黑电平为16,对应模拟电平为0mV。

    • 信号上方的“保护带”取值范围是236至254,而信号下方的“保护带”取值范围是1-15。

    • 最边缘的0和255两个电平是保护电平,是不允许出现在数据流中的。

    与之类似,10bit量化的时候,白电平是2354=940,黑电平是164=64。

    文末名片免费领取音视频开发学习资料,内容包括(C/C++,Linux 服务器开发,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

    quantization_yuv.jpg

    下面两张图是数字电视中色度信号量化后的电平分配图。可以看出:

    • 色度最大正电平为240,对应模拟电平为+350mV。

    • 色度最大负电平为16,对应模拟电平为-350mV。

    • 需要注意的是,色度信号数字电平128对应的模拟电平是0mV。

    quantization_2.jpg

    quantization_3.jpg

    3. YUV的存储格式

    YUV格式有两大类:planar和packed。

    对于 planar 的 YUV 格式,先连续存储所有像素点的 Y,紧接着存储所有像素点的 U,随后是所有像素点的 V。相当于将 YUV 拆分成三个平面 (plane) 存储。

    对于 packed 的 YUV 格式,每个像素点的 Y,U,V 是连续交替存储的。

    4. YUV的采样格式

    主要的采样格式有YUV4:4:4、YUV4:2:2、YUV4:2:0 ,其中YUV4:2:0是最常用的采样格式。

    采样就是根据一定的间隔取值。其中的比例是指 Y、U、V 表示的像素,三者分别占的比值。

    下图是YUV4:4:4,YUV4:2:2,YUV4:2:0的采样示意图。

    image

    • YUV 4:4:4采样,每一个Y对应一组UV分量。

    • YUV 4:2:2采样,每两个Y共用一组UV分量。

    • YUV 4:2:0采样,每四个Y共用一组UV分量。

    5. 存储方式

    下面用图的形式给出常见的YUV数据的存储方式,并在后面附有取样每个像素点的YUV数据的方法。

    (1) YUYV 格式 (属于YUV422)

    YUYV.png

    相邻的两个Y共用其相邻的两个Cb、Cr,对于像素点Y'00、Y'01 而言,其Cb、Cr的值均为 Cb00、Cr00,其他的像素点的YUV取值依次类推。

    (2) UYVY 格式 (属于YUV422)

    YUYV.png

    与YUYV不同的是UV的排列顺序不一样,还原其每个像素点的YUV值的方法与上面一样。

    (3) YUV422P(属于YUV422)

    YUV422P.png

    YUV422P是一种平面模式,其每一个像素点的YUV值提取方法也是遵循YUV422格式的最基本提取方法,即两个Y共用一个UV。比如,对于像素点Y'00、Y'01 而言,其Cb、Cr的值均为 Cb00、Cr00。

    (4) YUV420P格式(属于YUV420)

    YV12.png

    YUV420P,Y,U,V三个分量都是平面格式,分为I420和YV12。I420格式和YV12格式的不同处在U平面和V平面的位置不同。注意,上图中,Y'00、Y'01、Y'10、Y'11共用Cr00、Cb00,其他依次类推。在I420格式中,U平面紧跟在Y平面之后,然后才是V平面(即:YUV);但YV12则是相反(即:YVU)。

    YUV420p.png

    I420: YYYYYYYY UU VV YV12: YYYYYYYY VV UU

    (5) NV12、NV21(YUV420sp,属于YUV420)

    NV12.png

    这两种格式的不同在于UV交错排列的顺序不同,是一种two-plane模式,即Y和UV分为两个Plane,但是UV(CbCr)为交错存储,而不是分为三个plane。其提取方式与上一种类似,即Y'00、Y'01、Y'10、Y'11共用Cr00、Cb00,其他依次类推。

    假设一个分辨率为8X4的YUV图像,它们的格式如下图: YUV420sp格式如下图

    YUV420sp.png

    NV12: YYYYYYYY UVUV NV21: YYYYYYYY VUVU

    以w*h大小图像的YUV420数据为例, 其存储格式是: 共大小为(w * h * 3/2)字节, Y分量:(w * h)个字节 U(Cb)分量:(w * h/4)个字节 V(Cr)分量:(w * h/4)个字节

    6. 10bit YUV数据的存储

    常见的yuv数据,每个像素的一个通道一般是占用一个字节即8bit。而HDR常用的标准HDR10,数据是10bit的。

    10bit数据是怎么存储的呢?我们一般会有两种想法:

    1. 每个像素的一个通道占用两个字节,其中6个bit是填充位。

    2. 每个像素的一个通道占用10bit,10bit数据和10bit数据是挨着排列的。

    优缺点

    1. 方式1:便于运算处理,有存储冗余;

    2. 方式2:存储没有冗余,计算麻烦。

    事实上,10bit是采用方式1存储的,并且高有效字节的前6个bit是填充的0。

    HDR10视频解码得到YUV数据的命令:

    //yuv420p10le格式
    ffmpeg -i hdr10.mp4 -f rawvideo -pix_fmt yuv420p10be hdr10_yuv420p10le.yuv
    ​
    //yuv420p10be格式
    ffmpeg -i hdr10.mp4 -f rawvideo -pix_fmt yuv420p10be hdr10_yuv420p10le.yuv

    (1)yuv420p10le的数据格式的16进制的显示:

    image.png

    比如地址019f7040h开始的两个字节:

    -------------低地址---->高地址--------------
    00011111 000000 01  

    (2)yuv420p10be的数据格式的16进制的显示:

    image.png

    比如地址019f7040h开始的两个字节:

    -------------低地址---->高地址--------------
    000000 01 00011111   

    工具推荐:一个可以播放10bit yuv流的播放器YUV Player

    作者:smallest_one 链接:https://www.jianshu.com/p/8e0b9bbf9a41

  • 相关阅读:
    Redis之hash类型
    攻防世界看雪看雪看雪
    Linux进程理解(上)
    React Router 参数使用详解
    PyQt GUI 编程-01
    数学建模学习(101):车辆路线规划问题
    UE4和C++ 开发-C++与UMG交互3
    Ubuntu18.04安装Loam保姆级教程
    【JAVA UI】HarmonyOS Glide简单使用
    页面中满屏水印
  • 原文地址:https://blog.csdn.net/yinshipin007/article/details/128116325