YUV格式分析与转换

via :

【视频处理】YUV与RGB格式转换
YUV格式分析
图文详解YUV420数据格式


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

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


使用YUV的优点有两个:
    一.彩色YUV图像转黑白YUV图像转换非常简单,这一特性用在于电视信号上。
    二.YUV是数据总尺寸小于RGB格式

关于描述YUV格式,写得比较好是这一篇文件 <<Video Rendering with 8-Bit YUV Formats>>

YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式。

因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式。

RGB取值范围均为0255,Y=0255,U=-122+122,V=-157+157

   // RGB 转换成 YUV
    Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
    Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
    Cb = U = -( 0.148 * R) - (0.291 * G) + (0.439 * B) + 128

    //YUV 转换成 RGB
    B = 1.164(Y - 16) + 2.018(U - 128)
    G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
    R = 1.164(Y - 16) + 1.596(V - 128)

//以下是经过简化的公式,运算量比上述公式要小一些。
    //RGB转YUV
    Y = 0.299R + 0.587G + 0.114B
    U'= (BY)*0.565
    V'= (RY)*0.713

   // YUV转RGB
    R = Y + 1.403V'
    G = Y - 0.344U' - 0.714V'
    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一般是模拟信号,我引用两段来说明两者区别

什么是YCbCr?

  YCbCr表示隔行分量端子,是属于YUV经过缩放和偏移的翻版,常说的YUV也称作YCbCr。其中Y与YUV 中的Y含义一致,Cb , Cr 同样都指色彩,,只是在表示方法上不同而已,Cb Cr 就是本来理论上的“分量/色差”的标识。C代表分量(是component的缩写)Cr、Cb分别对应r(红)、b(蓝)分量信号,Y除了g(绿)分量信号,还叠加了亮度信号。
  其中YCbCr是隔行信号,YPbPr是逐行信号。YCbCr 是在计算机系统中应用最多的一种信号,其应用领域很广泛,JPEG、MPEG均采用此格式。

什么是YPbPr?

  Y'CbCr 在模拟分量视频(analog component video)中也常被称为YPbPr,YPbPr是将模拟的Y、PB、PR信号分开,使用三条线缆来独立传输,保障了色彩还原的准确性,YPbPr表示逐行扫描色差输出.YPbPr接口可以看做是S端子的扩展,与S端子相比,要多传输PB、PR两种信号,避免了两路色差混合解码并再次分离的过程,也保持了色度通道的最大带宽,只需要经过反矩阵解码电路就可以还原为RGB三原色信号而成像,这就最大限度地缩短了视频源到显示器成像之间的视频信号通道,避免了因繁琐的传输过程所带来的图像失真,保障了色彩还原的准确,目前几乎所有大屏幕电视都支持色差输入。

基于OpenCV的实现

利用OpenCV提供的转换函数实现YUV到RGB的转换,实现简单方便。实现过程,只需要合理构造包含YUV数据的Mat,具体实现方法如下。

    Mat img = imread(imagename); // the newer cvLoadImage alternative, MATLAB-style function
    if(img.empty())
    {
        fprintf(stderr, "Can not load image %s\n", imagename.c_str());
        return -1;
    }

    if( img.empty() ) // check if the image has been loaded properly
        return -1;

    Mat img_yuv;
    cvtColor(img, img_yuv, COLOR_BGR2YCrCb); // convert image to YUV color space. The output image will be created automatically
	
    namedWindow("image with img_yuv", WINDOW_AUTOSIZE);      
    imshow("image with img_yuv", img_yuv);


PS. opencv 3.3.1 cvtColor 中是利用 lambada 并行处理



        case COLOR_BGR2YCrCb: case COLOR_RGB2YCrCb:
        case COLOR_BGR2YUV: case COLOR_RGB2YUV:
            CV_Assert( scn == 3 || scn == 4 );
            _dst.create(sz, CV_MAKETYPE(depth, 3));
            dst = _dst.getMat();
            hal::cvtBGRtoYUV(src.data, src.step, dst.data, dst.step, src.cols, src.rows,
                             depth, scn, swapBlue(code), code == COLOR_BGR2YCrCb || code == COLOR_RGB2YCrCb);



参考资料:
https://code.google.com/p/libyuv/

posted @ 2017-11-23 21:42  scott_h  阅读(874)  评论(0编辑  收藏  举报