HDR中HLG与PQ曲线的互转

article/2025/8/16 9:06:07

      HDR视频中由于电光转换曲线的不同,技术标准也大致分为了杜比视界、HDR10+、HDR10、HLG等,目前常用的主要是以PQ曲线的HDR10和HLG。这两者之间的区别在HDR视频编码参数中进行过详细的说明。一般的HLG适用于广电(根据用户设备的峰值亮度动态的调整最高显示亮度),PQ适用于数码电脑等(绝对的亮度,如果设备达不到,则进行削峰)。他们之间根据不同的用户选择不同的技术标准。如果知道其中一个技术标准的HDR视频,其实是可以转换为另外一个的。

基本概念

色彩值(color value)

色彩值是用于描述一张图像中特定颜色分量(如R、G、B或Y)的数值。

数字编码值(digital code value)

一张图像信号值的数字表示,通常是非线性的颜色值。

电光转换函数(EOTF)

用于描述输入显示器的非线性颜色值(数字编码像素值E^{'})和显示器所显示的线性颜色值(F_{D})之间的关系。

光电转换函数(OETF)

用于描述线性颜色值E与非线性颜色值(数字编码像素值,E^{'})之间的关系。注意这里的线性颜色值是自然场景中的颜色值。而EOTF中的光是显示器的线性颜色值。

    之前也提到过,之所以有所谓的光电、电光转换函数,主要还是为了节省视频码率,在人眼对光线亮度的敏感区域分配更多的数值来表达光线的程度。

光光转换函数(OOTF)

用于描述相机捕获光线值(E)与显示器所显示光线强度F_{D}之间的关系。OOTF一方面可以通过后期进行所谓的艺术渲染对色彩进行调整,可以看成是OETF、艺术调整和EOTF的连结,另一方面也是对HLG技术的关键,因为根据不同显示亮度峰值的设备,通过该函数进行光程度的重新映射。

EOTF、OETF、OOTF三者是相互关联的,所以三者中只有两个是独立的。给定任何两个可以计算第三个

高动态范围(HDR)

图像或显示设备可以存储或显示的亮度等级范围要远大于传统成像系统。在SMPTE 2084标准中设定峰值亮度为10000 nits。

线性颜色值(Linear Color Value)

缩写记为L,归一化到[0, 1],与显示设备的输出光线强度成正比,但不与图像信号的编码值成正比,如场景线性光,显示线性光。

非线性值(Nonlinear Color Value)

缩写记为N,归一化到[0, 1],与图像信号的编码值成正比,但不予显示设备的输出光强度成正比。 

电视信号链(Television signal chain)

描述从相机的信号采集到显示器显示的整个过程,包括相机和显示器两部分的非线性变化。相机采集部分的非线性化由OETF描述,显示器显示部分非线性化由EOTF描述,整个流程如下:

不同技术标准之间的光电、电光转换公式是不一样的。可从这里下载BT.2100技术标准文档,以及其他的参考标准,下面分别进行介绍

SDR

这个通常比较熟悉,就是平常常用的gamma校正。针对SDR的亮度范围100nits,通过经验以及实验,发现可以使用幂函数来拟合亮度和人眼感知这种非线性的映射,公式表示:Y=X^\gamma

  • X 是使用 0-1 之间的实数表示的输入亮度;
  • Y 是使用 0-1 之间实数表示的输出亮度;
  • \gamma为设定的参数,通过调整\gamma的取值来调整输入输出亮度之间映射关系的方式,称之为 gamma 校正

encoding gamma 函数和display gamma 函数,对应OETF和EOTF

  • 摄像机中会使用一种 encoding gamma 函数进行 gamma 校正,这里的 gamma 值小于 1。
  • 显示阶段的使用一种 display gamma 函数来完成,这里的 gamma 值大于 1。
  • 大部分计算机显示系统 encoding gamma 大约是 0.45(也就是 1/2.2),display gamma是2.2。

PQ

基于PQ的HDR系统是一个绝对系统,对于输入的线性场景光,根据创作者的意图,选择合适的OOTF将场景光转换为最终用于显示的显示光,利用PQ逆EOTF将显示光转换为非线性的电信号,到了显示终端再采用PQ的EOTF 将电信号还原为显示光显示,PQ规的是EOTF曲线,描述了显示亮度的绝对亮度,最高亮度是10000cd/m2,如果前端制作的是显示峰值亮度为10000cd/m的PQ节目,最终得到的显示光亮度也为1000cd/m.如果显示设备显示能力不匹配时,例如:显示设备的色域小于母带的色域或者显示设备的亮度范围要小于母带的亮度范围,那么,设备就会根据这些静态元数据将色域和亮度范围相对地缩小到显示设备的范围内.

电光转换方程EOTF:

电光转换的逆运算:Inverse EOTF

电光转换的逆运算并不是OETF,光电转换曲线是光线采集端(相机等)将光线信号转换成电信号(编码值)

E^'表示非线性的像素编码值;

Y 表示对应的线性色彩值;

F_{}D  和Y成线性关系,表示对应的显示器光线输出值单位为nit。

m1= 2610/4096 ×1/4 = 0.1593017578125;

m2=2523/4096 ×128 = 78.84375;

c1= 3424/4096 = 0.8359375 =C3 - C2 + 1;

c2= 2413/4096×32 = 18.8515625;

c3= 2392/4096 × 32 = 18.6875;

因为PQ曲线表现光亮度的绝对性,从Inverse EOTF中的公式中可以提取到FD = OOTF[E]的信息。而FD最高亮度是表示的是10000nit。E在这里应当是表示的大自然场景(或者理解为摄影场景)的亮度(或者色彩度)。这里做了一个光光之间的转换。而经过了光光转换函数以后,Inverse EOTF就可以当成OETF的转换函数。

光光转换函数OOTF

在次提一句,由于PQ曲线显示亮度的绝对性,这些流程的参数一经制作就不再改变。比如说,拿到一个基于PQ转换曲线的MP4视频文件。其显示流程可表示成:

而在制作HDR视频文件时。E^{'}=OETF[E]=EOTF^{-1}[OOTF[E]],根据母带信息一经做了相关的光光转换。

HLG

HLG逆EOTF将电信号还原为场景光,再利用OOTF将场景光转换为显示光显示.HLG规定的是OETF曲线,描述了场景光的亮度当显示设备的亮度与原始场景光亮度不一致时,可以利用OOTF进行适配,而不需要额外的元数据.

不同于PQ转换曲线视频的播放设备必须和录制设备保持一致(或者向下兼容)才能正常显示画面,HLG对播放设备要求不是那么严格,是因为在播放前经过了scene luminance到display luminance的转换。

光电转换方程OETF

a = 0.17883277, b =1− 4a= 0.28466892, c = 0.5 − a ln(4a)== 0.55991073.

光光转换方程OOTF

之前已经介绍了,光光转换方程是自然光到显示器显示的光强度的映射方程。自然光亮度可以称为scene luminance(上面提到的场景光信号,线性光信号),显示器亮度可以成为display luminance。因此,带有S下标的一般都表示在自然光下的相关参数,带有D下标的是和显示器亮度有关的参数。HLG的光光转换方程为:

其中部分参数意义在PQ曲线中已经介绍。

Y_{S}与R,G,B的关系其实就是yuv和rgb格式转换的公式,这里就是表示scene luminance,当然他是在BT.2020标准下的。这个在之前介绍过。

\gamma是系统伽马射线 。显示器的标称峰值亮度为 1000cd/m2 时 ,其值为1.2

如果显示器的峰值亮度不是 1000cd/m2,那么可以通过下面的公式对伽马值进行调整

\alpha是以cd/m 2 为单位的用户增益变量。它代表L_{W} ,是显示器消色差像元的标称峰值亮度。

有光光转换也可以推出逆光光转换方程:

并且当不知道目标显示器的峰值亮度是,一般\alpha设为1.0。

电光转换方程EOTF

电光转换曲线是硬盘内的电信号转换成显示屏的光信号,在整个流程中有如下等价关系:

其中EOTF和OOTF就是上面所介绍的光电和光光转换方程。

逆光电转换方程:

a、b、c和光电转换方程中的参数一样,即a = 0.17883277, b =1− 4a= 0.28466892, c = 0.5 − a ln(4a)== 0.55991073.

β是用于提升用户黑色水平的变量

L_{W} 是以cd/m 2 为单位时消色差像素屏幕显示的额定峰值亮度

L_{B} 是以cd/m 2 为单位时黑色的屏幕显示亮度。

其中的\chi即是E^{'}

小节

通过以上分析可以看出PQ和HLG两者之间不仅仅是一个量化曲线的改变,而是整个系统的标示。三个关键术语OETF、OOTF、EOTF在不同的系统中,除了所用公式有所不同,在制作和使用过程中的顺序也有所不同。

PQ系统采用如下所示的模型设计,其中OOTF在摄像机中(或施加于制作过程中)

HLG系统采用如下所示的模型设计,其中OOTF在显示器中

OETF、EOTF和OOTF两两独立,之间的转换关系可以表示如下:

PQ方法由其EOTF定义。对于PQ,OETF可以使用上述等式的第三行从OOTD得出。用一种互补的方式,HLG方法由其OETF定义。对于HLG, EOTF可以使用上述等式的第二行从OOTF得出

HLG与PQ曲线的互转

两个系统的转换是参考的BBC的流程,该流程里面提到了一个非常有用的HDR工具。

PQ->HLG:

整个流程可以如下图表示:

从目标结果上看是PQ Signal -> HLG Signal的过程。其余的均为显示过程。但是显示目标是Display light要保持一致。所以基于PQ曲线的最终显示要和HLG的一样。通过前面介绍的,HDR视频的制作以及显示流程。我们要通过HLG的EOTF^{-1}(逆电光转换)。

并通过小节中的图二可知,HLG的EOTF过程包括inverse OETF + OOTF。那么EOTF^{-1}=OOTF^{-1} + OETF 

在上面的小节中我们已经知道,PQ方法由其EOTF定义,HLG方法由其OETF定义。现在整个流程就只剩inverse OOTF,OOTF^{-1}通过下图求解

1)通过Figure可知需要知道输入Display Light = PQ(EOTF).即通过PQ曲线的电光曲线求得。

2)对第一步求得的亮度进行规范化,这一步主要是因为,PQ曲线表示亮度的绝对性,需要使用主监视器最高亮度把归一化线性光转换为显示线性光。主监视器最高亮度表示终端显示该信号所能达到的最高亮度,该亮度值可通过对信号内容进行分析得到,也可以通过元数据得到比如说在最高亮度为1000nit的显示屏上,经过相应元数据信息的处理后,大于1000bit亮度在该标准的显示器上是无法正常显示的,即,大于1000nit的都以1000nit进行显示,被clip。通过公式可以表示成:

Y即是PQ的EOTF公式的输出值,可在上面查找到。这里是想当重要的一个转换,因为,假如在PQ的EOTF后,得到的结果是RD,GD,BD。如果标准显示器为1000nit,那么下面通过Y_{d}=0.2627R_{d} + 0.6780G_{d} + 0.0593B_{d}中的R_{d} = 10*RD,G_{d}=10*GD,B_{d}=10*BD. 总之,这里是显示的nit值并进行了归一化,也可以想成将超过1000nit的值置为1000,并对0-1000规范化到0-1,(成为nit可能不太标准,因为nit是亮度,而我们这里都是RGB的颜色值)

3)通过,逆OOTF需要先求得Y,因此需要根据YUV-RGB在bt2020颜色空间下的转换公式进行求出:Y_{d}=0.2627R_{d} + 0.6780G_{d} + 0.0593B_{d}

下标是d标示,标示是display显示器上的值。

4)通过逆的伽马曲线得出场景亮度:Y_{s}=(Y_{d})^{1/\gamma },在HLG的OOTF介绍中说过,如果显示器和母带信息亮度峰值不同时,可以通过\gamma =1.2 + 0.42Log_{10}(L_{w}/1000))进行改变。并通过HLG的逆光光转换曲线:

得出场景颜色数值。

5)通过HLG的OETF的公式即可求得。这里应当注意的是,完全按照BT.2100-0标准定义的公式中的注意事项5a,在执行OETF公式时需要先乘以12.如果是注意事项5b则不需要。

