# Gamma空间和线性空间 - [颜色空间](http://aicdg.com/gamma-and-linear-space/#颜色空间) - [Gamma校正](http://aicdg.com/gamma-and-linear-space/#gamma校正) - Gamma校正的过程 - [8位图的显示](http://aicdg.com/gamma-and-linear-space/#8位图的显示) - Gamma色彩空间与线性色彩空间与渲染 - [Linear颜色空间](http://aicdg.com/gamma-and-linear-space/#linear颜色空间) - [Gamma颜色空间](http://aicdg.com/gamma-and-linear-space/#gamma颜色空间) - [参考文章](http://aicdg.com/gamma-and-linear-space/#参考文章) # 颜色空间 ​ 常见的颜色空间有两种,分别是 - **线性空间**:颜色(亮度)按线性渐变的空间 - **Gamma空间**:颜色(亮度)不按线性渐变的空间 # Gamma校正 ​ 先做个有趣的对比实验。 ​ **第一步**:在PHOTOSHOP中新建一个文件,500*150 / 分辨率75 / 颜色模式RGB 8位 / 背景白色,然后从左(黑)到右(白),水平拉一条渐变,起点终点位于画布左右两端。 ![gamma.png](Gamma space and linear space.assets/gamma.png) ​ 接下来找到明暗的分界线,相信大多数人选择的都是如下图红线位置 ![gamma2.png](Gamma space and linear space.assets/gamma2.png) ​ 我们之所以选择这个位置作为明暗的分界线,是因为我们认为红线左面(暗部)和红线右面(亮部)的信息一样多。 ​ 现在打开取色器,取我们认为黑白分界线处的值,得到的是 **RGB(128, 128, 128)**。对于8位图像,有256个色阶(0~255),128恰好是正中间。 ​ **第二步**:既然说了对比试验,就要有对比的对象,在PHOTOSHOP中新建一个文件,500*150 / 分辨率75 / 颜色模式RGB 32位 / 背景白色,然后从左(黑)到右(白),水平拉一条渐变,起点终点位于画布左右两端。 ![linear.png](Gamma space and linear space.assets/linear.png) ​ 我们都知道明暗分界线是 **RGB(128, 128, 128)** ,所以在这张图中找到这个位置 ![linear2.png](Gamma space and linear space.assets/linear2.png) ​ 这个位置并不在图像正中间,而是 0.2 左右的位置。而且这个渐变过程很不自然,亮部很多,暗部很少。 - 暗部去哪了: - 暗部没减少,反倒增多了。 - 因为图片格式变成了32位,它有了更多的色阶来表现颜色。 - 它不再是RGB0-255,而是变成了0.0000-1.0000。代表了RGB三原色的更多色阶。 - 你之前划分的暗部仍然在红线的左侧,那128个暗部色值都没有消失。 - 相反,32位图提供了更多的色阶来表现暗部,数量也远大于128。具体数量不需要关心,也不是2的32次方,感兴趣的可以自行查阅32位RGB,不在本文展开。 - 也就是说32位格式下,使用了0.2的空间,表现了8位格式下占一半的暗部,不仅如此,还附送了多得多的暗部细节,因为色阶变多了嘛,虽然作为人类,我们可能感受不到那么多色阶变化..。 - 亮部增多了: - 没错,确实多出来许多的亮部信息。 - 32位格式下,多出来的亮部信息,包含8位原本的亮部信息,以及大量你可能难以区分的亮部信息。 - 渐变不自然 - “黑少白多,渐变不自然”————那是你以为。 - 这才是自然界中真实的渐变,因为这才是线性的,每次滴入等量白色颜料的从黑到白的渐变。 - 之所以你会觉得渐变不自然,是因为人类的眼睛对暗部的变化更为敏感(至于理论方面的依据,请自行搜索,本文只说结论)。 - 综上所述,你之所以会认为一个线性的渐变过程“不自然”,是因为你对亮部的细节变化不敏感,或者难以察觉。因此得出了“黑少白多,渐变不自然”的结论。 -也就是说,你觉得32位下的线性渐变,亮部区域出现了过多的冗余信息。 ​ 综合上面分析,可以知道: - 原本我们在8位图中找到的明暗分界线RGB(128,128,128)在自然界的线性渐变中,大致处于前20%的位置,即0.2的位置 - 之前的8位图1欺骗了我们,它如实的把你认为的0.5老老实实的记做了0.5,而不是实际的0.2。它出了问题 ​ 8位图为什么出了问题:类对于暗部敏感,我要是把你认为的0.5,记成0.2,那暗部色阶就只有256*0.2=50个左右的色阶来存储暗部,50个左右,明显不够用。而人类对亮部不敏感。以只能把人类认为的明暗分界线就记做0.5,然后去掉一部分感受不明显的亮部色阶,以此换来跟多的暗部色阶存储空间,来适应人类的感受。 ​ 8位图中 0.2 转换到 0.5 的过程,本质上是一个全局提亮的过程,这个过程被称作 **Gamma校正** ​ **Gamma校正** - Gamma校正被使用在8位RGB图中。 - 用来解决在有限的存储空间中保存尽可能多的人类感受敏感的色彩内容 # Gamma校正的过程 ​ Gamma校正的方式就是采样时,和输出到显示器给人类看时,对亮度进行的调整. - 采样时 Gamma=1/2.2 调亮Gamma - 显示时 Gamma=2.2 调暗Gamma ![curve.png](Gamma space and linear space.assets/curve.png) - 实际亮度(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 ## 8位图的显示 ​ 经过Gamma校正后,得到了更多的暗部存储空间,牺牲掉了一些不重要的亮部存储空间。它把你认为的0.2通过Gamma校正成了0.5,因为Gamma校正本身是一个非线性的调整过程(观察Gamma曲线图:Gamma为1,即是中间那条直线,表示未校正,那么Gamma为1时,渐变是线性的。其他的不是直线,不是直线你就当他是非线性 ​ 那么问题来了:显示器显示8位图片时,我们已知现在主流显示器的色彩要大于8位,多数都是32位真彩色,那么请问,显示器接受到8位图片存储的0.5时,显示的是32位颜色中(以图2位例)0.5位置的颜色,还是0.2位置的颜色。 ​ 没错,显示器显示的时候也经过了一次Gamma校正,它把0.5又变成了0.2。如果不经过这一步,直接输出0.5,因为显示器是32位的,那么你在屏幕上得到的将是位于图2中间位置的那个颜色,你会说这个显示器有问题,颜色不准确,亮瞎了 # Gamma色彩空间与线性色彩空间与渲染 - Gamma颜色空间里使用的是一个进过校正(阉割)过的颜色表。 - Linear颜色空间里使用的是一个线性的完整的颜色表 - 图片是通过颜色空间中的颜色创作出来的,那它就一定存在着一个问题,是否经过Gamma校正 ## Linear颜色空间 - 如果使用Linear颜色空间,除非对指定图片选择了ByPass sRGB(忽略sRGB,你理解为忽略Gamma校正),否则所有的图片都会默认变成sRGB格式。 - 这样做的目的是把你在Gamma颜色空间里创作的图片里面的颜色给校正到正确的32位颜色,再参与GPU渲染计算。 - ByPass sRGB的意思就是直接使用这个0.5,不用再校正了,除非你是在线性颜色空间里创作的图片,否则不建议这么干。 - 然后,GPU再把结果Gamma校正一次,0.2-0.5,这样做的目的是:显示器不管你到底干了什么,一定要在最后Gamma校正一次的(0.5-0.2)。 - 显示器按照接受到的值进行Gamma校正(0.5校正到0.2)给你看。 - 在这个空间里进行渲染,因为使用的是线性的颜色空间,因此你会得到非常真实的表现效果。 - 但是,因为色彩丰富的同时,带来的各项成本,如硬件渲染能力的需求也会增加。 ## Gamma颜色空间 - 在这个颜色空间内渲染,GPU不会再Gamma校正,而是直接使用存储的值参与渲染计算,因为大家使用的都是阉割版的颜色嘛。 - 但是在这个空间里进行的渲染,因为使用的是阉割过的Gamma颜色空间,因此你会得到不符合真实表现的效果。 - 在最终输出到显示器的时候,仍然会经过Gamma校正,将渲染后的0.5,表现成0.2给你看。 - 因为使用了较少的颜色(相对于线性颜色空间),因此会得到比较好的渲染效率以及较低的渲染能力需求。但是图像会存在失真(偏暗,因为亮部细节表现不够)等一系列问题 # 参考文章 ​ [颜色空间——Gamma与线性颜色空间](https://www.cnblogs.com/guanzz/p/7416821.html)