【问题标题】:What exactly is the need for gamma correction?伽马校正到底需要什么?
【发布时间】:2012-10-10 03:40:17
【问题描述】:

我无法完全理解伽玛校正的必要性。我希望你们能帮助我。

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

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

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

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

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

【问题讨论】:

    标签: image-processing brightness gamma luminance


    【解决方案1】:

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

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

    【讨论】:

    • “要实际显示正确的结果,您必须将线性强度转换回伽马校正强度。”
    • @user1494080:你的眼睛如何感知颜色并不重要。颜色计算不是基于感知强度来完成的。您已经计算了一种颜色,这就是您希望显示器显示的颜色,无论它是如何被感知的。您必须补偿监视器不能直接产生您想要的强度这一事实。
    • @user1494080,如果监视器被设计为输入线性值,那么你是正确的。但事实并非如此,其起源可以追溯到电视史上。
    • @user1494080 thers 是我非常喜欢的一个文档:“伽马常见问题解答”poynton.com/PDFs/GammaFAQ.pdf 伽马就像大/小端,我们经常做错了,因为太过分了。让我们都花时间充分消化它。沃恩所说的是关键。您计算一个物理值(线性),显示器显示它以 2.2 的功率升高,因此您需要在写入帧缓冲区之前通过提高 1/2.2 的功率来进行补偿。当然,只有当你真的在线性空间中工作时,这才是正确的。小心你的数据源。大多数情况下,数据源位于伽马空间(纹理、照片)..
    【解决方案2】:

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

    8 位是如此容易处理的事实几乎是伽玛压缩帧缓冲区和颜色符号的唯一理由(想想 HTML 的 #888 - 将 #333 用于中间灰色而不是 #888 会不会很酷) .

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

    【讨论】:

      【解决方案3】:

      请允许我“复活”这个问题,因为我现在正在为类似的问题而苦苦挣扎,我想我已经找到了答案 - 它可能对其他人有用。或者我可能是错的,有人可以告诉我:)

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

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

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

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

      B) 如果您想要一个渐变,而您想要“看起来”(AKA 被感知)为线性的,则恰恰是另一种情况。

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

      事实上,如果您看到伽马校正的线性梯度,例如 http://scanline.ca/gradients/ 中的那个,您根本不会认为它是线性的:您会看到较低强度的变化远大于较高强度的变化 (正如预期的那样)。

      嗯,至少这是我目前对该主题的理解。我希望它可以帮助任何人。再次,拜托,拜托,如果有错误,如果有人能指出它,我将非常感激......

      【讨论】:

      • 我的理解和你一样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-28
      • 2021-08-14
      • 1970-01-01
      • 2012-12-27
      相关资源
      最近更新 更多