将 YCbCr 转换为 RGB 的函数?

发布于 2024-09-29 07:36:23 字数 342 浏览 11 评论 0原文

我有 Y、Cb 和 Cr 值,每个值的大小均为 8 位。可以将这些值转换为 R、G、B(每个值均为 8 位)的简单 C 函数是什么?

这是我正在寻找的函数的原型:

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

PS 我只是在寻找正确的转换公式,因为我到处都找到了它的不同版本。我非常精通 C/C++。

I have Y, Cb and Cr values, each with a size of 8 bits. What would be a simple C function which can convert these values to R,G,B (each with a size of 8 bits)?

Here is a prototype of the function I am looking for:

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

P.S.
I am looking for the correct conversion formula only, since I have found different versions of it everywhere. I am very well-versed in C/C++.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凉月流沐 2024-10-06 07:36:23

问题来了,几乎每个人都混淆了 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 是为了修复旧的、损坏的链接)。

The problem comes that nearly everybody confuses YCbCr YUV and YPbPr. So literature you can find is often crappy. First you have to know if you really have YCbCr or if someone lies to you :-).

  • YUV coded data comes from analog sources (PAL video decoder, S-Video, ...)
  • YPbPr coded data also comes from analog sources but produces better color results as YUV (Component Video)
  • YCbCr coded data comes from digital sources (DVB, HDMI, ...)

YPbPr and YCbCr are related. Here are the right formulae:

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

(the archive.org has been added to fix the old, broken link).

缘字诀 2024-10-06 07:36:23

这是我对问题的解决方案。
这是全范围 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);
}

Here is my solution to my question.
This one is Full Range YCbCr to RGB conversion routine.

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);
}
可可 2024-10-06 07:36:23

YCbCr 的 ITU-R 标准的整数运算是(来自维基百科

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] 范围内。

Integer operation of ITU-R standard for YCbCr is (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) ;

or equivalently but more concisely to :

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

do not forget to clamp values of r, g and b within [0,255].

滥情空心 2024-10-06 07:36:23

查看此页面。它包含有关转换公式的有用信息。

顺便说一句,您可以返回一个 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;
}

Check out this page. It contains useful information on conversion formulae.

As an aside, you could return a unsigned int with the values for RGBA encoded from the most significant byte to least significant byte, i.e.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文