前言
HDR视频其完成已被传递函数的OETF紧缩过了,如下图所示HDR视频存在传递函数HLG,HDR转SDR需求先用传递函数的EOTF解紧缩,显现前还要用传递函数的OETF紧缩回去,其实普通视频和App开发也要这么处理,然而大多数开发对它不了解导致大多数应用(微信、Mac等)在缩放、含糊、半透明混合等都存在色差问题,本篇文章讲的便是传递函数的正确认知以及如何用传递函数完成色差纠正。如果你觉得有所收获,来给HDR转SDR开源代码点个赞吧,你的鼓舞是我前进最大的动力。
什么是传递函数
摄像头感应天然场景中光的改变用电信号存储下来,显现器把电信号转化成屏幕光信号展示出来,这个传递光的进程就叫传递函数。传递函数包含三个改换,相机收集线性光信号紧缩成暗部细节更多的非线性电信号叫做光电转化(OETF
),屏幕显现时解紧缩的进程叫做电光转化(EOTF)
,批改相机环境和屏幕环境的亮度差异叫做光光转化(OOTF
)。OETF、EOTF、OOTF中O是光optical
的缩写、E是电electro
的缩写、TF是传递函数transfer funciton
的缩写,如下图所示便是传递函数的整个流程。
如下图所示OETF、EOFT、OOTF其实便是三条曲线函数,OETF和EOTF叠加后会变成一根直线。
为了排除外界光照的影响使显现作用更好还要叠加OOTF曲线, 终究变成一根略微向下凹的曲线,比如视频OETFf(x)=x0.5f(x) = x^{0.5},显现器EOTFf(x)=x2.4f(x) = x^{2.4},终究眼睛看到的OOTF曲线便是0.52.4=1.20.52.4=1.2。
从上图中也能够看出来光电转化和电光转化的区别
传递函数 | 作用 |
---|---|
光电转化(OETF) | 1. 线性光信号变成非线性电信号 2. 色彩变亮,函数曲线向上凸 |
电光转化(EOTF) | 1. 非线性电信号变成线性光信号 2. 色彩变暗,函数曲线向下凹 |
色差问题
传递函数听起来这么笼统,不做视频开发不了解好像也没什么吧?传递函数不仅存在视频中还存在图形界面中,运用错误会导致色差问题,互联网的大部分程序都存在色差问题,由于视频进行OETF处理后色彩非线性的,在非线性空间修改色彩会导致色差问题。
用上图测验缩放、半透明混合、高斯含糊三种作用会发现色差问题
图片缩放色差问题
扩大后呈现黑色分界线,用测色计测出中间色是暗色,原图其实是没有的。
正常情况下扩大后红绿还是分明的,如下图所示
扩大是用插值完成的,插值后的色彩看起来很暗,如下图所示。
半透明混合色差问题
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="match_parent">
<View
android:background="#ff0000"
android:layout_width="200dp"
android:layout_height="200dp">
</View>
<View
android:layout_marginLeft="-100dp"
android:background="#8000ff00"
android:layout_width="200dp"
android:layout_height="200dp">
</View>
</LinearLayout>
Android中红色方块上放半透明绿色方块呈现上图中错误的色彩(不符合日子中的知识)。
半透明色混合是通过混合公式合成的,合成的色彩很暗,如下图所示。
高斯含糊色差问题
高斯含糊后正常情况中间区域是红绿渐变
然而Mac上设为桌面后打开LaunchPad却发现变得黑乎乎
微信上设为朋友圈封面也变得黑乎乎
为什么会这样呢?
上图是高斯含糊流程,为了解说便使用平均数替换高斯含糊,右边的色彩看起来很暗,这也是微信和Mac设置高斯含糊变成黑乎乎的原因。
色差问题纠正
色差问题的原因
要知道为什么存在色差问题,首要需求整理一下显现流程。
上图是视频显现流程,录制时通过Gamma编码,显现时会用Gamma解码,其实便是x通过x0.45x^{0.45}后再用x2.2x^{2.2}还原成x。
留意:
-
Gamma函数 f(x)=xf(x) = x^{}(是Gamma的希腊字母)是传递函数的一种,如下图所示不同规范的不相同,曲线也不相同,依据显现器地点环境亮度不同取1.8~3.5,全文用BT709规范=2.2来讨论问题。Gamma编码便是Gamma函数f(x)=x12.2=x0.45f(x)=x^{\frac{1}{2.2}} =x^{0.45},Gamma解码便是Gamma函数f(x)=x2.2f(x)=x^{2.2},两个函数互为可逆。Gamma函数中的Gamma不是Gamma射线是代号,Alpha、Beta、Gamma在开发中不便是版本号吗,Gamma函数天然能够了解成色彩显现前的终究一个版本调色流程。
-
为什么显现流程要先Gamma编码再Gamma解码(先x0.45x^{0.45}再用x2.2x^{2.2}),这么绕不能直接用x吗?这后面会说到,先说一下定论由于拍摄时用Gamma编码x0.45x^{0.45}提亮色彩后暗处细节就能多存一点,而Gamma解码x2.2x^{2.2}是为了还原前面的Gamma编码让显现作用和拍摄时相同。
-
显现器刚开始只要CRT显现器,CRT显现器内部其实是没有Gamma解码的,内部的电子枪发射到荧光粉上的电子会丢掉很巧合地符合了Gamma2.4曲线(Gamma解码),而LED显现器创造今后为了兼容以前的视频人为在屏幕上添加了Gamma解码函数。
那么为什么上述流程在显现时分明是正常的,而在比如高斯含糊、扩大、半透明混合等修改流程时却呈现了色差问题呢?
上图可在Gamma函数色差问题可视化检查,依据上图你会发现红线始终坐落绿线下面,红线表明修改流程的色彩,绿线表明预期的色彩,这便是为什么上述修改流程色彩比较暗的原因。先x0.45x^{0.45}后x2.2x^{2.2}对显现没有影响,对修改却有影响,通过x0.45x^{0.45}后再修改时色彩现已不是线性了,再用x2.2x^{2.2}还原天然有问题了,这便是色差问题的实质,非线性空间修改色彩。
色差问题纠正流程
已然色差问题是由于Gamma函数发生的非线性空间导致的,那么天然也能用Gamma函数纠正色差。视频拍摄时会用Gamma编码,屏幕显现会用Gamma解码,那么修改时只要把逆进程插入到显现流程中就行,如下图所示其实便是先用Gamma解码把非线性变成线性后修改,上屏前再用Gamma编码,也便是先x2.2x^{2.2}后x0.45x^{0.45}。色差纠正包含了Gamma解码和Gamma编码,这也是为什么Gamma编码不用常规叫法Gamma纠正的原因,Gamma纠正很简单误导成只用Gamma纠正就能完成色差纠正,Gamma纠正之所以叫Gamma纠正,不是由于它纠正了色差而是由于它纠正了暗部细节问题。
留意: 上述色差纠正流程在实际开发中有两个战略,个人觉得下方第一种战略比较好,遵从最小改动的一起防止不需求色差纠正时速度变慢。
- 默许不做色差纠正,只在图画处理(交融、含糊等)下运用
- 默许开启色差纠正
把上述流程代入高斯含糊中,如下图所示
留意: 上面只画了修改环节的Gamma解码和编码,显现进程中屏幕本身还会Gammma解码的。
细节丢掉问题
前面说到传递函数是为了处理暗部细节丢掉创造的,那么为什么会丢掉细节呢?如下图右边的色带便是量化带来的细节丢掉问题。实质原因是高精度的物理亮度量化后会丢掉精度,而传递函数使用物理亮度和视觉亮度的联系(视觉对低亮度数据更灵敏)重新分配亮度占比,对低亮度的数据多分配一点,高亮度的数据少分配点。
物理亮度和视觉亮度的联系
上图用照度计测量15盏LED灯的亮度,每盏LED中都放有不同程度的减光片,终究测出每盏灯的亮度如下图所示。
留意:
- 第一行数字表明视觉看到的亮度,亮度呈线形改变,每盏灯的视觉亮度相差相同
- 第二行数字表明物理测量出的亮度,亮度呈倍数上升,每盏灯的物理亮度相差2倍左右
上述实验说明晰视觉中线形改变的亮度对应物理国际中倍数上升的亮度,而物理国际才是实在才是线形的,也便是说视觉是对数的,如下图所示。 。
量化物理亮度带来的问题
物理亮度用电信号存储时需求量化(8位只能保存0-255),如下图所示
留意:
- 黑色到白色的亮度改变叫做灰阶,红框所示物理中性灰是64,视觉中性灰是128。
- 蓝框所示物理灰阶时存在暗部细节变少的问题,中性灰左边只要64位,右边却有192位。
- 为了处理物理灰阶量化时暗部细节变少的问题,只要把物理灰阶的中性灰向右移动变成视觉灰阶就能够了,这个改变便是光电转化,在屏幕显现时需求把视觉灰阶还原成物理灰阶,这个改变便是电光转化。
- 相同大小的视觉灰阶比物理灰阶暗,可是把物理灰阶变成视觉灰阶却是变亮。细细品味一下,物理灰阶64比视觉灰阶64暗,物理灰阶64变成视觉灰阶128虽然在不同色阶中看起来亮度没变,可是在同个色阶64变成128就变大变亮了。在实际开发中有时会纠结运用光电转化还是电光转化,记住光电转化会把色彩变亮,电光转化会把色彩变暗。
细节丢掉问题实质上是低精度存储高精度数据导致的,而传递函数其实便是使用视觉特性重新分配亮度占比的紧缩算法,紧缩亮区域扩展暗细节,如果献身带宽直接用高精度浮点数存储根本就不需求传递函数,其实传递函数和缩小图片道理是相同的,都是为了处理高频信号(高精度)用低频信号(低精度)来表明带来的细节丢掉问题。
问题考虑
下面2个问题留给我们考虑
- 如何在APP开发中处理缩放、半透明混合、高斯含糊的色差问题
- 视觉是对数的,那为什么视频的传递函数却用幂函数不用对数函数呢
系列文章
- HDR转SDR实践之旅(一)流程总结
- HDR转SDR实践之旅(二)解码10位YUV纹理
- HDR转SDR实践之旅(三)YUV420转YUV公式
- HDR转SDR实践之旅(四)YUV转RGB矩阵推导
- HDR转SDR实践之旅(五)色域转化BT2020转BT709
- HDR转SDR实践之旅(六)传递函数与色差纠正
- HDR转SDR实践之旅(七)Gamma、HLG、PQ公式详解
- HDR转SDR实践之旅(八)色彩映射
- HDR转SDR实践之旅(九)HDR开发资源汇总
- HDR转SDR实践之旅(十)SDR转HDR逆色彩映射探究