本文介绍了JPEG:YCrCb- RGB转换精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用
中的JPEG转换公式实现了rgb-> ycrcb和ycrcb-> rgb转换 http://www.w3.org/Graphics/JPEG/jfif3.pdf
(相同于: http://en.wikipedia.org/wiki/YCbCr (JPEG转换)).

I've implemented rgb->ycrcb and ycrcb->rgb conversion using JPEG conversion formulae from
http://www.w3.org/Graphics/JPEG/jfif3.pdf
(the same at: http://en.wikipedia.org/wiki/YCbCr (JPEG conversion)).

在检查结果是否正确时(原始-> YCrCb-> RGB),某些像素相差一个,例如201-> 200.

When checking whether results are correct (original->YCrCb->RGB), some of pixels differ by one, e.g 201->200.

精度误差的平均百分比为0.1%,所以并不重要.

Average percent of precision errors is 0.1%, so it's not critical.

/// converts RGB pixel to YCrCb using { en.wikipedia.org/wiki/YCbCr: JPEG conversion }
ivect4 rgb2ycrcb(int r, int g, int b)
{
    int y =  round(0.299*r + 0.587*g + 0.114*b) ;
    int cb = round(128.0 - (0.1687*r) - (0.3313*g) + (0.5*b));
    int cr = round(128.0 + (0.5*r) - (0.4187*g) - (0.0813*b));
    return ivect4(y, cr, cb, 255);
}
/// converts YCrCb pixel to RGB using { en.wikipedia.org/wiki/YCbCr: JPEG conversion }
ivect4 ycrcb2rgb(int y, int cr, int cb)
{
    int r = round(1.402*(cr-128) + y);
    int g = round(-0.34414*(cb-128)-0.71414*(cr-128) + y);
    int b = round(1.772*(cb-128) + y);
    return ivect4(r, g, b, 255);
}

我使用舍入公式:
地板((x)+ 0.5)

I use round formula:
floor((x) + 0.5)

使用其他类型的舍入时,例如float(int)或std :: ceil(),结果甚至更糟.

When using other types of rounding, e.g. float(int), or std::ceil(), results are even worse.

那么,是否存在进行YCrCb<-> RGB转换而又不损失精度的方法?

推荐答案

问题不是舍入模式.

即使将浮点常量转换为比率,并且仅使用整数数学运算,反之后仍会看到不同的值.

Even if you converted your floating point constants to ratios and used only integer math, you'd still see different values after the inverse.

要了解原因,请考虑一个函数,在该函数中我告诉您将数字0到N转换为范围0到N-2.事实是这种变换只是没有逆向.您可以使用浮点计算(f(x) = x*(N-2)/N)或多或少地精确地表示它,但是在整数数学中,某些相邻值将映射到相同的结果(鸽子洞原理!).这是一种简化,可以压缩"范围,但是同样的事情也发生在您正在使用的任意仿射变换中.

To see why, consider a function where I tell you I'm going to shift the numbers 0 through N to the range 0 through N-2. The fact is that this transform is just doesn't have an inverse. You can represent it more or less exactly with a floating point computation (f(x) = x*(N-2)/N), but some of the neighboring values will map to the same result in integer math (pigeonhole principle!). This is a simplification and "compresses" the range, but the same thing happens in arbitrary affine transforms like this one you are using.

如果r,g,b的浮点数保持不变,直到量化为整数为止,那将是另一回事了-但是在整数中,您一定总会看到原始数和逆数之间的某些差异.

If you had r, g, b in floating point, and kept it that way until you quantized to integer, that would be a different story - but in integers you will necessarily always see some difference between the original and the inverse.

这篇关于JPEG:YCrCb- RGB转换精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 07:18