YUV的概念

YUV 和我们熟知的 RGB 类似,是一种颜色编码格式。它主要用于电视系统和模拟视频邻域(如 Camera 系统)。YUV 包含三个分量,其中 Y 表示明亮度(Luminance 或 Luma),也就是灰度值。而 U 和 V 则表示色度(Chrominance 或 Chroma),作用是描述图像色彩及饱和度,用于指定像素的颜色。没有 UV 分量信息,一样可以显示完整的图像,只不过是黑白的灰度图像。YUV 格式的好处是很好地解决了彩色电视机与黑白电视机的兼容问题(当只要Y分量时就是黑白图像)。YCbCr,YPbPr等专有名词都可以称为YUV。

YUV的格式

YUV的格式取决采样方式

YUV的采样方式

  • 4:4:4表示完全取样(每一个Y对应一组UV分量)
  • 4:2:2表示2:1的水平取样,垂直完全采样(每两个Y共用一组UV分量)
  • 4:2:0表示2:1的水平取样,垂直2:1采样(每四个Y共用一组UV分量)
  • 4:1:1表示4:1的水平取样,垂直完全采样(每四个Y共用一组UV分量)

YUV的存储格式

我们主要关心的是如何处理YUV数据,所以最关心的是YUV数据的存储格式。内存中存储的方式包括两种:

  1. planar 格式:先连续存储所有像素点的 Y 分量,紧接着存储所有像素点的 U 分量,再是V分量(当然不同存储格式的UV的先后顺序是不一样的,如I420的V在U后,YV12则是U在V后)。

  2. packed 格式:每个像素的Y,U,V分量交替存储。

Y,U,V分量存储时的先后顺序的不同,代表了不同的格式,以下列出了几种常见的YUV格式:

  • YUYV(属于YUV422)

    两个Y共用一组UV分量。Y,U,V分量交替存储。

  • UYVY(属于YUV422)


可以看到与YUYV的分量的顺序不一样。

  • YUV422P(属于YUV422)

    是Planar存储模式,依次是Y,U,V。U分量在V分量之前

YUV420

根据U分量和Y分量的位置不同,也分为几种类型,常见的如下:

  • YV12(属于YUV420)


是Planar存储模式,依次是Y,V,U。V分量在U分量之前。

  • NV12(属于YUV420)


先是Y,在是U,V分量交替出现

一个简易存储示意图

I420: YYYYYYYY UU VV    =>YUV420P
YV12: YYYYYYYY VV UU    =>YUV420P
NV12: YYYYYYYY UVUV     =>YUV420SP
NV21: YYYYYYYY VUVU     =>YUV420SP

YUV420sp与YUV420p的不同之处在,存储UV分量时,YUV420sp中的UV分量是交替存储。

处理I420

I420属于YUV420P(存储格式为Planar),先是Y分量,再依次是U分量,V分量

这种格式很常用,在x264/265的中要求传入的源数据就是这种格式。在libyuv中,进行YUV图像处理(缩放,剪切,旋转)也是要求以这种格式传入。ffmpeg解码h264/265后数据也是这种格式。这种格式也可以直接通过D3D,OpenGL进行渲染。

计算占用的字节大小

一个分量占用一个字节,每一个象素点对应一个Y分量,四分之一个U分量,四分之一个V分量。所以分辨率为w*h的I420格式,Y的字节数为 w*h, U的字节数为w*h/4,V的字节数大小为w*h/4,总字节数即为w*h*3/2

定位像素数据

要处理I420的数据,首先要能定位到像素分量数据。一个典型的场景是,通过freetype在YUV图像上加字幕时,这是需要将指定坐标点的像素替换为freetype返回的字体图数据。

那么下面是取像素点YUV(I420格式)分量数据的公式(Planar存储方式):

size.total = size.width * size.height;
y = yuv[position.y * size.width + position.x];
u = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total];
v = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total + (size.total / 4)];

size.width/2为U分量和Y分量的步长

转一张很直观的I420存储的示意图。Y,U,V相同颜色的表述是同一像素的分量。可以结合这个图套用上面的公式推算一下:

一种常用的YUV数据表示方法

如果直接分配一段内存用以存储图像数据(比如I420格式),是没法知道这段内存的YUV分量特点的(每个分量的数据起始及长度)。那么我们可以下面这种方式定义数据结构来解释存储结构:

enum enImageFmt
{enImageFmt_YUV420P...
};struct ImageSize
{int iWidth;int iHeight;
};struct VideoFrame
{//Image的格式enImageFmt fmt;//图像的分辨率ImageSize Size;//分别指向Y,U,V分量的开头unsigned char *data[3];//分别指示Y,U,V分量一行(步长)数据大小unsigned short linesize[3];
}//如下的一个示例代码
//指针pImage指向一幅YUV420P格式的图像,通过该结构体指示它的内存结构VideoFrame frame;
frame.fmt = enImageFmt_YUV420P;
frame.Size.w = w;
frame.Size.h = h;
//Y分量的步长
frame.linesize[0] = w;
//U分量的步长(其长度就是Y分量步长的一半,同理V分量)
frame.linesize[1] = w/2;
//V分量的步长
frame.linesize[2] = w/2;//那么data[0]指向的就是Y数据的起始
frame.data[0] = (unsigned char*)pImage;
//U数据的起始
frame.data[1] = frame.data[0] + frame.linesize[0]*h;
//V数据的起始
frame.data[2] = frame.data[1] + frame.linesize[1]*h/2;

