Coverage for models/rgb/transfer_functions/itur_bt_2020.py: 45%

31 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1""" 

2Recommendation ITU-R BT.2020 

3============================ 

4 

5Define the *Recommendation ITU-R BT.2020* opto-electrical transfer function 

6(OETF) and its inverse. 

7 

8- :func:`colour.models.oetf_BT2020` 

9- :func:`colour.models.oetf_inverse_BT2020` 

10 

11References 

12---------- 

13- :cite:`InternationalTelecommunicationUnion2015h` : International 

14 Telecommunication Union. (2015). Recommendation ITU-R BT.2020 - Parameter 

15 values for ultra-high definition television systems for production and 

16 international programme exchange (pp. 1-8). 

17 https://www.itu.int/dms_pubrec/itu-r/rec/bt/\ 

18R-REC-BT.2020-2-201510-I!!PDF-E.pdf 

19""" 

20 

21from __future__ import annotations 

22 

23import numpy as np 

24 

25from colour.algebra import spow 

26from colour.hints import ( # noqa: TC001 

27 Domain1, 

28 Range1, 

29) 

30from colour.utilities import ( 

31 Structure, 

32 as_float, 

33 domain_range_scale, 

34 from_range_1, 

35 optional, 

36 to_domain_1, 

37) 

38 

39__author__ = "Colour Developers" 

40__copyright__ = "Copyright 2013 Colour Developers" 

41__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" 

42__maintainer__ = "Colour Developers" 

43__email__ = "colour-developers@colour-science.org" 

44__status__ = "Production" 

45 

46__all__ = [ 

47 "CONSTANTS_BT2020", 

48 "CONSTANTS_BT2020_PRECISE", 

49 "oetf_BT2020", 

50 "oetf_inverse_BT2020", 

51] 

52 

53CONSTANTS_BT2020: Structure = Structure( 

54 alpha=lambda x: 1.0993 if x else 1.099, 

55 beta=lambda x: 0.0181 if x else 0.018, 

56) 

57"""*BT.2020* constants.""" 

58 

59CONSTANTS_BT2020_PRECISE: Structure = Structure( 

60 alpha=lambda x: 1.09929682680944, # noqa: ARG005 

61 beta=lambda x: 0.018053968510807, # noqa: ARG005 

62) 

63""" 

64*BT.2020* constants at double precision to connect the two curve segments 

65smoothly. 

66 

67References 

68---------- 

69:cite:`InternationalTelecommunicationUnion2015h` 

70""" 

71 

72 

73def oetf_BT2020( 

74 E: Domain1, 

75 is_12_bits_system: bool = False, 

76 constants: Structure | None = None, 

77) -> Range1: 

78 """ 

79 Apply the *Recommendation ITU-R BT.2020* opto-electronic transfer function 

80 (OETF). 

81 

82 Parameters 

83 ---------- 

84 E 

85 Voltage :math:`E` normalised by the reference white level and 

86 proportional to the implicit light intensity that would be detected 

87 with a reference camera colour channel R, G, B. 

88 is_12_bits_system 

89 *BT.709* *alpha* and *beta* constants are used if system is not 

90 12-bit. 

91 constants 

92 *Recommendation ITU-R BT.2020* constants. 

93 

94 Returns 

95 ------- 

96 :class:`numpy.ndarray` 

97 Non-linear signal :math:`E'`. 

98 

99 Notes 

100 ----- 

101 +------------+-----------------------+---------------+ 

102 | **Domain** | **Scale - Reference** | **Scale - 1** | 

103 +============+=======================+===============+ 

104 | ``E`` | 1 | 1 | 

105 +------------+-----------------------+---------------+ 

106 

107 +------------+-----------------------+---------------+ 

108 | **Range** | **Scale - Reference** | **Scale - 1** | 

109 +============+=======================+===============+ 

110 | ``E_p`` | 1 | 1 | 

111 +------------+-----------------------+---------------+ 

112 

113 References 

114 ---------- 

115 :cite:`InternationalTelecommunicationUnion2015h` 

116 

117 Examples 

118 -------- 

119 >>> oetf_BT2020(0.18) # doctest: +ELLIPSIS 

120 0.4090077... 

121 """ 

122 

123 E = to_domain_1(E) 

124 constants = optional(constants, CONSTANTS_BT2020) 

125 

126 a = constants.alpha(is_12_bits_system) 

127 b = constants.beta(is_12_bits_system) 

128 

129 E_p = np.where(b > E, E * 4.5, a * spow(E, 0.45) - (a - 1)) 

130 

131 return as_float(from_range_1(E_p)) 

132 

133 

134def oetf_inverse_BT2020( 

135 E_p: Domain1, 

136 is_12_bits_system: bool = False, 

137 constants: Structure | None = None, 

138) -> Range1: 

139 """ 

140 Apply the *Recommendation ITU-R BT.2020* inverse opto-electronic transfer function 

141 (OETF). 

142 

143 Parameters 

144 ---------- 

145 E_p 

146 Non-linear signal :math:`E'`. 

147 is_12_bits_system 

148 *BT.709* *alpha* and *beta* constants are used if system is not 

149 12-bit. 

150 constants 

151 *Recommendation ITU-R BT.2020* constants. 

152 

153 Returns 

154 ------- 

155 :class:`numpy.ndarray` 

156 Voltage :math:`E` normalised by the reference white level and 

157 proportional to the implicit light intensity that would be detected 

158 with a reference camera colour channel R, G, B. 

159 

160 Notes 

161 ----- 

162 +------------+-----------------------+---------------+ 

163 | **Domain** | **Scale - Reference** | **Scale - 1** | 

164 +============+=======================+===============+ 

165 | ``E_p`` | 1 | 1 | 

166 +------------+-----------------------+---------------+ 

167 

168 +------------+-----------------------+---------------+ 

169 | **Range** | **Scale - Reference** | **Scale - 1** | 

170 +============+=======================+===============+ 

171 | ``E`` | 1 | 1 | 

172 +------------+-----------------------+---------------+ 

173 

174 References 

175 ---------- 

176 :cite:`InternationalTelecommunicationUnion2015h` 

177 

178 Examples 

179 -------- 

180 >>> oetf_inverse_BT2020(0.705515089922121) # doctest: +ELLIPSIS 

181 0.4999999... 

182 """ 

183 

184 E_p = to_domain_1(E_p) 

185 constants = optional(constants, CONSTANTS_BT2020) 

186 

187 a = constants.alpha(is_12_bits_system) 

188 b = constants.beta(is_12_bits_system) 

189 

190 with domain_range_scale("ignore"): 

191 E = np.where( 

192 E_p < oetf_BT2020(b), 

193 E_p / 4.5, 

194 spow((E_p + (a - 1)) / a, 1 / 0.45), 

195 ) 

196 

197 return as_float(from_range_1(E))