如何修复此YCbCr - > RGB转换公式?

时间:2014-08-08 19:23:57

标签: ios c image image-processing colors

我正在使用this question中的公式:

uint8_t *rgbBuffer = malloc(imageWidth * imageHeight * 3);

// .. iterate over height and width

// from ITU-R BT.601, rounded to integers
rgbOutput[0] = (298 * (y - 16) + 409 * cr - 223) >> 8;
rgbOutput[1] = (298 * (y - 16) + 100 * cb + 208 * cr + 136) >> 8;
rgbOutput[2] = (298 * (y - 16) + 516 * cb - 277) >> 8;

我假设它基于ITU-R_BT.601 formula in the wiki article

enter image description here

但是我认为公式不太正确,因为输出图像如下所示:

I don't actually have green hair

如何修复公式?

2 个答案:

答案 0 :(得分:4)

假设第一次计算的最大值(y == 255cr == 255):

rgbOutput[0] = (298 * (255 - 16) + 409 * 255 - 223) >> 8;
rgbOutput[0] = (298 * 239 + 104295 - 223) >> 8;
rgbOutput[0] = (71222 + 104295 - 223) >> 8;
rgbOutput[0] = 175294 >> 8; // 175294 == 0x2ACBE
rgbOutput[0] = 684; // 684 == 0x2AC

rgbOutput[0]可容纳的最大值为255。您正在尝试为其分配684,从而导致截断。分配给它的实际值为1720xAC)。

编辑1

根据您发布的公式,您的第一次计算应如下:

rgbOutput[0] = ((298 * y) >> 8) + ((409 * cr) >> 8) - 223;

这导致y的值{假设cr480的最大值),这也会导致截断。

编辑2

据说推荐以下等式:

equation

使用此代码,您的第一次计算应该是这样的:

rgbOutput[0] = ((255 * (y - 16)) / 219) + ((179 * (cr - 128)) / 112;

这导致y的值(假设cr480的最大值)(编辑1中的相同答案),这也会导致截断。

编辑3

请参阅@Robert的回答以获得完整的解决方案。

编辑4

y == 0cr == 0时,写入y的值也会导致截断,除非执行限定。

答案 1 :(得分:1)

在@Fiddling Bits的帮助下。更正后的代码如下:

uint8_t ClampIntToByte(int n) {
    n = n > 255 ? 255 : n;
    return n < 0 ? 0 : n;
}

rgbOutput[0] = ClampIntToByte(((298 * (y - 16) + 409 * cr) >> 8) - 223);
rgbOutput[1] = ClampIntToByte(((298 * (y - 16) - 100 * cb - 208 * cr) >> 8) + 136);
rgbOutput[2] = ClampIntToByte(((298 * (y - 16) + 516 * cb) >> 8) - 277);