zoukankan      html  css  js  c++  java
  • YUV

    YUV 简介

    YUV 是一种彩色编码系统,相对于 RGB 颜色空间,设计 YUV 的目的就是为了编码、传输的方便,减少带宽占用和信息出错。

    YUV 设计的初衷是为了使彩色电视能够兼容黑白电视。对于黑白电视信号,没有色度信息也就是(UV),那么在彩色电视显示的时候指显示亮度信息。

    Y 为亮度信息,UV 为色度(Chroma)信息。U/V分别等于 blue–luminance/red–luminance。Y 信号分量为黑白灰度图。U、V信号分量为单色彩色图。

    YUV 编码

    人眼的视觉特点是对亮度更敏感,对位置、色彩相对来说不敏感。在视频编码系统中为了降低带宽,可以保存更多的亮度信息(luma),保存较少的色差信息(chroma)。这叫做色度二次采样。原则,数字图像中:

    • 每一个图形像素都要包含 luma(亮度)值。
    • 几个图形像素共用一个 Cb + Cr 值,一般是 2、4、8 个像素。

    常见的 YUV 格式以及其对应的采样方式:

    如上图中所示,左侧一列,每一个小矩形是图形像素表示,黑框矩形是色度像素表示,小黑点是表示色度像素值(Cb+Cr),表示图形像素和色度像素在水平和垂直方向的比例关系。比如:

    • 4:4:0 水平方向是1/1,垂直方向是1/2,表示一个色度像素对应了两个图形像素。
    • 4:2:2 水平方向是1/2,垂直方向是1/1,表示一个色度像素对应了两个图形像素。
    • 4:2:0 水平方向是1/2,垂直方向是1/2,表示一个色度像素对应了四个图形像素。

    右侧一列是二次采样模式记号表示, 是 J:a:b 模式,实心黑色圆圈表示包含色度像素(Cb+Cr),空心圆圈表示不包含色度像素。对于 J:a:b 模式,主要是围绕参考块的概念定义的,这个参考块是一个 J x 2 的矩形,J 通常是 4。这样,此参考块就是宽度有 4 个像素、高度有 2 个像素的矩形。a 表示参考块的第一行包含的色度像素样本数,b 表示在参考块的第二行包含的色度像素样本数。

    • 4:4:0 参考块第一行包含四个色度样本,第二行没有包含色度样本。

    • 4:2:2 参考块第一行包含两个色度样本,第二行也包含两个色度样本,他们是交替出现。

    • 4:2:0 参考块第一行包含两个色度样本,第二行没有包含色度样本。

    yuv444,yuv422,yuv420 等像素格式的本质是:每个图形像素都会包含亮度值,但是某几个图形像素会共用一个色度值,这个比例关系就是通过 4 x 2 的矩形参考块来定的。这样很容易理解类似 yuv440,yuv420 这样的格式了。

    存储格式

    • 平面格式(planar formats) :先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的 V,UV的顺序可能会调换。

    • 紧缩格式(packed formats):对于 packed 的YUV格式,每个像素点的Y,U,V是连续交替存储的,如,yuv444 可能是YUV YUV YUV YUV, yuv420 可能是YYUV,YYUV,UV的顺序可能会调换,有些代码里面packed 也称为 Interleaved。

    YUV420SP, YUV420P中的 P 表示的都是planar, SP 是 semi-Planar 他们的区别是:

    • YUV420P: YUV都是planer格式, 即 YYYY UU VV的顺序(UV的顺序可能会调换)。
    • YUV420SP: Y是 planer 格式, UV 是 packet 格式,即 YYYY YYYY UV UV的顺序(UV的顺序可能会调换)。

    yuv422

    yuyv(yuy2)

    [ y u ] [ y v ] [ y u ] [ y v ]
    [ y u ] [ y v ] [ y u ] [ y v ]
    [ y u ] [ y v ] [ y u ] [ y v ]
    [ y u ] [ y v ] [ y u ] [ y v ]
    

    uyvy

    [ u y ] [ v y ] [ u y ] [ v y ]
    [ u y ] [ v y ] [ u y ] [ v y ]
    [ u y ] [ v y ] [ u y ] [ v y ]
    [ u y ] [ v y ] [ u y ] [ v y ]
    

    yuv422p (yu16) 或 (yv16)

    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ u u u u ]
    [ u u u u ]
    [ v v v v ]
    [ v v v v ]
    --------------
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ v v v v ]
    [ v v v v ]
    [ u u u u ]
    [ u u u u ]
    

    yuv422sp (nv16) 或 (nv61)

    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ u v u v ]
    [ u v u v ]
    [ u v u v ]
    [ u v u v ]
    ------------------
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ v u v u ]
    [ v u v u ]
    [ v u v u ]
    [ v u v u ]
    

    yuv420

    yuv420p(yu12)或(yv12)

    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ u u ]
    [ u u ]
    [ v v ]
    [ v v ]
    --------------
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ v v ]
    [ v v ]
    [ u u ]
    [ u u ]
    

    yuv420sp(nv12)或(nv21)

    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ u v u v ]
    [ u v u v ]
    ---------------
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ y y y y ]
    [ v u v u ]
    [ v u v u ]
    

    小结

    • nv 都是 semi-plane 系列
    • nv12 表示正常的顺序,即uv plane,先是u,然后是v,nv 21 表示相反的顺序,即uv plane,先是v,然后是u,nv16 和 nv61 也类似此含义。
    • 12 表示一个像素占用12bit,其中y是定死的占8bit,也就是u占2bit,v占2bit。
    • 16 表示一个像素占用16bit,其中y是定死的8bit,也即是u占4bit,v占4bit。

    分解 YUV 数据

    分解 YUV420P

    /*
    * @brief:splict y u v from yuv420p
    * param[in] src: srource file name
    * param[in] w: srource file width
    * param[in] h: srource file height
    * param[in] frames: srource frame numbers
    */
    int split_yuv420P(const char* src, int w, int h, int frames)
    {
    	assert(src != nullptr);
    	FILE* fsrc = fopen(src, "rb");
    	if (fsrc == nullptr)
    		return -1;
    
    	const char* out_y = "out_y.y";
    	const char* out_u = "out_u.u";
    	const char* out_v = "out_v.v";
    
    	FILE* fy = fopen(out_y, "wb");
    	FILE* fu = fopen(out_u, "wb");
    	FILE* fv = fopen(out_v, "wb");
    
    	assert(fy && fu && fv);
    	const int frame_len = w * h * 3 / 2;
    	uint8_t* buf = new uint8_t[frame_len];
    	for (int i = 0; i < frames; ++i)
    	{
    		int n = fread(buf, 1, frame_len, fsrc);
    		if (n != frame_len)
    			break;
    
    		fwrite(buf, 1, w * h, fy);
    		fwrite(buf + w * h, 1, w * h / 4, fu);
    		fwrite(buf + w * h * 5 / 4, 1, w * h / 4, fv);
    	}
    
    	free(buf);
    	fclose(fsrc);
    	fclose(fy);
    	fclose(fu);
    	fclose(fv);
    
    	return 0;
    }
    

    分解 YUV444P

    /*
    * @brief:splict y u v from yuv444p
    * param[in] src: srource file name
    * param[in] w: srource file width
    * param[in] h: srource file height
    * param[in] frames: srource frame numbers
    */
    int split_yuv444P(const char* src, int w, int h, int frames)
    {
    	assert(src != nullptr);
    	FILE* fsrc = fopen(src, "rb");
    	if (fsrc == nullptr)
    		return -1;
    
    	const char* out_y = "out_y.y";
    	const char* out_u = "out_u.u";
    	const char* out_v = "out_v.v";
    
    	FILE* fy = fopen(out_y, "wb");
    	FILE* fu = fopen(out_u, "wb");
    	FILE* fv = fopen(out_v, "wb");
    
    	assert(fy && fu && fv);
    	const int frame_len = w * h * 3;
    	uint8_t* buf = new uint8_t[frame_len];
    	for (int i = 0; i < frames; ++i)
    	{
    		int n = fread(buf, 1, frame_len, fsrc);
    		if (n != frame_len)
    			break;
    
    		fwrite(buf, 1, w * h, fy);
    		fwrite(buf + w * h, 1, w * h, fu);
    		fwrite(buf + w * h * 2, 1, w * h, fv);
    	}
    
    	delete(buf);
    	fclose(fsrc);
    	fclose(fy);
    	fclose(fu);
    	fclose(fv);
    
    	return 0;
    }
    

    测试:
    下载 Lena 图转换成 YUV 格式:

    .ffmpeg.exe -i Lena.jpg -s 480*420 -pix_fmt yuv42p Lena480_420_420p.yuv
    .ffmpeg.exe -i Lena.jpg -s 480*420 -pix_fmt yuv444p Lena480_420_444p.yuv
    

  • 相关阅读:
    NOIP201208同余方程
    NOIP模拟赛 最佳组合
    NOIP模拟赛 拓展
    CF1253E Antenna Coverage(DP)
    LOJ6033「雅礼集训 2017 Day2」棋盘游戏 (博弈论,二分图,匈牙利算法)
    CF582E Boolean Function(DP,状态压缩,FMT)
    CF750G New Year and Binary Tree Paths(DP)
    Codeforces Round 596 题解
    AGC008E Next or Nextnext(组合计数,神奇思路)
    ARC082E ConvexScore(神奇思路)
  • 原文地址:https://www.cnblogs.com/xiaojianliu/p/14686080.html
Copyright © 2011-2022 走看看