【问题标题】:How can I fix this YCrCb -> RBG conversion formula?如何修复这个 YCrCb -> RBG 转换公式?
【发布时间】:2014-10-02 08:49:13
【问题描述】:

我使用来自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

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

如何修正公式?

【问题讨论】:

  • 会不会是整数上溢/下溢问题?
  • 你的数组是什么类型的?
  • @FiddlingBits - 字节数组uint8_t *rgbBuffer = malloc(imageWidth * imageHeight * 3); 将添加到问题中。
  • +1 对问题的精彩介绍,引用了另一个问题的代码,尤其是显示问题所在的图像。

标签: ios c image image-processing colors


【解决方案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);

【讨论】:

  • 错过了上一题答案中的夹紧部分。很好的收获。
【解决方案2】:

假设第一次计算的最大值(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 分配给它,导致截断。分配给它的实际值为172 (0xAC)。

编辑 1

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

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

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

编辑 2

建议使用以下等式:

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

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

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

编辑 3

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

编辑 4

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

【讨论】:

  • 是的 - 你是对的。我将其基于的公式添加到问题中。似乎还缺少一些常量。
  • 太棒了 - 图像现在看起来好多了!我认为只有一些奇怪的区域是截断的结果。您知道截断值的最有效方法是什么吗?我是否将其存储在 int 中,然后使用 if 语句检查其大小?
  • 其实不用担心,我找到了这个codereview.stackexchange.com/q/6502/30438。我自己试试看!
  • @Robert 你不想截断,因为 RGB 值应该在 0 到 255 之间,对吧?
  • 是的 - 我的意思是夹紧而不是截断。我刚刚修改了公式,现在效果很好。谢谢您的帮助! :) 为了完整性,我将提交我的修改。
猜你喜欢
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
相关资源
最近更新 更多