Функция конвертировать YCbCr в RGB? - PullRequest
2 голосов
/ 28 октября 2010

У меня есть значения Y, Cb, Cr по 8 бит, можете ли вы дать мне простую функцию C, которая преобразует ее в R, G, B, каждый из 8 бит.

Вот ее прототип.

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

PS
Я ищу только правильную формулу преобразования.Потому что я везде нахожу это по-другому.Даже я также эксперт в C, C ++

Ответы [ 4 ]

8 голосов
/ 28 октября 2010

Проблема в том, что почти все путают YCbCr YUV и YPbPr.Таким образом, литература, которую вы можете найти, часто дерьмовая.Прежде всего вы должны знать, действительно ли у вас YCbCr или кто-то вам врет: -).

  • YUV-кодированные данные поступают из аналоговых источников (видеодекодер PAL, S-Video, ...) *Кодированные данные 1004 *
  • YPbPr также поступают из аналоговых источников, но дают лучшие цветовые результаты, поскольку YUV (компонентное видео)
  • Кодированные данные YCbCr поступают из цифровых источников (DVB, HDMI, ...)

YPbPr и YCbCr связаны между собой.Вот правильные формулы:

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

(добавлен archive.org для исправления старой, неработающей ссылки).

7 голосов
/ 28 октября 2010

Вот мое решение моего вопроса.
Это программа полного преобразования 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 голосов
/ 28 октября 2010

Проверьте эту страницу .Он содержит полезную информацию о формулах преобразования.

Кроме того, вы можете вернуть целое число без знака со значениями для 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;
}
2 голосов
/ 11 марта 2013

Целочисленная работа стандарта МСЭ-R для YCbCr составляет ( из Википедии )

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].

...