【秒懂音视频开发】18_详解YUV
本文的主角是多媒体领域非常重要的一个概念:YUV。
简介
YUV,是一种颜色编码方法,跟RGB是同一个级别的概念,广泛应用于多媒体领域中。
也就是说,图像中每1个像素的颜色信息,除了可以用RGB的方式表示,也可以用YUV的方式表示。
vs RGB
对比RGB,YUV有哪些不同和优势呢?
体积更小
- 如果使用RGB
- 比如RGB888(R、G、B每个分量都是8bit)
- 1个像素占用24bit(3字节)
- 如果使用YUV
- 1个像素可以减小至平均只占用12bit(1.5字节)
- 体积为RGB888的一半
组成
RGB数据由R、G、B三个分量组成。
YUV数据由Y、U、V三个分量组成,现在通常说的YUV指的是YCbCr。
- Y:表示亮度(Luminance、Luma),占8bit(1字节)
- Cb、Cr:表示色度(Chrominance、Chroma)
- Cb(U):蓝色色度分量,占8bit(1字节)
- Cr(V):红色色度分量,占8bit(1字节)
兼容性
根据上面的1组图片,不难看出:
- Y分量对呈现出清晰的图像有着很大的贡献
- Cb、Cr分量的内容不太容易识别清楚
此外,你是否感觉:Y分量的内容看着有点眼熟?其实以前黑白电视的画面就是长这样子的。
YUV的发明处在彩色电视与黑白电视的过渡时期。
- YUV将亮度信息(Y)与色度信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的
- 这样的设计很好地解决了彩色电视机与黑白电视的兼容性问题,使黑白电视也能够接收彩色电视信号,只不过它只显示了Y分量
- 彩色电视有Y、U、V分量,如果去掉UV分量,剩下的Y分量和黑白电视相同
相互转换
RGB和YUV之间是可以相互转换的。
RGB转YUV
待补充
YUV转RGB
待补充
色度二次采样
原理
人眼的视网膜上,分布着两种感光细胞:视杆细胞和视锥细胞。
视杆细胞
- 感知光线的强弱
- 没有色彩识别功能
- 负责夜间非彩色视觉
视锥细胞
- 感知颜色
- 负责白天彩色视觉
- 如果你的视锥细胞发育不正常,数量太少,那感知颜色就会受阻,可能会导致你色弱
人眼中有上亿个感光细胞,其中视杆细胞占了95%,而视锥细胞仅占5%。
因此,人眼对亮度的敏感程度要高于对色度的敏感程度,人眼对于亮度的分辨要比对颜色的分辨精细一些。
如果把图像的色度分量减少一些,人眼也丝毫感觉不到变化和差异。
概念
如果在色度分量上进行(相对亮度分量)较低分辨率的采样,也就是存储较多的亮度细节、较少的色度细节,这样就可以在不明显降低画面质量的同时减小图像的体积。上述过程称为:色度二次采样(Chroma Subsampling)。
采样格式
采样格式通常用A:B:C的形式来表示,比如4:4:4、4:2:2、4:2:0等,其中我们最需要关注的是4:2:0。
- A:一块A*2个像素的概念区域
- B:第1行的色度采样数目
- C:第2行的色度采样数目
- C的值一般要么等于B,要么等于0
上图中,不管是哪种采样格式,Y分量都是全水平、全垂直分辨率采样的,每一个像素都有自己独立的Y分量。
4:4:4
- 第1行采集4组CbCr分量,第2行采集4组CbCr分量
- 每1个像素都有自己独立的1组CbCr分量
- Y分量与CbCr分量的水平方向比例是1:1(每1列都有1组CbCr分量)
- Y分量与CbCr分量的垂直方向比例是1:1(每1行都有1组CbCr分量)
- Y分量与CbCr分量的总比例是1:1
- 1个像素占用24bit(3字节),跟RGB888的体积一样
- 没有进行色度二次采样
叉叉代表:亮度。
圆圈代表:色度。
4:2:2
- 第1行采集2组CbCr分量,第2行采集2组CbCr分量
- 水平方向相邻的2个像素(1行2列)共用1组CbCr分量
- Y分量与CbCr分量的水平方向比例是2:1(每2列就有1组CbCr分量)
- Y分量与CbCr分量的垂直方向比例是1:1(每1行都有1组CbCr分量)
- Y分量与CbCr分量的总比例是2:1
- 1个像素平均占用16bit(2字节)
- 因为2个像素共占用32bit(4字节 = 2个Y分量 + 1个Cb分量 + 1个Cr分量)
4:2:0
- 第1行采集2组CbCr分量,第2行共享第1行的CbCr分量
- 相邻的4个像素(2行2列)共用1组CbCr分量
- Y分量与CbCr分量的水平方向比例是2:1(每2列就有1组CbCr分量)
- Y分量与CbCr分量的垂直方向比例是2:1(每2行就有1组CbCr分量)
- Y分量与CbCr分量的总比例是4:1
- 1个像素平均占用12bit(1.5字节)
- 因为4个像素共占用48bit(6字节 = 4个Y分量 + 1个Cb分量 + 1个Cr分量)
存储格式
存储格式,决定了YUV数据是如何排列和存储的。
分类
YUV的存储格式可以分为3大类:
- Planar
- Y、U、V分量分开单独存储
- 名称通常以字母p结尾
- Semi-Planar:Y分量单独存储,U、V分量交错存储
- 名称通常以字母sp结尾
- Packed
- 或者叫Interleaved
- Y、U、V分量交错存储
4:4:4
Planar
- I444
Y Y Y Y
Y Y Y Y
U U U U
U U U U
V V V V
V V V V
- YV24
Y Y Y Y
Y Y Y Y
V V V V
V V V V
U U U U
U U U U
Semi-Planar
- NV24
Y Y Y Y
Y Y Y Y
U V U V U V U V
U V U V U V U V
- NV42
Y Y Y Y
Y Y Y Y
V U V U V U V U
V U V U V U V U
4:2:2
Planar
- I422
Y Y Y Y
Y Y Y Y
U U
U U
V V
V V
- YV16
Y Y Y Y
Y Y Y Y
V V
V V
U U
U U
Semi-Planar
- NV16
Y Y Y Y
Y Y Y Y
U V U V
U V U V
- NV61
Y Y Y Y
Y Y Y Y
V U V U
V U V U
Packed
- UYVY
U Y V Y U Y V Y
U Y V Y U Y V Y
- YUYV
Y U Y V Y U Y V
Y U Y V Y U Y V
- YVYU
Y V Y U Y V Y U
Y V Y U Y V Y U
4:2:0
Planar
- I420
- 大多数视频解码器以I420格式输出原始图片
Y Y Y Y
Y Y Y Y
U U
V V
- YV12
Y Y Y Y
Y Y Y Y
V V
U U
Semi-Planar
- NV12
Y Y Y Y
Y Y Y Y
U V U V
- NV21
Y Y Y Y
Y Y Y Y
V U V U
【秒懂音视频开发】18_详解YUV的更多相关文章
- 【秒懂音视频开发】02_Windows开发环境搭建
音视频开发库的选择 每个主流平台基本都有自己的音视频开发库(API),用以处理音视频数据,比如: iOS:AVFoundation.AudioUnit等 Android:MediaPlayer.Med ...
- 【秒懂音视频开发】23_H.264编码
本文主要介绍一种非常流行的视频编码:H.264. 计算一下:10秒钟1080p(1920x1080).30fps的YUV420P原始视频,需要占用多大的存储空间? (10 * 30) * (1920 ...
- 【秒懂音视频开发】26_RTMP服务器搭建
从本节开始,正式开启流媒体相关的内容. 流媒体 基本概念 流媒体(Streaming media),也叫做:流式媒体. 是指将一连串的多媒体数据压缩后,经过互联网分段发送数据,在互联网上即时传输影音以 ...
- 【秒懂音视频开发】14_AAC编码
AAC(Advanced Audio Coding,译为:高级音频编码),是由Fraunhofer IIS.杜比实验室.AT&T.Sony.Nokia等公司共同开发的有损音频编码和文件格式. ...
- 【秒懂音视频开发】21_显示BMP图片
文本的主要内容是:使用SDL显示一张BMP图片,算是为后面的<播放YUV>做准备. 为什么是显示BMP图片?而不是显示JPG或PNG图片? 因为SDL内置了加载BMP的API,使用起来会更 ...
- 【秒懂音视频开发】05_Qt开发基础
控件的基本使用 为了更好地学习Qt控件的使用,建议创建项目时先不要生成ui文件. 打开mainwindow.cpp,在MainWindow的构造函数中编写界面的初始化代码. 窗口设置 MainWind ...
- 【秒懂音视频开发】12_播放WAV
对于WAV文件来说,可以直接使用ffplay命令播放,而且不用像PCM那样增加额外的参数.因为WAV的文件头中已经包含了相关的音频参数信息. ffplay in.wav 接下来演示一下如何使用SDL播 ...
- Python开发技术详解(视频+源码+文档)
Python, 是一种面向对象.直译式计算机程序设计语言.Python语法简捷而清晰,具有丰富和强大的类库.它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结 ...
- PyQt+moviepy音视频剪辑实战1:多个音视频合成顺序播放或同屏播放的视频文件实现详解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...
随机推荐
- 《C++ Primer》笔记 第2章 变量和基本类型
如果你的数值超过了int表示范围,选用long long 如果你需要使用一个不大的整数,那么明确指定它的类型是signed char或者unsigned char 执行浮点数运算选用double 当一 ...
- Java 程序员每天都在做什么?
作为一名 在大.中.小微企业都待过 的 Java 开发者,今天和大家分享下自己在不同公司的工作日常和收获.包括一些个人积累的工作提升经验,以及一些 Java 学习的方法和资源. 先从我的第一份 Jav ...
- WEBAPI 的调用方式
示例是调用谷歌短网址的API. 1. HttpClient方式 public static async void DoAsyncPost() { DateTime dateBegin = DateTi ...
- pytorch(12)ContainersAndAlexNet
containers graph LR A["Containers"] --> B["nn.Sequetial"] B["nn.Sequetia ...
- 关于MarkDown语法
Markdown语法 码云笔记链接:https://gitee.com/out_of_zi_wen/practical-experience/blob/master/Markdown%E8%AF%AD ...
- Java 面向对象 02
面向对象·二级 构造方法Constructor概述和格式 * A:构造方法概述和作用 * 给对象的数据(属性)进行初始化 * B:构造方法格式特点 * a:方法名与类名相同(大小也要与 ...
- golang调用shell命令(实时输出, 终止等)
背景 是这样的,最近在研究一个定时任务系统的改造,可能有点像jenkins做到的那种吧. 可以输入shell命令,也可以执行py脚本等等,相比之前来说,也要能够及时停止! 但是遇到了这么个问题,gol ...
- 越来越受欢迎的Vue想学么,90后小姐姐今儿来教你
摘要:Vue的相关技术原理成为了前端岗位面试中的必考知识点,掌握 Vue 对于前端工程师来说更像是一门"必修课". 本文原作者为尹婷,擅长前端组件库研发和微信机器人. 我们发现, ...
- C# 基础 - 日志捕获二使用 log4net
引入 log4net.dll 项目->添加->新建项->应用程序配置文件,命名为 log4net.config,并把属性的复制到输出目录设置为 如果较新则复制,后续客户端需要读取在 ...
- kubernetes生产实践之mongodb
简介 先看下生命周期图 kubedb支持的mongodb版本 [root@qd01-stop-k8s-master001 mysql]# kubectl get mongodbversions NAM ...