我已经使用 JPEG 转换公式实现了 rgb->ycrcb 和 ycrcb->rgb 转换
http://www.w3.org/Graphics/JPEG/jfif3.pdf
(同样在:http://en.wikipedia.org/wiki/YCbCr(JPEG 转换))。
检查结果是否正确时(原始->YCrCb->RGB),某些像素相差一,例如201->200。
平均精度误差百分比为 0.1%,因此并不重要。
/// 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)
当使用其他类型的舍入时,例如float(int) 或 std::ceil(),结果更糟。
So, 是否存在在不损失精度的情况下进行 YCrCb RGB 转换的方法?
问题不在于舍入模式。
即使您将浮点常量转换为比率并仅使用整数数学,逆运算后您仍然会看到不同的值。
要了解原因,请考虑一个函数,我告诉您我将把数字 0 到 N 移动到 0 到 N-2 的范围。事实上,这个变换只是没有逆变换。您可以使用浮点计算或多或少准确地表示它(f(x) = x*(N-2)/N
),但一些相邻值将映射到整数数学中的相同结果(鸽巢原理!)。这是一种简化并“压缩”范围,但是在像您正在使用的这样的任意仿射变换中也会发生同样的事情。
如果你有浮点数的 r、g、b,并保持这种状态直到量化为整数,那将是一个不同的故事 - 但在整数中,你一定会看到原始值和逆值之间的一些差异。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)