我该如何解决这个YCrCb – > RBG转换公式?

我使用这个问题的公式:

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公式 。

在这里输入图像说明

但是我认为这个公式并不完全正确,因为输出图像如下所示:

我实际上并没有绿发

我如何修复这个公式?

假设第一次计算的最大值( 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; 

这导致(假设ycr最大值)为480 ,这也导致截断。

编辑2

据说build议使用以下等式:

方程

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

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

这导致(假定ycr最大值)为480 (在编辑1中相同的答案)的值,这也导致截断。

编辑3

查看@Robert的答案以获得完整的解决scheme。

编辑4

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

在@Fiddling位帮助。 更正后的代码如下所示:

 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);