伽玛校正究竟需要什么?

时间:2012-10-19 13:48:04

标签: image-processing brightness gamma luminance

我有充分理解伽马校正需求的问题。我希望你们能帮助我。

假设我们想要显示256个相邻像素。这些像素应该是从黑到白的平滑渐变。为了表示他们的颜色,我们使用来自0..255.的线性灰度值。由于人眼的非线性,显示器不能仅将这些值转换为线性亮度值。如果相邻像素具有亮度值(1/256)*I_max, (2/256)*I_max, et cetera,我们会在较暗区域感知两个像素之间的亮度差异太大(渐变不会是平滑的)。

幸运的是,显示器与人眼具有相互的非线性。这意味着,如果我们将线性灰度值0..255放入帧缓冲区,则监视器将它们转换为非线性亮度值x ^ gamma。然而,由于我们的眼睛是非线性的,反之亦然,我们感觉到平滑的线性梯度。显示器和我们的一只眼睛的非线性相互抵消。

那么,为什么我们需要伽马校正?我在书中读过,我们总是希望显示器产生线性亮度值。根据它们,必须在将灰度值写入帧缓冲器之前补偿监视器的非线性。这是通过伽马校正完成的。但是,我的问题在于 - 据我所知 - 当显示器产生线性亮度值时,我们不会感知到线性亮度值(即我们不会感觉到平滑,稳定的渐变)。

据我所知,如果我们将线性灰度值放入帧缓冲区,那将是完美的。监视器将这些值转换为非线性亮度值,并且我们的眼睛再次感知线性亮度值,因为眼睛是互逆的非线性。无需对帧缓冲区中的灰度值进行伽玛校正,也无需强制显示器生成线性亮度值。

我看待这些事情的方式有什么问题? 感谢

3 个答案:

答案 0 :(得分:4)

请允许我“复活”这个问题,因为我现在正在努力解决类似的问题而且我认为我找到了答案 - 这可能对其他人有用。或者我可能错了,有人可以告诉我:)。

我认为你的思维方式没有任何问题。事情是,如果你知道自己在做什么,你不需要一直进行伽马校正。这取决于你想要达到的目标。让我们看看两种不同的情况。

A)光模拟(AKA渲染)。你有一个漫反射的表面,指向它的光。然后,光的强度加倍。

好。让我们看看在这种情况下现实世界中会发生什么。假设一个纯粹的漫反射表面,反射光的强度将是表面的反照率乘以入射光强度和入射光角度和法线的余弦。随你。事实是,当入射光强度加倍时,反射光强度也会加倍。这就是光传输被认为是线性过程的原因。有趣的是,你不会将表面感知为亮度的两倍,因为我们的感知是非线性的(这是通过所谓的史蒂文的幂律来建模的)。再说一遍:在现实世界中,反射光加倍,但你不会觉得它亮两倍。

现在,我们将如何模拟这个?好吧,如果我们的sRGB纹理具有表面的反照率,我们需要对其进行线性化(通过去校正它,这意味着应用2.2伽玛)。现在它是线性的,并且我们有光强度,我们可以使用我之前说过的公式来计算反射光强度。由于我们处于线性空间,通过加倍强度,我们将使输出加倍,就像在现实世界中一样。现在我们对结果进行伽马校正。因此,当屏幕显示渲染图像时,它将应用伽玛,因此它将具有线性响应,这意味着当我们模拟两次时,屏幕发出的光的强度将是两倍。比我们模拟第一个时的光强。因此,从屏幕到达您眼睛的光线将具有两倍的强度。正如你用正常光影响它的真实表面那样会发生。你不会觉得第二次渲染的亮度是两倍,当然,但是,正如我们之前所说,这正是它在真实情况下会发生的事情。现实世界和模拟中的相同行为意味着模拟(渲染)是正确的:)

B)如果你想要一个你想要“看起来”(被认为是AKA)的渐变,那么就是一个不同的情况。

由于您希望屏幕的非线性响应抵消我们的非线性视觉感知,您可以完全跳过伽马校正(如您所建议的那样)。或者,更准确地说,继续在线性空间和伽马校正中操作,但是创建梯度不是连续的像素(1,2,3 ... 255)的值,这些像素会被非线性地感知(因为Steven的),但是值通过我们的感知亮度响应的倒数(即,将1 / 0.5 = 2的指数应用于归一化值来转换。这是应用Steven指数对亮度的倒数)。

事实上,如果您看到经过伽马校正的线性渐变(例如http://scanline.ca/gradients/中的线性渐变),您根本不会将其视为线性渐变:您会看到较低强度的变化远远高于较高强度(正如预期的那样)。

嗯,至少这是我目前对该主题的理解。我希望它可以帮助任何人。请再说一遍,如果有问题,我会非常感激,如果有人能说出来的话......

答案 1 :(得分:3)

问题实际上是在进行颜色计算时。例如,如果要混合两种颜色,则需要使用线性强度进行计算。要实际显示正确的结果,您必须将线性强度转换回伽马校正的强度。

你的眼睛如何看待强度是不相关的。要正确进行颜色计算,必须根据光学的物理原理来完成,这些原理依赖于线性亮度值。计算出一种颜色后,您希望显示器输出这些亮度值,无论其感知方式如何,因此您必须补偿显示器不能直接生成您想要的颜色这一事实。

答案 2 :(得分:0)

要真正回答你看待这个问题的方式有问题 - 它没有什么不妥。拥有一个线性帧缓冲区会很棒,但正如你所说,拥有一个8位线性帧缓冲区并不是很好。

8位易于处理的事实几乎是伽马压缩帧缓冲和颜色符号的唯一理由(Think HTML的#888 - 使用#333作为中间灰色而不是#888不太酷)

关于显示器 - 您希望能够预测它对您的输入的响应,并且您从sRGB知道它应该是什么。通常这就是你需要知道的全部。有些人认为它是“正确的”或某些东西,如果显示器产生“线性”输出,如果你补偿显示器的伽玛,可以模拟。我建议避开这样的设置,这会破坏所有应用程序(正确且理智地)采用标准伽玛,而不是破坏不良的线性 - 假设应用程序。不要那样做。相反,修复应用程序或转储它们。