对动态范围内亮度的非线性存储/还原算法

韦伯定律

  • 以光为例,若在一小黑屋中,点亮了一支蜡烛A,这支蜡烛对屋内的贡献是显著的,在视觉上也感受到极大的明度提升。但是若是屋内已经点亮了1000支蜡烛,此时再点亮一支蜡烛B的话,从物理能量贡献上,这支新蜡烛B与蜡烛A的物理贡献是一样大的,但是在人的视觉中,B引起的“明度”变化,远远不如A。

  • 音乐的音阶,是符合十二平均律的,音调的频率以等比数列增加,人听起来是均匀升调。两个八度之间频率翻一倍。

  • 据说人所能感受到的疼痛分为了10级,1级是被蚊子叮了,10级呢,是孕妇分娩。有人就问了,那什么是11级疼痛呢?答“11级疼痛就是孕妇分娩的时候被蚊子叮了”

不是线性

中灰

“中灰就是人眼能分辨的所有灰阶的中间点。”

中灰像素的亮度是白像素亮度的20%左右,而不是现实场景中最亮物体的20%。这一点是很关键的。
Gamma Correction

物理反射率检测

若我们定义白卡的反射率是100%,黑卡的反射率是0%,你会发现,中灰卡的反射率不是直觉中的50%,而是一个在20%上下徘徊的数值。

Gamma Correction
人心目中看起来中灰的色块,其物理亮度值大约在白色块的20%左右
视觉感受的中灰色是白色反射率的20%左右。(注:白色为低动态颜色1.0)
此图原点是黑色,1,1点是白色,你可以这么理解此图:当整体环境较暗,微小的亮度增长也会在人的心目中是显著的明度提升
Gamma Correction

为什么要进行矫正?

从人类的视觉特性说起。人类的视觉系统进化出了一个特性,黑暗环境下的辨识能力要强于明亮环境,这可能有助于我们及时发现黑暗中隐藏的危险。如果有兴趣,可以在计算机上绘制一条从白到黑的渐变条,你会发现明显黑色部分的色阶要多于白色部分,是因为我们对于暗色的分辨能力远超过亮色.

那么在有限的计算机颜色(民用显示器和操作系统中黑色到白色256个色阶)中,亮色和暗色均匀分布的话,那亮色部分就会精度过剩而暗色部分就会精度不足.如何解决这个问题?进行 Gamma 矫正。

灰阶预算很紧张,只有灰阶有限,我们才需要考虑中灰映射给谁的问题,如果灰阶足足的够用,硬盘不要钱了,我们主流不再使用8位每通道图片记录亮度信息的话,Gamma是没必要的

Gamma Correction
上图中的红色虚线就是图像的 Gamma 矫正曲线,一般都是2.2的倒数,0.454545…。观察矫正以后的曲线,原来0到0.5的区间被扩展到了0到~0.73,相应的大于0.5的区间被压缩到只有原来的一半左右。这样通过一次简单的计算,我们达到了不增加数据量的前提下提高可辨识精度(Perceptual precision)

存储在你硬盘上的图像,都是矫正过的
Gamma Correction
Gamma Correction

为什么是2.2的倒数?

1996年微软和惠普在特定的光照条件下测试人观看显示器的感受,他们认为,把8位图像中128号灰(0.5灰)这个抽象的、代表心目中中灰色的数值,对应以白像素21.8%的亮度显示出来,由黑到白的渐变过渡看起来会比较均匀。最终对应的Gamma就是2.2。那么他们定了这个标准,后世的硬件也就都往上面靠了,包括拍照的时候,编码Gamma也就取了1/2.2=0.454

sRGB(standard Red Green Blue)是由Microsoft影像巨擘共同开发的一种彩色语言协议,微软联合爱普生、HP惠普等提供一种标准方法来定义色彩,让显示、打印和扫描等各种计算机外部设备与应用软件对于色彩有一个共通的语言

???误解
因为老式的 CRT 显示器。
阴极管显示器有一个物理特性——输入值和输出值呈现指数关系,这个指数是2.2。也就是说,当你输入0.5的亮度,在屏幕上得到的不是0.5,而是0.5的2.2次方,约等于0.218
Gamma Correction
当我们在 CRT 显示器上显示一张 Gamma 矫正过的图像,也就是上面的那根曲线,就会获得所期望的线性图像——中间那跟灰色的直线。你看,对图像进行Gamma 矫正即可以获得我们想要的精度,又能在 CRT 显示器上正确显示,这岂不是一个美好的巧合?

事实上我们之所以选择2.2的倒数进行图像矫正,那是为了迎合 CRT 显示器的特性。如果显示器的 Gamma 值不是2.2,那么图像矫正 Gamma 值也需要相应变更,比方说早年的 Mac 操作系统都是使用1.8的 Gamma 值。现代的 LCD 显示器已经不再具有这个特性,但是生产厂商仍旧会加入模拟 Gamma 曲线的硬件功能,也就是说所有显示器都期待软件输出 Gamma 矫正过的图像。总结一下,所谓 Gamma 矫正就是对颜色进行指数运算。对图像进行矫正是为了获得符合人眼特性的可辨识精度。矫正使用的Gamma 值取决于显示器,现代系统基本上都统一使用2.2。
就是显示器说没有2.2也模拟出2.2。

RGB 8位

Gamma Correction
三原色(红绿蓝RGB)的色阶最多256 X 256 X 256 = 16777216种颜色

RGB32位

RGB值不是0-255,而是变成了0.0000-1.0000
Gamma Correction

Gamma Correction

实际亮度(X轴)=>内部存储(Y轴) 存储数值 = 物理亮度的1/2.2次方

  • 即对应使用1/2.2位置的Gamma曲线
  • 假设实际亮度X轴为0.2,存储数值将为0.2的1/2.2次方,即Y轴0.5

内部存储(X轴)=>显示还原(Y轴) 显示的物理亮度 = 存储数值的2.2次方

  • 即对应使用2.2位置的Gamma曲线
  • 假设内部存储X轴为0.5,显示物理亮度将为0.5的2.2次方,即Y轴0.2

相关文章: