Gamma 会涉及两个地方,一个是图像信号处理(ISP)过程中的 gamma,另一个是 Panel 显示中的 gamma。
1、由于早期都是 CRT 显示器,这种显示器的亮度和电压并不是线性关系,而是呈现一种类似反 gamma_2.2 的非线性关系,所以需要进入 panel 的数据需要是带 gamma_1/2.2,这样输出的数据才是线性的数据,但这不是因为,而是巧合的所以;
2、人眼对亮度的感知是非线性的,或者说是 gamma_1/2.2,即人眼对暗处的变化更加敏感,而对亮处的变化没那么敏感,这样一个 panel 的线性的物理输出,经过人眼自带的 1/2.2gamma,就变成了非线性,也就是人眼对真实物理亮度的感知;
3、如前面所说,人眼对亮度的感知是非线性的,即人眼对暗处的变化更加敏感,而对亮处的变化没那么敏感,那么在 8bit 颜色空间中,我们希望可以存储更多暗处的信息,并适当减少亮处的信息。
( CRT 显示的 gamma 值,其实并没有确定的某个值,只能说是 1.8-2.5 之间,但早期的应该是 2.5 居多,只是后来随着应用和经验的不断积累,逐渐趋于 2.2,但本质上就是一个 1.8-2.5 之间的值,后面涉及到 gamma,都以 2.2 标准)
早期的CRT(Cathode-ray tube)显示器,也就是阴极射线管,电子枪利用电压控制电子轰击到荧幕上进行显像,但这个电压和最终的显示亮度不是线性关系,而是呈现 2.2 的指数关系,即随着电压的增加,亮度增加越来越快,Curve图如下所示:
三条不同的曲线代表不同对比度设置下的电压/亮度映射关系,也就是说对比度对曲线是有影响的,但是这个不是我们关注的点,我们只需要知道电压-亮度是一个 2.2 的指数关系就可以了
到这里会发现,人眼的亮度感知曲线和 CRT 显示器的 Luma 曲线刚好是近似倒数关系,前者是 1/2.2=0.45,后者是 2.2,如果 ISP 输出的是没有经过任何的 Gamma 处理的线性存储的 Image,那么用电子枪打出来的 Image 就是一个自带反 gamma 的图像,所以进入人眼的就是一个带了反 gamma 的物理图像,那么加上人眼的 gamma 就是个线性图像,即在人的大脑中看到的就是一个物理图像,会很暗,这和我们人眼看到的现实世界就不一样了。
人眼对于亮度变化的感知是非线性的,即在 8bit 的 0-255 颜色空间中,从0到1人眼能分辨,但从250到251却很难分辨,这就是所谓人眼对亮度的感应是非线性的,而是指数相关,这和物理世界的绝对标尺是不一样的,毕竟人就是人,不只是物理的人。这里多说一句,其实人对很多事物的感知都不是线性的,而是近似 1/2.2 指数响应,如听觉、嗅觉等,这在生理学上叫韦伯定律。( 德国生理学家E.H.韦伯通过对重量差别感觉的研究发现的一条定律,即感觉的差别阈限随原来刺激量的变化而变化,而且表现为一定的规律性 ),就像你从一天赚一万到赚两万很开心,但从一天赚一百万到一百零一万也就那样,人的指数感应就像物理世界的高斯分布一样普遍。
但为什么会有指数关系,或者说是 Log 关系,无非是现象找到了理论,理论又反向背书现象而已,上面图片的横轴是 Luma 亮度,纵轴是人主观感知到的 Luma 亮度。upper 的是 Luma 均匀变化对应人眼看到的亮度变化,旋转90°,也就是lower那张图,如果人眼观测的亮度是均匀变化的,那么 Luma 就比较集中于暗部区域,亮部区域比较分散,从信息论的角度来讲,也就是暗部区域包含了更多的信息量,而亮部区域相对来说信息量比较少。所以我们要增加暗部的信息,适当减少亮部的信息,后面会上理论解释。
在白天环境亮度10000nits时,人眼大约能分辨的亮度范围为200 - 20,000尼特,低于200尼特的亮度同感觉为黑色。而夜间环境为30nits时,可分辨的亮度范围为1~200尼特,这时100尼特的亮度就引起相当亮的感觉。只有低于1尼特的亮度才引起黑色感觉。人眼感知的亮度与光强成指数关系,而物理学定义的亮度与光强成正比。
目前的工业应用中,色彩空间的存储多以8bit位宽为主,虽然增大位宽,会带来更多的颜色展现,更加细腻,但当所有的数据都在更高位宽上运算时,也相应的会给硬件带来更大的 Cost 和 Power.
如上图所示,第一个代表物理世界的亮度变化,从极暗到极亮,如果我们对其进行 5bit 线性编码,也就是按照其亮度均分成 32 等份,假设Original 是0-255,那么5bit也就是 0-7,8-15,…,201-207,248-255,在数据上是均匀的,但在视觉上可能很长一段都会落入到0-7,而248-255可能很小,这里的原因可以从前面所述的人眼感光特性的得到解释。
所以线性编码之后的灰阶视觉上就如第二个所示,我们主管感受上会暗部比较稀疏,而亮部比较密集,即暗部的细节展现力不够,这也就说明人眼的1/2.2的gamma是多么的合理,物理是绝对的,但人是相对的。人眼对自然界相对暗部区域的分辨力是要高于亮部区域的,也就是人眼对物理世界的相对暗的部分更敏感,谁闲着没事盯着刺眼的阳光看呢。
而这样的线性编码会使人眼感兴趣的亮度区域信息量减少,除非暴力存储,不编码了,直接无限数据存储,那计算机肯定不行,人眼也不行,因为这里的无限指的不只是物理亮度的连续,还有物理亮度有最小值,却没有最大值,你觉得的最大只是人为定义的最大。就像有最低温度,却没有最高温度一样。所以我们要加入gamma,使得存储或者说编码的亮度还原后也是人眼可以接受的,如第三张所示。
gamma本质上就是一个用来亮度映射的指数曲线,下图是从 Raw Image 到最终显示的整个过程中 gamma 变化 pipe
ISP gamma 就是上图中的第一个所谓的 Image gamma,也就是 encode 的过程,可以把整个图片拉亮,在暗部的斜率更大,所以会把暗部的细节展现的更充分,增加了暗部区域的信息量。在有限带宽的限制下,只能尽量增加人眼比较敏感的暗部信息,同时适应 CRT Panel 的 gamma,如果 panel gamma 不变,减小 ISP gamma,就是小于1/2.2,那么ISP之后的 Image 会变亮,最终panel上显示的图像也会变量,越亮对比度自然也会降低。
如下分别为Original / gamma=1/2.2 / gamma=2.2 的显示效果图:
1/2.2=0.45的gamma亮度比较高,0.66的gamma 对比度比较好,ISP gamma是要小于1的,Display gamma 是大于1的,一般消费类相机里面 gamma 范围是[0.6 - 0.8],是亮度和对比度平衡的经验值
如下分别为Linear / gamma0.45 / gamma0.66 的显示效果图:
gamma非线性映射是色彩重建的一个部分,而ISP中很多模块需要在线性颜色空间下进行,尤其是和颜色相关的,看情况吧,有时候需要带 gamma,有时候不需要带 gamma。另外,gamma 测量可以使用24色卡colorchecker
Panel gamma 就是上图中的第二个所谓的 Display gamma,就是 decode 的过程,和 ISP gamma 相对应,达到解码成原始数据的目的,也就是 Sensor 拿到的物理世界数据,如果保持 ISP gamma 不变,panel gamma 越大,也就是大于2.2,那么 panel 上显示的图像就会变暗,但暗了之后对比度也会增加。
System Gamma 就是上面两部分 gamma 的综合效果,理论上我们应该把两条曲线之和做成一条直线,也就是1,这样才能理想的复原 Sersor 捕捉到的物理世界数据的亮度,就是Raw data 的亮度,但实际的工业应用中,我们会让 System gamma 稍微大于1,以获得更高点的亮度,饱和度和对比度也会更好,其实就是会让人视觉上更舒服,符合人眼的感受。
更详细一点说,我们会在 ISP gamma 中,分为 Global gamma 和 Local gamma,一个是用在整幅 Image 的,一个是 local 的,也就是会对 Image 进行分区域做 gamma,比如分成网格来分别做,这样在不同亮度的区域可以针对性的做 gamma,即不同的亮度区域应用不同的 gamma 矫正系数,以期达到更好的效果,在目前的 ISP 中,Global gamma 和 Local gamma 都会在 pipeline 中,根据产品需要和实际效果,可以单开也可以同时开,以达到最佳的 gamma 亮度调整,但也是主观感受。
就是经过上面两个 Gamma correction 之后的最终 Gamma 系数,理论上来说我们需要把这个做成 1,因为它是理论上比较接近现实世界的显示亮度。但是从实际操作的时候我们一般是把 system gamma 做成一个大于 1 的矫正曲线,这样可以获得更好的动态范围,达到较高对比度的目的。但是更加深入一点去探讨,实际我们应用的时候就更加复杂点儿,我们会根据图像的亮暗区域分别应用不同的 Gamma 校正系数以达到更好的显示效果,当然这个都是比较主观的感受。
我们再回到最初的问题,我们为什么要做 gamma,CRT显示器电压-亮度是一个反 gamma 曲线,但现在的LCD/OLED的显示器已经不需要电子轰击来显示了,也就是可以做到 gamma 是1 的 panel 线性显示,所以肯定不是因为CRT 的反gamma曲线。事实上,是因为 Raw data 也就是图像的存储位宽,位宽导致我们需要对数据进行编码,因为人眼感光特性,线性的对亮度编码自然会理想的使亮度均匀分布,解码就会均匀丢失,但因为人眼对物理世界相对暗部更敏感,需要暗部细节,不需要太多亮部信息,毕竟亮度是无限大的你也看不清,所以我们需要更多暗部信息,所以 ISP gamma 需要是一个 1/2.2 encode 的 gamma,也就直接导致了 panel 上的 Panel gamma 是一个反向的 2.2 的 decode 的 gamma,这样非线性的编解码得到的数据才能达到增加暗部信息减少亮部信息的目的。
所以究其根本原因,是因为人眼的感光特性,而编解码会造成信息丢失,所以才用了 1/2.2 的 gamma encode 方式,减少人眼感光较敏感的暗部信息丢失,早期CRT显示器的反 gamma,只是一个巧合。Raw data 存储位宽限制,导致需要编解码,而编解码一定有亮度损失,而人眼感光特性,不允许其均匀损失,得减小暗部损失,所以才有 encode 的 ISP gamma,所以才有 decode 的 Penal gamma,除非你有无限存储。
最后,gamma 怎么实现,这里,论道法,不学无术