YUV视频格式分析

Andrew Huang <bluedrum@163.com> 转载请注明作者及联络方式
在摄像头之类编程经常是会碰到YUV格式,而非大家比较熟悉的RGB格式. 我们可以把YUV看成是一个RGB的变种来理解.

YUV的原理是把亮度与色度分离,研究证明,人眼对亮度的敏感超过色度。利用这个原理,可以把色度信息减少一点,人眼也无法查觉这一点。

YUV三个字母中,其中"Y"表示明亮度(Lumina nce或Luma),也就是灰阶值;而"U"和"V"表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。用这个三个字母好象就是通道命令。


使用YUV的优点有两个:
一.彩色YUV图像转黑白YUV图像转换非常简单,这一特性用在于电视信号上。

二.YUV是数据总尺寸小于RGB格式

关于描述YUV格式,写得比较好是这一篇文件
<<Video Rendering with 8-Bit YUV Formats>>
http://msdn.microsoft.com/en-us/library/aa904813(VS.80).aspx


一.YUV格式与RGB格式的换算


关于YUV与RGB转换

可以参见  http://www.fourcc.org/fccyvrgb.php

以下是标准公式
  1. RGB 转换成 YUV
  2. Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
  3. Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
  4. Cb = U = -( 0.148 * R) - (0.291 * G) + (0.439 * B) + 128
  5. YUV 转换成 RGB
  6. B = 1.164(Y - 16) + 2.018(U - 128)
  7. G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
  8. R = 1.164(Y - 16) + 1.596(V - 128)

RGB取值范围均为0~255,Y=0~255,U=-122~+122,V=-157~+157
以下是经过简化的公式,运算量比上述公式要小一些。

  1. RGB转YUV
  2. Y = 0.299R + 0.587G + 0.114B
  3. U'= (BY)*0.565
  4. V'= (RY)*0.713
  5. YUV转RGB
  6. R = Y + 1.403V'
  7. G = Y - 0.344U' - 0.714V'
  8. B = Y + 1.770U'

如果只有Y信号分量而没有U、V分量,那么这样表示的图像就是黑白灰度图像。因此用YUV格式由彩色转
黑白信号相当简单. 
在技术文档里,YUV经常有另外的名字, YCbCr ,其中Y与YUV 中的Y含义一致,Cb , Cr 同样都指色彩,,只是在表示方法上不同而已,Cb Cr 就是本来理论上的“分量/色差”的标识。C代表分量(是component的缩写)Cr、Cb分别对应r(红)、b(蓝)分量信号,Y除了g(绿)分量信号,还叠加了亮度信号。

还有一种格式是YPbPr格式,它与YCbPr格式的区别在于,其中YCbCr是隔行信号,YPbPr是逐行信号。
数字信号都是YCbCr ,其应用领域很广泛,JPEG、MPEG均采用此格式。在后文中,如无特别指明,讲的YUV都是指YCbCr格式。

而YPbPr一般是模拟信号,我引用两段来说明两者区别
  1.   什么是YCbCr?
  2.   YCbCr表示隔行分量端子,是属于YUV经过缩放和偏移的翻版,常说的YUV也称作YCbCr。其中Y与YUV 中的Y含义一致,Cb , Cr 同样都指色彩,,只是在表示方法上不同而已,Cb Cr 就是本来理论上的“分量/色差”的标识。C代表分量(是component的缩写)Cr、Cb分别对应r(红)、b(蓝)分量信号,Y除了g(绿)分量信号,还叠加了亮度信号。
  3.   其中YCbCr是隔行信号,YPbPr是逐行信号。YCbCr 是在计算机系统中应用最多的一种信号,其应用领域很广泛,JPEG、MPEG均采用此格式。
  4.   什么是YPbPr?
  5.   Y'CbCr 在模拟分量视频(analog component video)中也常被称为YPbPr,YPbPr是将模拟的Y、PB、PR信号分开,使用三条线缆来独立传输,保障了色彩还原的准确性,YPbPr表示逐行扫描色差输出.YPbPr接口可以看做是S端子的扩展,与S端子相比,要多传输PB、PR两种信号,避免了两路色差混合解码并再次分离的过程,也保持了色度通道的最大带宽,只需要经过反矩阵解码电路就可以还原为RGB三原色信号而成像,这就最大限度地缩短了视频源到显示器成像之间的视频信号通道,避免了因繁琐的传输过程所带来的图像失真,保障了色彩还原的准确,目前几乎所有大屏幕电视都支持色差输入。

