YUV格式分析

来源:互联网 发布:2016淘宝市场份额 编辑:程序博客网 时间:2024/04/28 14:52
本文非笔者原创,原文转载自:http://www.cnblogs.com/armlinux/archive/2012/02/15/2396763.html


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 按字节序分为 IMC1 和IMC2

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.

 HorizontalVerticalY Sample Period11V Sample Period22U Sample Period22

   

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

0 0