如何修复此YCrCb - > RBG转换公式?

Rob*_*ert 5 c image colors image-processing ios

我正在使用这个问题的公式:

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;
Run Code Online (Sandbox Code Playgroud)

我假设它基于维基文章中的ITU-R_BT.601公式.

在此输入图像描述

但是我觉得公式不太对,因为输出图像看起来像这样:

我其实没有绿头发

我该如何修复配方?

Fid*_*its 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
Run Code Online (Sandbox Code Playgroud)

rgbOutput[0]可以容纳的最大值是255。您尝试分配684给它,导致截断。实际分配给它的值为172( 0xAC)。

编辑1

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

rgbOutput[0] = ((298 * y) >> 8) + ((409 * cr) >> 8) - 223;
Run Code Online (Sandbox Code Playgroud)

这会产生 的值(假设ycr的最大值)480,这也会导致截断。

编辑2

据说推荐使用以下等式:

方程

使用这个,你的第一个计算应该是这样的:

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

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

编辑3

有关完整的解决方案,请参阅@Robert 的回答。

编辑4

y == 0和 时cr == 0,写入的值y也将导致截断,除非执行钳位。