二.YUV的存储格式
RGB格式中,一个24bpp像素要占用4字节空间。在YUV格式中,可以对于UV分量的数据压缩,但是对图像整体质量影响不大,这样YUV所占的空间就比RGB要小一些
不过RGB中 16bpp的 565格式每一个点只占2个字节,从这一点看也没有省多少。不过视频应用都是清一色的YUV应用。因此YUV的处理还是一个比较重要课题。

YUV的存储中与RGB格式最大不同在于,RGB格式每个点的数据是连继保存在一起的。即R,G,B是前后不间隔的保存在2-4byte空间中。而YUV的数据中为了节约空间,U,V分量空间会减小。每一个点的Y分量独立保存,但连续几个点的U,V分量是保存在一起的,(反正人眼一般也看不出区别).这几个点合起来称
为macro-pixel, 这种存储格式称为Packed格式。
另外一种存储格式是把一幅图像中Y,U,V分别用三个独立的数组表示。这种模式称为planar模式。

这里我们主要使用第一种Packed格式。

2.1 采样格式
表示YUV格式,一般用Y,U,V三者的比率来表示不同格式,比如YUV420 表示三者是比值此是 4:4:4
即一个点数据点,Y,U,V的空间都是一样大小。目前主要有如下比例,注意所有格式中Y比值都是4,占一个字节,表示没有减少采样。不同格式中,减小只是UV的采样值.

  • 4:4:4 表示色度值(UV)没有减少采样。即Y,U,V各占一个字节,加上Alpha通道一个字节,总共占4字节.这个格式其实就是24bpp的RGB格式了。
  • 4:2:2 表示UV分量采样减半,比如第一个像素采样Y,U,第二个像素采样Y,V,依次类推,这样每个点占用2个字节.二个像素组成一个宏像素.
  • 4:2:0  这种采样并不意味着只有Y,Cb而没有Cr分量,这里的0说的U,V分量隔行才采样一次。比如第一行采样 4:2:0 ,第二行采样 4:0:2 ,依次类推...在这种采样方式下,每一个像素占用16bits或10bits空间.
  • 4:1:1 可以参考4:2:2分量,是进一步压缩,每隔四个点才采一次U和V分量。一般是第0点采Y,U,第1点采Y,第3点采YV,第四点采Y,依次类推。

除了4:4:4采样,其余采样后信号重新还原显示后,会丢失部分UV数据,只能用相临的数据补齐,但人眼对UV不敏感,因此总体感觉损失不大。
4:2:2示例
如果原始数据三个像素是 Y0 U0 V0 ,Y1 U1 V1,Y2 U2 V2,Y3 U3 V3
经过4:2:2采样后,数据变成了 Y0 U0 ,Y1 V1 ,Y2 U2,Y3 V3
如果还原后,因为某一些数据丢失就补成 Y0 U0 V1,Y1 U0 V1,Y2 U2 V3 ,Y3 U3 Y2

  4:1:1示例
   原来四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
存放的码流为:    Y0 U0     ,Y1 , Y2  V2,   Y3
还原出像素点为:[Y0 U0 V2] [Y1 U0 V2] [Y2 U0 V2] [Y3 U0 V2]
  4:2:0示例
下面八个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] [Y5 U5 V5] [Y6 U6 V6] [Y7U7 V7] [Y8 U8 V8]
存放的码流为:  Y0 U0 ,Y1, Y2 U2, Y3 ,Y5 V5, Y6, Y7 V7, Y8
映射出的像素点为:[Y0 U0 V5] [Y1 U0 V5] [Y2 U2 V7] [Y3 U2 V7] [Y5 U0 V5] [Y6 U0 V5] [Y7U2 V7] [Y8 U2 V7]


YUV 4:4:4格式内存布局,每一个像素拥有完整的YUV,加上A(Alpha)

YUV 4:2:2 小端字节序排列

2.2 Four CC 码
关于YUV444,YUV422,YUV420的名称还有别外一种命名方式,FOURCC 码,上文中用就是这个命令,这Four CC使用四个字母的命名,
   FourCC全称Four-Character Codes,是由4个字符(4 bytes)组成,是一种独立标示视频数据流格式的四字节,在wav、avi档案之中会有一段FourCC来描述这个AVI档案,是利用何种codec来编码的。因此wav、avi大量存在等于“IDP3”的FourCC
  http://zh.wikipedia.org/wiki/FourCC