该结构体不止可以指示YUV420P的结构,也可以指示其它YUV格式的结构。在ffmpeg中也有类型的结构定义。

总结:

虽然主要是讲解的如果处理I420格式,但是前面介绍了几种不同YUV的存储格式。可以结合存储示意图,类推出如何处理其它YUV格式数据。

参考

https://zh.wikipedia.org/wiki/YUV

https://www.cnblogs.com/azraelly/archive/2013/01/01/2841269.html

彻底弄懂I420格式相关推荐

  1. 程序员,想要彻底弄懂Redis,这15点你一定要明白~(纯干货)

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:Java实现QQ登录和微博登录个人原创+1博客:点击前往,查看更多 作者:耿直的小码农 来源:https://s ...

  2. 一文弄懂EnumMap和EnumSet

    文章目录 简介 EnumMap 什么时候使用EnumMap EnumSet 总结 一文弄懂EnumMap和EnumSet 简介 一般来说我们会选择使用HashMap来存储key-value格式的数据, ...

  3. ​Cookie 从入门到进阶:一文彻底弄懂其原理以及应用

    大家好,我是若川.持续组织了8个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步.同时极力推荐订阅我写的<学习源码整体架构系列& ...

  4. hwt字体转换ttf_五分钟教你弄懂了字体反爬是个啥

    今天的文章内容主要是关于字体反爬. 目前已知的几个字体反爬的网站是猫眼,汽车之家,天眼查,起点中文网等等. 以前也看过这方面的文章,今天跟个老哥在交流的时候,终于实操了一把,弄懂了字体反爬是个啥玩意. ...

  5. 前后落差大用什么词语_语文考题一共有五类:汉字类、词语类、句子类、阅读类、作文类,如果基础扎实,答题技巧弄懂了,哪一类都能拿高分!...

    期末考越来越近,孩子们也逐渐进入了紧张的复习中,扎实的基本功是成功的基础无可厚非,然而巧妙的答题技巧更能为孩子的努力锦上添花.今天跟着小编一起把下面的内容掌握住吧!  01  汉字类考题 汉字是阅读和 ...

  6. 5分钟弄懂语音识别技术原理

    5分钟弄懂语音识别技术原理 首先,我们知道声音实际上是一种波.常见的mp3.wmv等格式都是压缩格式,必须转成非压缩的纯波形文件来处理,比如Windows PCM文件,也就是俗称的wav文件.wav文 ...

  7. 【一文弄懂】优先经验回放(PER)论文-算法-代码

    [一文弄懂]优先经验回放(PER)论文-算法-代码 文章目录 [一文弄懂]优先经验回放(PER)论文-算法-代码 前言: 综合评价: 继续前言唠叨 per论文简述: 参考博客: 背景知识 A MOTI ...

  8. 彻底弄懂Python标准库源码(一)—— os模块

    目录 第1~22行 模块整体注释.nt与posix 第24~46行 模块引入._exists方法._get_exports_list方法 第48~97行 根据系统不同导入不同的方法和属性 第100~1 ...

  9. 计算机基础知识之Unicode-彻底弄懂 Unicode 编码

    彻底弄懂 Unicode 编码 前言 为什么要有编码? 大家需要明确的是在计算机里所有的数据都是字节的形式存储.处理的.我们需要这些字节来表示计算机里的信息.但是这些字节本身又是没有任何意义的,所以我 ...

最新文章

  1. 网络营销外包——网络营销外包新手如何理解优化对网络营销的重要性?
  2. 关于图片缩放的两种方式
  3. Oracle sql解析类型, 软解析和硬解析浅析
  4. 干货,师兄倾力推荐的14个实验心得
  5. vue-cli2.9.6 build项目无法访问资源 无法访问elementUI字体
  6. 在春意盎然的季节里初识GIT
  7. MongoDB via Dotnet Core数据映射详解
  8. [Linux] VIM 代码折叠
  9. 1286:怪盗基德的滑翔翼(错)
  10. html div数据替换,在contenteditable div中替换innerHTML
  11. 大数据之-Hadoop3.x_MapReduce_MapJoin案例需求分析---大数据之hadoop3.x工作笔记0133
  12. 小鹏汽车副总裁纪宇:坚持智能化技术自研,打造最深的护城河
  13. 文本数据抽取经验总结
  14. minecraft java_minecraft java版本下载
  15. Laravel5.5前后台分离
  16. centos服务器磁盘清理
  17. 0ctf Babyheap 2017
  18. hp linux 禁用u盘启动不了,笔记本被禁用U盘启动功能的bios设置解除方法
  19. Outlook2007 打不开EXCEL?
  20. 猜年龄python实现

热门文章

  1. 华为开发者联盟鸿蒙系统,公告 | 华为开发者联盟
  2. 构建统一平台消除“数据烟囱”“信息孤岛”
  3. 测试5g网速的软件排行榜,5G网速测试
  4. 使用C++访问Google API
  5. 机器学习数学笔记|大数定理中心极限定理矩估计
  6. 《GitHub入门与实践》读书笔记
  7. hs8545m5虚拟服务器,华为HS8545M光猫怎么开启路由功能
  8. 软件看门狗控制计算机重启,看门狗2打开后电脑重启(看门狗应用)
  9. 一个字典树问题--电话号码转化问题(POJ 1002 487-3279)
  10. 2d有限元计算机仿真,超导感应电机的建模与分析