问题描述
我已经使用
中的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转换精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!