按fourcc的命名.
http://www.fourcc.org/yuv.php

YUV444 的FourCC 称为 AYUV
YUV422 的FourcCC 按字节序分为 YUY2 和UYVY
YUV420 的FourcCC 按字节序分为 IMC1IMC2

2.3 V4L2 采用编码
我们一般是在V4L驱动里使用这一些编码,而且V4L2也有一类对应的编码.参见vedio2dev.h,在编程中要与实际排列对应上.它后面的定义值实际就是FourCC 码.

#define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y', 'V', '1', '2') /* 12  YVU 4:2:0     */
#define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2     */
#define V4L2_PIX_FMT_UYVY    v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16  YUV 4:2:2     */
#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16  YVU422 planar */
#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16  YVU411 planar */
#define V4L2_PIX_FMT_Y41P    v4l2_fourcc('Y', '4', '1', 'P') /* 12  YUV 4:1:1     */
#define V4L2_PIX_FMT_YUV444  v4l2_fourcc('Y', '4', '4', '4') /* 16  xxxxyyyy uuuuvvvv */
#define V4L2_PIX_FMT_YUV555  v4l2_fourcc('Y', 'U', 'V', 'O')
比如在CMOS摄像头里 支持
V4L2_PIX_FMT_YVU420 ,它对应的是YV12 格式,查相应文档,它是Plane格式,即Y,U,V分三个区排列
YV120x32315659128 bit Y plane followed by 8 bit 2x2 subsampled V and U planes.

This is the format of choice for many software MPEG codecs. It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes.

 HorizontalVertical
Y Sample Period11
V Sample Period22
U Sample Period22

 

Positive biHeight implies top-down image (top line first)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/403830.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自定义ant中table表格的展开图标 修改ant-vue-design中嵌套表格table的expandIcon自定义图标

效果&#xff1a; 1. <a-table:expandIcon"expandIcon":loading"loading":columns"columns":data-source"data"class"components-table-demo-nested"change"onChangeTable":scroll"{x:1300,y:y}":p…

Foundationd和Application Kit的类层次

Foundationd类 Application Kit类 转载于:https://www.cnblogs.com/ikodota/archive/2012/08/01/2618590.html

python多线程编程(1): python对多线程的支持

From: http://www.cnblogs.com/holbrook/archive/2012/03/01/2376408.html 前面介绍过多线程的基本概念&#xff0c;理解了这些基本概念&#xff0c;掌握python多线程编程就比较容易了。 在开始之前&#xff0c;首先要了解一下python对多线程的支持。 虚拟机层面 Python虚拟机…

三个数从小到大排序

描述 现在要写一个程序&#xff0c;实现给三个数排序的功能 输入输入三个正整数 输出给输入的三个正整数排序 样例输入20 7 33 样例输出 7 20 33 测试代码 1 #include "stdio.h"2 3 int main()4 {5 int a, b, c, t;6 scanf("%d%d%d", &a, &…

监听vuex的某条数据

需要现在计算属性里获取 computed: {tabType: {get() {return this.$store.state.tabType;},set(val) {this.$store.state.tabType val;},}},watch: {tabType(val) {this.allType this.$store.state.tabType;}, }

dup和dup2的使用方法

/*本文通过标准输出的重定向和恢复的过程来解释dup和dup2的使用方法*/#include <stdio.h> #include <unistd.h>#include <fcntl.h>//STDIN_FILENO标准输入描述符&#xff08;0&#xff09;//STDOUT_FILENO标准输出描述符&#xff08;1&#xff09; //STDERR_…

django时间问题和时区设置

django里默认设置了一个时区&#xff0c;我在django里调time获取时间&#xff0c;与系统时间出现不一致的情况&#xff0c;所以我们需要重启设置时区&#xff0c;如下&#xff1a;在settings.py里面把TIME_ZONE设为&#xff1a;Etc/GMT-8 转载于:https://blog.51cto.com/linuxs…

python多线程编程(2): 线程的创建、启动、挂起和退出

From: http://www.cnblogs.com/holbrook/archive/2012/03/02/2376940.html 如上一节&#xff0c;python的threading.Thread类有一个run方法&#xff0c;用于定义线程的功能函数&#xff0c;可以在自己的线程类中覆盖该方法。而创建自己的线程实例后&#xff0c;通过Thread类的…