HLG->PQ

首先看一下整体的流程:

和PQ->HLG一样,我们要达到的目的就是保持在同一显示器下转换前后两个格式观看的效果是一样的。也就是Display Light保持一致,目标是从Display Light-PQ Signal:

由于PQ方法由EOTF定义,那么inverse EOTF公式也能直接求出,这个在PQ曲线介绍中公式已经给出。所以重点还是在于HLG的EOTF。根据小节图二的信息,HLG的EOTF过程包括inverse OETF + OOTF。

其中,HLG的inverse OETF在HLG曲线中就已经介绍过,那么就只剩OOTF。

1)在HLG的inverse OETF中,我们还是按照已经归一化的公式(非归一化有其他公式),即

2)OOTF的计算过程也已经提到过,即:

这里的L_{W}是目标PQ曲线的显示屏的亮度。

3)然后进行规范化:

其中E_{D}代表着R_{D},G_{D},B_{D}

4)通过PQ曲线的inverse EOTF即可得出结果:

c和m系列的值已经提到过。

其他

另一方面也可以通过使用3D look up table(LUT)的方式来进行两者的互转,但是前提条件是,在使用LUT时,一般都是R、G、B格式进行输入的。因此在使用是,如果是YUV格式,需要进行格式的转换。

PQ-HLG code

