【问题标题】:Function to convert YCbCr to RGB?将 YCbCr 转换为 RGB 的函数?
【发布时间】:2019-02-26 19:30:38
【问题描述】:

我有 8 位的 Y、Cb、Cr 值,你能给我一个简单的 C 函数,将它转换为 8 位的 R、G、B。

这是它的原型。

void convertYCbCrToRGB(
    unsigned char Y,
    unsigned char cg,
    unsigned char cb,
    unsigned char &r,
    unsigned char &g,
    unsigned char &b);

附言
我只是在寻找正确的转换公式。因为我发现它到处都不一样。即使我也是C,C++专家

【问题讨论】:

    标签: c graphics rgb


    【解决方案1】:

    问题来了,几乎每个人都混淆了 YCbCr YUV 和 YPbPr。所以你能找到的文学作品往往很糟糕。首先,您必须知道您是否真的患有 YCbCr,或者是否有人对您撒谎:-)。

    • YUV 编码数据来自模拟源(PAL 视频解码器、S-Video...)
    • YPbPr 编码数据也来自模拟源,但作为 YUV(分量视频)产生更好的色彩效果
    • YCbCr 编码数据来自数字源(DVB、HDMI 等)

    YPbPr 和 YCbCr 是相关的。以下是正确的公式:

    https://web.archive.org/web/20180421030430/http://www.equasys.de/colorconversion.html

    (已添加 archive.org 以修复旧链接)。

    【讨论】:

    • 非常非常有用的链接。谢谢你。
    • 我已将链接更新为互联网存档版本@GaryO
    【解决方案2】:

    这是我的问题的解决方案。
    这是全范围 YCbCr 到 RGB 的转换例程。

    Color GetColorFromYCbCr(int y, int cb, int cr, int a)
    {
     double Y = (double) y;
     double Cb = (double) cb;
     double Cr = (double) cr;
    
     int r = (int) (Y + 1.40200 * (Cr - 0x80));
     int g = (int) (Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80));
     int b = (int) (Y + 1.77200 * (Cb - 0x80));
    
     r = Max(0, Min(255, r));
     g = Max(0, Min(255, g));
     b = Max(0, Min(255, b));
    
     return Color.FromArgb(a, r, g, b);
    }
    

    【讨论】:

    • 我认为转换是自动的,所以不需要明确。很好的解决方案。
    【解决方案3】:

    YCbCr 的 ITU-R 标准的整数运算是 (from Wikipedia)

    Cr = Cr - 128 ;
    Cb = Cb - 128 ;
    r = Y + ( Cr >> 2 + Cr >> 3 + Cr >> 5 ) ;
    g = Y - ( Cb >> 2 + Cb >> 4 + Cb >> 5) - ( Cr >> 1 + Cr >> 3 + Cr >> 4 + Cr >> 5) ;
    b = Y + ( Cb + Cb >> 1 + Cb >> 2 + Cb >> 6) ;
    

    或等效但更简洁:

    Cr = Cr - 128 ;
    Cb = Cb - 128 ;
    r = Y + 45 * Cr / 32 ;
    g = Y - (11 * Cb + 23 * Cr) / 32 ;
    b = Y + 113 * Cb / 64 ;
    

    不要忘记将 r、g 和 b 的值限制在 [0,255] 内。

    【讨论】:

    • 我认为第三行是不正确的。它应该是: r = Y + ( Cr + Cr >> 2 + Cr >> 3 + Cr >> 5 ) ;
    【解决方案4】:

    看看这个page。它包含有关转换公式的有用信息。

    顺便说一句,您可以返回一个 unsigned int 值,其中包含从最高有效字节到最低有效字节编码的 RGBA 值,即

    unsigned int YCbCrToRGBA(unsigned char Y, unsigned char Cb, unsigned char Cb) {
       unsigned char R = // conversion;
       unsigned char G = // conversion;
       unsigned char B = // conversion;
    
       return (R << 3) + (G << 2) + (B << 1) + 255;
    }
    

    【讨论】:

    • 我只在寻找正确的转换论坛。因为我发现它到处都不一样。即使我也是 C、C++ 方面的专家。 :-)
    • 我指给你的网站非常明确,但我知道你从哪里来关于色彩空间转换的不同观点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    相关资源
    最近更新 更多