记录ie下报XMLHttpRequest: 网络错误 0x80070005, 拒绝访问。

问题&#xff1a; 同样的调用接口&#xff0c;在谷歌是没有问题的&#xff0c;但是在ie下报错XMLHttpRequest: 网络错误 0x80070005, 拒绝访问。 1.分析&#xff1a; 对比了一下&#xff0c;相同的是接口传递参数错误导致报错&#xff0c;传递的参数自动带上了 " "…

getopt和getopt_long函数

平时在写程序时常常需要对命令行参数进行处理&#xff0c;当命令行参数个数较多时&#xff0c;如果按照顺序一个一个定义参数含义很容易造成混乱&#xff0c;而且如果程序只按顺序处理参数的话&#xff0c;一些“可选参数”的功能将很难实现。 在Linux中&#xff0c;我们可以使…

MVC3.0+DWZ探索

将themes 文件移到 js文件 index.html 转载于:https://www.cnblogs.com/acyy/archive/2012/08/03/2621594.html

棋盘覆盖

在一个2k x 2k ( 即&#xff1a;2^k x 2^k )个方格组成的棋盘中&#xff0c;恰有一个方格与其他方格不同&#xff0c;称该方格为一特殊方格&#xff0c;且称该棋盘为一特殊棋盘。在棋盘覆盖问题中&#xff0c;要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外…

VMM2012应用指南之12- 创建自助服务用户并分配云

河北经贸大学 王春海如果要在云中创建、管理虚拟机&#xff0c;首先要创建自助服务帐户&#xff0c;在创建用户角色的同时即可以分配云。本节介绍这部分内容。【说明】在做下面的这个操作的时候&#xff0c;需要向“库”服务器再添加另外一个库的路径&#xff0c;用于保存云中的…

分隔符字符串处理(strtok与strsep区别)

1、strtok原型与应用原型&#xff1a;char *strtok(char *src, const char *delim);功能&#xff1a;将src(原字符串)根据delim(分隔符串)分解为不同子串&#xff08;连续算一个&#xff09;返回&#xff1a;属于当前分割的子串&#xff0c;当前没有分割的子串时返回NULL#inclu…

解决vue项目在ie浏览器下白屏问题;ie运行项目报正在兼容性是图中运行,因为选中了“在兼容性视图中显示Intranet站点”

如果已经配置了babel-polyfill&#xff0c;在ie下依然白屏&#xff0c;打开控制台刷新&#xff0c;看看是否报 正在兼容性是图中运行&#xff0c;因为选中了“在兼容性视图中显示Intranet站点” 如图 解决方案 在ie浏览器—设置—兼容性视图设置&#xff08;B&#xff09;…

第六次java作业

package choujiang; import java.util.ArrayList; import java.util.Collections; import java.util.Random; public class ChouJiang { private ArrayList List; public void deal(){ //向List容器中顺序添加指定数量num的整数 if (List null){ List new ArrayList(); for(i…

自已脚本开发常用的底层方法

脚本下载地址&#xff1a;/Files/cocoxye/winBasics.rar 仅适用于原生脚本开发&#xff0c;同jquery会有冲突&#xff0c;主要存在于$选择器上。 常用变量 docdocument doedoc.documentElement sliceArray.prototype.slice Ie是否为IE浏览器 Ie6是否为IE6浏览器 webkit是否为we…

python多线程编程(4): 死锁和可重入锁

From: http://www.cnblogs.com/holbrook/archive/2012/03/08/2385449.html 在线程间共享多个资源的时候&#xff0c;如果两个线程分别占有一部分资源并且同时等待对方的资源&#xff0c;就会造成死锁。尽管死锁很少发生&#xff0c;但一旦发生就会造成应用的停止响应。下面看一…

ie浏览器跨域报错问题;Access-Control-Allow-Headers 列表不存在请求表头 content-type;XMLHTTPRequest:网络错误 0x80070005,拒绝访问。

问题&#xff1a; 这段是我在main.js下设置的&#xff0c;为了在请求头上添加后端需要的参数sessionId 和xrequestedwith &#xff0c;在谷歌下是正常的&#xff0c;ie报Access-Control-Allow-Headers 列表不存在请求表头 content-type&#xff1b;XMLHTTPRequest:网络错误 0x…