关于Gamma的学习笔记。欢迎参观、指导。。

  1. 在哪见过、听说过Gamma?

  2. 什么是Gamma?

  2.1. 显示器Gamma曲线

  2.2. 检查显示系统的Gamma值

  3. 什么是Gamma校正?

  4. Gamma校正可能发生在哪里

  4.1. 系统级(硬件、操作系统)

  4.2. 应用程序级

  4.3. 文件级

  5. 改变Gamma带来的影响

  5.1. 影调的变化

  5.2. 颜色的变化

  5.3. 其它

  6. 校正Gamma的理由

  6.1. 标准化及互换性

  6.2. 算法上的要求

  7. 不校正Gamma的理由

  7.1. 现实的非标准化

  7.2. 更符合视觉特性

  7.3. 可能导致颜色数的减少

  8. 结论

  1. 在哪见过、听说过Gamma?

  * 还用说,Adobe Gamma

  * 常听说MAC的默认Gamma是1.8,PC的是2.2

  * 我的显卡驱动程序里有Gamma调节

  * 我下载了一个软件,也可以调节显示器的Gamma

  * WinDVD播放器带Gamma校正功能

  * ACDSEE的曝光调节里可以调Gamma

  * ACDSEE的选项中有Enable Gamma Correction

  * XV Viewer 能以参数-gamma 2.2 启动(x window也可以)

  * PNG文件里有Gamma校正

  * Photoshop里当然也有

  * ICC Profile也和Gamma有关?

  * 摄像头、数码相机、扫描仪?胶片?……中也有提到Gamma的

  ……

  这些都是怎么回事?

  图 1-1 显卡(驱动程序)上的Gamma设置现在很多显卡上都有Gamma设置(图中是一破烂集成显卡)。

  图 1-2 ACDSEE中的曝光调节

  2. 什么是Gamma?

  2.1. 显示器Gamma曲线

  Gamma可能源于CRT(显示器/电视机)的响应曲线,即其亮度与输入电压的非线性关系。

  图 2-1 一典型显示器 的响应曲线,非常接近指数函数 图片来源:http://radsite.lbl.gov/radiance/refer/Notes/gamma.html (说明:上图中输入值为数字化的,即通常的RGB值,但可以理解数/模转换是线性的,所以它和输入电压是等效的。)

  归一化后,我们通常可以用一简单的函数来表示: output = input ^ gamma

  gamma就是指数函数中的幂

  图 2-2 归一化的Gamma曲线 图片来源:http://www.teamten.com/lawrence/graphics/gamma/

  注意上图曲线的一些特性:

  * 端点是不变的,即不管gamma值如何变化,0对应的输出始终是0,1的输出始终是1(这一特性会被用到)。这可能是gamma又被叫作“灰度”系数的原因吧。

  * gamma > 1时,曲线在gamma=1斜线的下方;反之则在上方。

  另外说明一下,虽然是以显示器作为例子,但可扩展到一般的图像相关的输入/输出设备。Gamma曲线应该是普遍存在的,即使它不是严格的指数关系,可能还是会这么通称。至少我知道的数码机机/摄像头里的sensor也存在gamma曲线及gamma校正。

  2.2. 检查显示系统的Gamma值

  在PC上,好像还没有什么软件方法可以得到系统的Gamma值(4.1会说明这一点)。有人做了一些图片,可以粗略估计。其原理和Adobe Gamma类似。

  图 2-3 Gamma对照图 图片来源:http://radsite.lbl.gov/radiance/refer/Notes/gamma.html

  另有一张类似的图片: http://www.teamten.com/lawrence/graphics/gamma/ramp.gif

  使用方法:与Adobe Gamma类似,即眯着眼,或站远点,或近视眼取下眼镜,总之当左边糊成一片,而右边某栏的亮度和左边相当时。

  注意:如果您没有做任何Gamma校正(没有使用Adobe Gamma之类的软件,或虽使用了但校正系数设为1.0),测得的才是显示器的Gamma,否则只能称为系统Gamma(或复合Gamma)。 另外,通过显示器自带的ICC Profile是可以知道显示器的Gamma的,这个应该比较准。我看了自己的G71f+,大约是2.2.

  3. 什么是Gamma校正?

  从一个数字化的图片文件,到我们最终看到的图片,中间要经过许多环节。几乎在任何一个环节上,都可以加入一些变换,以改变最终输出和最初输入的关系(类似的,这种关系被称作系统Gamma或复合Gamma)。

  比如,对gamma=2.5的显示器,在数据传递到显示器之前,将其做一个gamma=0.4的变换(比如对显卡缓存中的数据,d’ = d ^ 0.4),这样就能从总体上得到一个线性的关系。 注意这里有一点混乱。通常我们说做一个gamma=c的校正,意思是指做output = input ^ (1/c)的变换。有一个倒数关系。

  对于PC,显示器的Gamma是2.2左右(可能以前更多的是2.5,现在好像趋向2.2了),一般没有内置的校正,所以我们说Adobe Gamma对Windows系统默认的校正系数是2.2。对于MAC,显示器的Gamma是2.5,硬件内置了1.4的校正,所以它还需要2.5/1.4~=1.8的校正才成为线性的。下文对各种系统下的gamma校正过程有更详细的说明。 http://www.cgsd.com/papers/gamma_diagram.html

  4. Gamma校正可能发生在哪里

  4.1. 系统级(硬件、操作系统)

  显示器内没有听说过有何补偿,即使有,它们也对外呈现一定的gamma值。DVI接口的及LCD类显示器不清楚。 主要的补偿发生在显卡及其驱动程序类。如果显卡硬件不支持,则由驱动程序软件完成。在Windows中,上层通过调用驱动程序的一个接口函数(DrvIcmSetDeviceGammaRamp)向其传递Gamma校正表(LUT),这个表的大小是3*256项(每项16字节),对应于RGB三个通道,每个通道256级。描述这一细节,可以对有些事情更有把握:

  * 这种校正实际上可以是任意函数,而不限于gamma为幂的指数函数。

  * 也是因为此,不能通过驱动程序得到系统的gamma值(因为最多只能得到那个表)。

  * 这一设置对整个系统有效(任何程序,任意显示的图片都受它影响)。

  以前我一直不明白Adobe Gamma和驱动程序的Gamma是什么关系,它们一起出现就不知所措。还有人说它们是共同作用的。现在我完全明白了,没有迭加关系,最后者的设置有效。而且,Adobe Gamma也不必是(实际上也不是)一个驻留程序,它仅在启动时将那个表传给驱动程序就完成了它的任务。

  还可以用其它程序来校正/设置gamma,下面是一个方便的小工具:Gamma Panel。(查看本文中的图片,需要经常改变gamma,最好下一个,Free的。) http://www.stars.benchmark.pl/index.php?show=gapa&SID=5c96c83c7df02e6e44dea37584af9534

  图 4-1 Gamma Panel,一个校正系统Gamma的小工具 图中的Gamma是校正系数,即实际曲线是:output = inupt ^ (1/gamma)

  4.2. 应用程序级

  如前提到的,某些播放软件有Gamma校正功能,ACDSEE也有。这时,它们不是修改系统的Gamma校正表,而是在解码时对当前帧/图像作了实时的Gamma变换。

  图 4-2 ACDSEE浏览图片时可加载Gamma校正功能 图中左边是由IE打开的同一图片(无Gamma校正),可以看出它们的亮度不同。(不过,黑框和白边是相同的。)

  4.3. 文件级

  如前面提到的(图 1-2 ACDSEE中的曝光调节),某些图像处理软件可以调整文件的Gamma,这种调整的结果将写入文件(即相当于对图像进行某种处理)。比如,当你的PC未进行Gamma校正(你的系统Gamma=显示器的Gamma约2.2),这时你可以把文件的Gamma调为2.2保存,你以及其它未校正系统Gamma的PC用户看到的这个图片应是正好的。(注意,这里有一个前提即原始图片在Gamma=1的系统上看是“正好”的。)

  另一种方式则是将Gamma校正的系数写入文件内,而不改变文件内容,而浏览/处理软件在解码这一图像时会依据这一参数对它单独进行Gamma校正。(这被称作“文件Gamma”。PNG格式支持)

  总之,不管Gamma校正发生在哪一环节,它们是等效的(在理想情况下/或近似地看)。明白在哪些环节Gamma发生了怎样的变化,然后做一些乘除法就可以了。

  5. 改变Gamma带来的影响

  5.1. 影调的变化

  通常的感觉是,系统gamma高,图像会发暗,而校正后,画面变亮。观察下列图片。

  两个对应的File Gamma=2.5的图片是为了模拟系统Gamma的变化。或者也可以用Gamma Panel之类的工具,将Gamma校正系数设为1.0~2.5观察(每组中的第1个图片)。

  图 5-1 灰度图0-128, File Gamma=1.0 图片来源:http://www.cgsd.com/papers/palette2.html

  图 5-2 灰度图0-128, File Gamma=2.5 图片来源:http://www.cgsd.com/papers/palette2.html

  图 5-3 灰度图128-255, File Gamma=1.0 图片来源:http://www.cgsd.com/papers/palette.html

  图 5-4 灰度图128-255, File Gamma=2.5 图片来源:http://www.cgsd.com/papers/palette.html

  结论:

  * 当系统Gamma高(Gamma校正=1.0)时,看到的图像暗部影调丰富;反之,则亮部丰富。

  * Gamma校正设为2.5时看到的File Gamma=2.5的图片,和校正设为1.0时看到的File Gamma=1.0的图片相当。

  另:这里有一个直观的(用普通照片的)例子。http://graphics.stanford.edu/gamma.html

  5.2. 颜色的变化

  很显然,Gamma的变化带来亮度的变化。而单独改变某个通道的Gamma,则会则会带来色调(Hue)的变化。http://www.cgsd.com/papers/gamma_colorspace.html

  当然,如果显示器本来就偏色,我们则可以改变某个通道的Gamma使其总体上保持均衡。

  5.3. 其它

  其它影响在后面有说明或提及。

  6. 校正Gamma的理由

  主要指是否要将系统Gamma校正到1.0。因为校正总是存在的。(下同)

  6.1. 标准化及互换性

  如果数码相机/扫描仪给你一个Gamma=1.0的图片,你最好是在系统Gamma=1.0的系统上查看;或者当你的数码图片要拿去输出时,对方系统Gamma=1.0;…… (这部分涉及到色彩空间、ICC Profile,我还不太清楚,而且接触的设备非常有限,不多说了。)

  6.2. 算法上的要求

  在涉及不同灰度的混合时,就会对gamma有要求。一个简单的例子,考虑在填充时,一半的黑(0)+一半的白(255),效果应该和50%的灰(128)相同。但这仅在系统gamma=1.0时成立。

  又如,彩色转黑白时常说的:30% R + 59% G + 11% B,也是针对gamma=1.0而言。 同样,许多算法也是针对1.0的系统gamma,否则算法内要做gamma校正。 下面是一个抗距齿(anti-alias,反走样)的例子。

  图 6-1 通常情况下的边缘 图片来源:http://www.teamten.com/lawrence/graphics/gamma/

  由于只能在矩形的点阵中画斜线,而斜线的像素值为全黑,当斜线较陡(或平)时,就会有明显的锯齿感。

  请将系统的gamma校正设为1.0查看下面两图(即不校正系统gamma)

  图 6-2 采用anti-alias后,锯齿感没有那么明显了 图片来源:http://www.teamten.com/lawrence/graphics/gamma/

  在Photoshop中放大查看此图片,就会发现边缘不是全黑的,而是渐变的。(这是对anti-alias的直观理解。)

  注:不要用ACDSEE放大查看,它默认的放大算法是插值的,无法看清像素的原貌。

  图 6-3 anti-alias并gamma校正后,锯齿感完全消失 图片来源:http://www.teamten.com/lawrence/graphics/gamma/

  当然,如果你保持系统gamma=1.0去查看上面的图片,就会发现第2张图完全无锯齿感,第3张图反而有一点。(这不是也可以作为一种估计系统gamma的方法吗)

  7. 不校正Gamma的理由

  7.1. 现实的非标准化

  假定你的图片作为Web发布,你的用户(观众)的系统Gamma会是1.0吗?即使可以假定色影无忌的泡菜会用Adobe Gamma将他们的系统Gamma校正到1.0左右,但绝大多数普通用户呢?——在接触到Photoshop前,我是不知道什么Gamma的。也许只能折衷吧。(MAC通过硬件只校正到1.8,SGI只校正到1.4,不知道有没有这方面的原因。)

  Making Good Cross Platform And WWW Pictureshttp://www.cgsd.com/papers/gamma.web.html

  而我们整天面对的操作系统,它默认用户界面的设计,又是以什么系统Gamma值为前提的呢?——似乎设为1.0并不是最舒服的。 PNG文件格式提供了Gamma补偿的功能,但并没有流行起来,因为人们不知道他们的系统Gamma是多少(当然还有别的原因)。

  The Sad Story of PNG Gamma “Correction”http://www.hut.fi/u/hsivonen/png-gamma.html

  7.2. 更符合视觉特性

  就人的感知觉,心理量和物理量一般呈对数关系,视觉也不例外。虽然这个对数关系和那个指数关系并不严格对应,但方向上是一致的。即越暗处感觉越细(对同等光强的变化,暗处比亮处敏感),而对于(未校正的)显示器gamma曲线(gamma值大于1),也是暗处对应的层次更多。

  比如对gamma=2,以一半的光强为分界,0~182对应于暗的一半,182~255对应于亮的一半。

  7.3. 可能导致颜色数的减少

  这是由于数字量的舍入误差造成的。输入数据按通常的每通道8位计算,当显卡(DAC)精度只有8位时就会发生。 x = 0:255; y = uint8((x / 255) .^ gamma * 255); n = histc(y, x); count = sum(n>0)

  当gamma=2(或0.5)时,结果count=192,即256色变为了192色。若三通道Gamma值(校正系统)相同,则总共的颜色数为192^3 = 707,788色,而24位色原本为16,777,216。

  当然,对10bit, 12bit及更高位显卡就不存在这个问题了。(以前一直不明白在8bit色彩的系统上,更高位的显卡有何意义。现在有一点感受了。)

  8. 结论

  Gamma是一个基本的要素。关心图形、图像的人应该给它一点关心. 不将显示系统Gamma校正到1.0似乎并没有太大的错误,至少你和人民大众站在了一边。校正到什么程度,既有折衷的考虑,也有口味的因素。但不偏色是必要的。当标准需要你校正时,你最好遵守标准。总之,取决于你的图片与谁“接口”。 Gamma只是ICC Profile的一部分。关于标准及互换性的问题,也许只有理解了色彩管理以后,才能完全明白。

  注:这段话中有错误,用Adobe Gamma是将系统Gamma校正到2.2(PC用户)或1.8(MAC用户)等。由于我当初有这种理解(认为校正是应将系统Gamma校正到1.0),导致一些偏差,请各位小心!估计不影响全局,我也就不一一修正了。