a_2020 = 0.2627
b_2020 = 0.6780
c_2020 = 0.0593
d_2020 = 1.8814
e_2020 = 1.4747m1 = (2610.0) / (4096.0 * 4.0)
m2 = (2523.0 * 128.0) / 4096.0
c1 = (3424.0) / 4096.0
c2 = (2413.0 * 32.0) / 4096.0
c3 = (2392.0 * 32.0) / 4096.0m2_inverse = 1.0/m2
m1_inverse = 1.0/m1
a = 0.17883277
b = 0.28466892
c = 0.55991073
hlg_tsd = 0.083333333
gamma = 1.2def RGB2YUV_bt2020(R,G,B,w=960,h=540):Y = a_2020 * R + b_2020 * G + c_2020 * BCb = (B - Y) / d_2020Cr = (R - Y) / e_2020Y = (219*Y + 16) * 4Cb = (224*Cb + 128) * 4Cr = (224*Cr + 128) * 4Y = np.around(Y).astype(np.uint16)Cb = np.around(Cb).astype(np.uint16)Cr = np.around(Cr).astype(np.uint16)Cb = cv.resize(Cb, (w, h), interpolation=cv.INTER_LINEAR)Cr = cv.resize(Cr, (w, h), interpolation=cv.INTER_LINEAR)return Y,Cb,Crdef HLG_OETF(E):E_p = np.where(E < hlg_tsd, np.power(3*E,0.5), a*np.log(12*E-b)+c)return E_pdef pq_EOTF(E_p):E_i = np.power(E_p,m2_inverse)e_i = E_i - c1E_0 = np.maximum(e_i, 0)deno = c2 - c3*E_iY_i = E_0/denoreturn np.power(Y_i, m1_inverse) def YUV2RGB_bt2020(Y,U,V):Cb = UCr = VY = (Y/4 - 16)/219Cb = (Cb/4 - 128)/224Cr = (Cr/4 - 128)/224R = Y + e_2020 * CrG = Y - (a_2020 * e_2020 / b_2020) * Cr - (c_2020 * d_2020 / b_2020) * CbB = Y + d_2020 * CbR = R.clip(0.0, 1.0)G = G.clip(0.0, 1.0)B = B.clip(0.0, 1.0)return R,G,Bdef PQ2HLG_trans(Y,U,V,height, width):R, G, B = YUV2RGB_bt2020(yuv[:, :, 0], yuv[:, :, 1], yuv[:, :, 2])Rd = pq_EOTF(R)Gd = pq_EOTF(G)Bd = pq_EOTF(B)Rd = np.minimum(Rd*10,1.0)Gd = np.minimum(Gd*10,1.0)Bd = np.minimum(Bd*10,1.0)YD = 0.2627*Rd + 0.6780*Gd + 0.0593*BdYD_gamma = np.power(YD,(1-gamma)/gamma)Rs = Rd * YD_gammaGs = Gd * YD_gammaBs = Bd * YD_gammahlg_R = HLG_OETF(Rs)hlg_G = HLG_OETF(Gs)hlg_B = HLG_OETF(Bs)Y,Cb,Cr = RGB2YUV_bt2020(hlg_R,hlg_G,hlg_B,width//2,height//2)return Y,Cb,Cr


http://chatgpt.dhexx.cn/article/fHMaqsEI.shtml

相关文章

使用DataList吧

这是个具有明显煽动性的标题&#xff0c;没错&#xff0c;在这里就是提议大家使用DataList。在MSDN中文站有一篇关于repeater&#xff0c;datalist和datagrid的性能测试的文章&#xff0c;我也把这篇文章转到了我的站的“转载嘿嘿 希望你接受我的教训 一定早做打算 精华”里&am…

html5-datalist标签-定义选项列表

datalist使用 datalist使用需与input关联起来&#xff0c;input定义list属性&#xff0c;同时datalist定义id属性&#xff0c;两者的值必须相同。 实例代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><m…

常用数据集合—List

1、List、Map、Set、Queue、Array 2、数据结构&#xff1a;数组、链表 3、实现List方法的类Ctrl T&#xff08;设置的是Eclipse快捷键&#xff09;或右键查找 4、这里就简单看下最常用的ArrayList 5、构造方法一目了然 6、添加数据&#xff0c;一条条添加或者添加集合 良好…

DataList的数据绑定

8.4.1 DataList的数据绑定 DataList控件中通过自定义模板来设置数据的显示样式&#xff0c;它支持如下模板类型&#xff1a; ItemTemplate&#xff1a;包含一些 HTML元素和控件&#xff0c;将为数据源中的每一行呈现一次这些HTML元素和控件。 AlternatingItemTemplate&#xf…

datalist标签

学习笔记&#xff0c;仅供参考&#xff0c;有错必纠 参考自&#xff1a;w3school 关于datalist标签 <datalist> 标签定义选项列表&#xff0c;应该与 <input>标签配合使用该&#xff0c;它定义 input 可能的值&#xff1b; <datalist> 及其选项不会被显示出…

datalist 元素

效果图&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>datalist 元素</title> </head> <body><form action"#" method"post">请输入用户…

<datalist>标签

<datalist>标签是HTML5新增的元素&#xff0c;用于input的标签可选值。 用法&#xff1a;input标签的list属性指定自定义的datalist可选值&#xff0c;datalist的id于list值相同即可完成绑定。 可选值: <input type"text" list"myDatalist">…

数据列表DataList模板之实例

1&#xff0c;数据列表DataList与重复列表Repeator很类似&#xff0c;但是DataList应用更广泛&#xff0c;因为他可以选择和修改数据项的内容。 DataList的数据显示和布局与Repeator控件一样都是通过“模板”控制的。 &#xff08;注&#xff1a;模板至少要定义一个“数据项模…

DataList详细用法

DataList控件与Repeater控件一样由模板驱动,与Repeater控件不同的是: DataList控件默认输出是一个HTML表格.DataList在输出时已经在相应的模板上套上了表格标签,而Repeater则是模板是什么样,输出就是什么样. 1. DataList显示数据 例1:使用DataList显示数据 Code <as…

DataList 用法详解

<% Page Language"C#" AutoEventWireup"true" CodeBehind"DataList.aspx.cs" Inherits"FileUpload自动上传文件.DataList" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w…

datalist标签使用

jsp使用datalist标签写可查询可输入下拉框样式 jsp使用datalist标签写可查询可输入下拉框样式。需求用法 jsp使用datalist标签写可查询可输入下拉框样式。 需求 jsp页面实现可选择,可查询,可输入的下拉选择框, 一段废话 本来想用select看看有什么属性可以实现,但基本上接触的…

DataList内容详解

DataList是另一种显示数据控件&#xff0c;它与GridView不同的是&#xff0c;它全部使用模板进行设计&#xff0c;并且DataList的模板是对整行设置&#xff0c;而不是像GridView那样只对某一列进行模板设计。 正是由于它使用模板进行设计&#xff0c;所以它的灵活性比GridView更…

DataList控件详细用法(一)

使用DataList控件 本章内容&#xff1a; 1、理解事件冒泡 2、使用模板 3、在DataList中显示数据 4、在DataList中创建多列 5、捕获DataList控件中产生的事件 6、选择DataList中的项 7、使用DataList控件中的DataKeys集合 8、编辑DataList中的项 本章介绍在ASP.NET框架中功能…

(13)<datalist> 标签

一、<datalist>标签的作用 <datalist> 标签规定了<input> 元素可能的选项列表。<datalist>元素包含了一组<option>元素&#xff0c;这些元素表示预定义可选值&#xff0c;在<input>元素输入过程中&#xff0c;会自动响应<option>元…

Hibernate缓存的evict、clear和flush方法

evict()、clear()和flush()方法是Hibernate缓存的3种基本操作方法&#xff0c;本文主要介绍这3种方法的使用方式和具体区别。 Company表&#xff1a; Company实体类&#xff1a; import java.util.Set;public class Company {private int companyId;private String companyName…

注册中心日志输出_Running the evict task with compensationTime 0ms_频繁输出这句_SpringCloud工作笔记161

可以在:application.properties 中配置一下不停的打印日志,太烦人了.##Running the evict task with compensationTime 0ms不停的输出这个太烦人了可以关闭 logging.level.com.netflixwarn技术交流QQ群【JAVA,C,Python,.NET,BigData,AI】&#xff1a;170933152 开通了个人技术微…

SpringCloud Eureka注册中心日志输出问题:Running the evict task with compensationTime 0ms

动Eureka注册中心后&#xff0c;控制台一直输出 — [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 0ms 这段日志&#xff0c;间隔时间与你的配置有关。强迫症看着很烦&#xff0c;那么在开发过程中如何关闭这条日…

HashMap中的putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)解读

在面试中我们会经常遇到关于HashMap的问题&#xff0c;这里我写了我对HashMap里面一个挺重要的方法 putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)的理解&#xff0c;下面就是我对这个方法的理解。 其实putVal(int hash, K key, V value, boolean o…

org.hibernate.Session.evict(Object object)方法的使用

在一个实体A、B的关联关系中&#xff0c;如下图&#xff1a; B外键关联A&#xff0c;关联字段A_id A中保存有B的集合blist 在A的实体属性blist&#xff0c;使用懒加载注解&#xff0c;如下: OneToMany(targetEntityB.class, cascade CascadeType.ALL, fetch FetchType.LAZY)…