Duanxx的HEVC学习(一)输入视频文件YUV文件的分析

来源:互联网 发布:淘宝信誉评级怎么提升 编辑:程序博客网 时间:2024/06/06 02:47

转自:http://blog.csdn.net/daunxx/article/details/37959831

目录(?)[+]

一 什么是YUV文件

         Y'UV的发明是由于彩色电视黑白电视的过渡时期。黑白视讯只有Y(Luma,Luminance)视讯,也就是灰阶值。到了彩色电视规格的制定,是以YUV/YIQ的格式来处理彩色电视图像,把UV视作表示彩度的C(ChrominanceChroma),如果忽略C信号,那么剩下的Y(Luma)信号就跟之前的黑白电视信号相同,这样一来便解决彩色电视机与黑白电视机的相容问。YYV文件实际上是将RGB文件拆解成了亮度和色度信息保存,Y'UV最大的优点在于只需占用极少的带宽

         RGB文件最大的问题是RGB的视频文件难以操作,如果我希望降低视频文件的亮度,RGB文件必须同时处理RGB三色,并且在数据上会存在失真,为了解决这个问题,YCbCr形式的文件就诞生了,Y是亮度频道(luminance channel),Cb是蓝色色度频道(Bluechannel),Cr是红色色度频道(Red channel)。

 


1.1 YUV文件的采样方式

         YUV文件的色度频道的采样频率是可以比亮度频道的采样频率低的,但不会明显的降低视觉质量,于是乎就有一种用于描述YUV文件的采样频率比的方法A:B:C

l  444代表没有亮度和色度都没有下采样

l  422表示2:1的水平下采样,但是没有垂直下采样。每行扫描都含有4个Y采样点,2个U采样点和两个V采样点。即,在水平方向的隔行采样,垂直方向全采样。

l  420表示2:1的水平下采样和2:1的垂直下采样。每行扫描都好友4个Y采样点,1个U采样点和一个V采样点。即,在水平方向隔行采样,垂直方向也隔行采样。



1.2YUV文件的存储方式

对于8bit深度的数据而言,一个字节就是一个采样点。10bit或者12bit的数据深度,则需要两个字节来存储一个采样点,此时低位优先,最低有效位数据对齐。即:Y[0]Y[1]表示一个Y采样数据,那么其值为Y[1]*256+Y[0]。

         YUV文件的存储方式指的是YUV文件中YUV数据在其Byte System中的排布或者说位置。YUV文件的数据存储方式有两种Packed format和 Planarformat。

         在Packed format中,YUV文件的Y/U/V数据打包在了一起,依次存放,如下图所示。


         在Planar format中,YUV的文件存放是分开的,先存放一帧图片的Y数据,然后存放UV数据。

IMC4,i420格式的文件存放方式:Y + U + V


IMC2、YV12的存放方式:Y + V + U





1.3 YUV和RGB之间的转换

从RGB到YUV:


从YUV到RGB:


以矩阵表示法(matrix representation),可得到公式:







二 HEVC标准测试视频文件分析

         HEVC标准测试文件有很多,此处对BasketballDrill_832x480_50.yuv分析其文件格式。

         此文件的分辨率为832x480,文件数据深度为8bit,文件格式为420,总帧数为501帧。

         在这里我用了两个软件:Elecard和Binary Viewer

         首先用Binary Viewer打开该文件:


         其文件大小为300119040字节

         计算YUV数据量:(832*480 + 832*480/4 + 832*480/4)*501 =  300119040

         由此可以看出,YUV文件全部是数据,此处就有一个疑惑,它的文件格式,文件名等等信息怎么存储的呢?有二进制查看器打开其他的文件,比如一个图片什么的,都会找到文件格式、文件名之类的东西,但是YUV文件却什么都没有,只有数据,真心不理解。

         再用Elecard,以YV12显示的方式打开该文件,并查看其144*15那个点的数据。


         由图中可以看到,红色框中的UV值都是一样的,因为是420采样,横向和纵向都下采样了,在从420转换成444时,直接填充。所以才会出现一个2*2的块中的UV值都是一样的。且下标都是从0开始,所以:

Y的位置为:832*15+145 = 12625

U的位置为:832*480 + 832/2*(15-1)/2 + 144/2 +1 =402345

V的位置为:832*480 + 832*480/4 + 832/2*(15-1)/2 + 144/2 +1 = 502185

         从Binary Viewer定位到这些位置,便可以查看到相应的值。需要注意两点,Binary Viewer中的下标是从0开始的,所以在定位时,需要减1;并且,上面是YV12打开的,所以UV的位置反了。


 

三 Matlab读取一个YUV文件并查看

         此处我读取了一帧的数据,然后将YUV420转为YUV44最后转为RGB显示出来:

[html] view plaincopy
  1. fid=fopen('BasketballDrill_832x480_50.yuv','rb');  
  2. width = 832  
  3. height = 480  
  4.    
  5. %% Read a yuv file ,thefile format is i420  
  6. Y = fread(fid,[width,height],'uint8');  
  7. U = fread(fid,[width/2,height/2],'uint8');  
  8. V = fread(fid,[width/2,height/2],'uint8');  
  9.    
  10. %% inital memory for yuv444  
  11. YY=zeros(width,height,'uint8');  
  12. UU=zeros(width,height,'uint8');  
  13. VV=zeros(width,height,'uint8');  
  14.    
  15. %% fill the empty of yuv444in U and V  
  16. UU(1:2:width-1,1:2:height-1)=U(:,:);  
  17. UU(1:2:width-1,2:2:height)=U(:,:);  
  18. UU(2:2:width,1:2:height-1)=U(:,:);  
  19. UU(2:2:width,2:2:height)=U(:,:);  
  20. VV(1:2:width-1,1:2:height-1)=V(:,:);  
  21. VV(1:2:width-1,2:2:height)=V(:,:);  
  22. VV(2:2:width,1:2:height-1)=V(:,:);  
  23. VV(2:2:width,2:2:height)=V(:,:);  
  24.    
  25. %% transform the yuv444 toRGB,and show the picture  
  26. YUV444=cat(3,Y',UU',VV');  
  27. RGB=ycbcr2rgb(YUV444);  
  28. imshow(RGB)  

最后显示的图像如图所示:


在U/V都为0时的图像:

只有U为0时的图像:


只有V为0的图像:


0 0
原创粉丝点击