我正在使用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。
但是我认为公式不太正确,因为输出图像如下所示:
如何修复公式?
答案 0 :(得分:4)
假设第一次计算的最大值(y == 255
和cr == 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
,从而导致截断。分配给它的实际值为172
(0xAC
)。
编辑1
根据您发布的公式,您的第一次计算应如下:
rgbOutput[0] = ((298 * y) >> 8) + ((409 * cr) >> 8) - 223;
这导致y
的值{假设cr
和480
的最大值),这也会导致截断。
编辑2
据说推荐以下等式:
使用此代码,您的第一次计算应该是这样的:
rgbOutput[0] = ((255 * (y - 16)) / 219) + ((179 * (cr - 128)) / 112;
这导致y
的值(假设cr
和480
的最大值)(编辑1中的相同答案),这也会导致截断。
编辑3
请参阅@Robert的回答以获得完整的解决方案。
编辑4
当y == 0
和cr == 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);