美文网首页视频iOS技术文章扩展眼界
音视频开发:RGB与YUV相互转换问题

音视频开发:RGB与YUV相互转换问题

作者: 熊皮皮 | 来源:发表于2016-07-19 10:51 被阅读2678次

    本文档描述了RGB与YUV两个颜色空间的相互转换问题。

    很多书在讲YUV颜色空间或YUV模型时,一般直接给出RGB与YUV的相互转换公式,比如这样:

    (1)RGB转换成YUV

    Y = 0.299R + 0.587G + 0.114B
    U = 0.567(B - Y)
    V = 0.713(R - Y)
    

    值得注意的是,Y值范围为[0, 1.0]、UV值范围都是[-0.5, 0.5],在Accelerate框架的vImage_CVUtilities.h有描述。

    (2)YUV转换成RGB

    R = Y + 1.402V
    G = Y - 0.344U - 0.714V
    B = Y + 1.772U
    

    对于JPEG图片,这两组公式的计算结果往往是正确的。然而,对于视频,这只处理了一种情况,即,这只是BT.601 Full Range转换矩阵。实际上,据我所知,还存在多个转换矩阵,部分转换矩阵可在GPUImage源码中找到应用。值得注意的是,GPUImage使用列矩阵存储。其中,ITU BT.601对应于标准分辨率电视(SDTV)、ITU BT.709对应于高分辨率电视(HDTV),几个常见的颜色转换矩阵分别是:

    • ITU BT.601 Full Range转换矩阵

      ITU BT.601 Full Range

    GLfloat kColorConversion601FullRangeDefault[] = {
    1.0, 1.0, 1.0,
    0.0, -0.343, 1.765,
    1.4, -0.711, 0.0,
    };

    
    - ITU BT.601默认转换矩阵
    
      ![ITU BT.601默认转换矩阵](http:https://img.haomeiwen.com/i1613657/c90e9ab3f9d8d8d9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    

    GLfloat kColorConversion601Default[] = {
    1.164, 1.164, 1.164,
    0.0, -0.392, 2.017,
    1.596, -0.813, 0.0,
    };

    
    - ITU BT.709默认转换矩阵
    
      ![ITU BT.709默认转换矩阵](http:https://img.haomeiwen.com/i1613657/dad726961c0f76d3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    

    GLfloat kColorConversion709Default[] = {
    1.164, 1.164, 1.164,
    0.0, -0.213, 2.112,
    1.793, -0.533, 0.0,
    };

    
    - ITU BT.709 Full Range转换矩阵
    
      留空
    
    由于OpenGL ES着色器中mat系列数据结构以列优先存储,意味着,**数据上传到着色器端将按列优先规则构造矩阵**,故GPUImage在保存转换矩阵时也以列矩阵表示。因此,在片段着色器中的计算为:
    
    

    yuv.x = texture2D(luminanceTexture, textureCoordinate).r;
    yuv.yz = texture2D(chrominanceTexture, textureCoordinate).rg - vec2(0.5, 0.5);
    rgb = colorConversionMatrix * yuv;

    
    以ITU BT.601 Full Range为例,kColorConversion601FullRangeDefault * yuv可得到:
    
    

    R = Y + 1.4V
    G = Y - 0.343U - 0.711V
    B = Y + 1.765U

    
    基本等于文档开始提及的转换公式,个别小数部分内容不太一样,怀疑是舍入或大家相互抄袭导致书写错误。
    
    其中,阐明了BT.601与BT.709的区别,这在很多书上是不作说明的,为刚接触视频开发的开发人员提供了参考。
    full range我之前了解是[0, 255],video range把人眼察觉不到的范围给去掉了
    
    
    **参考:**
    
    - 数字图像处理与机器视觉——Visual C++与Matlab实现(第二版)
    
    **推荐阅读:**
    
    - [YCbCr](https://en.wikipedia.org/wiki/YCbCr)
    - [R-REC-BT.709](https://www.itu.int/rec/R-REC-BT.709)

    相关文章

      网友评论

      • af1b65b6ce0e:yuv.yz = texture2D(chrominanceTexture, textureCoordinate).rg - vec2(0.5, 0.5);
        你这也写错了吧 应该是把rg改成ra才对

      本文标题:音视频开发:RGB与YUV相互转换问题

      本文链接:https://www.haomeiwen.com/subject/kvwpjttx.html