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

1"""

2 Recommendation ITU-R BT.2020

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

4

5 Define 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

11 References

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/\

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

19"""

20

21 from __future__ import annotations

22

23 import numpy as np

24

25 from colour.algebra import spow

26 from colour.hints import ( # noqa: TC001

27 Domain1,

28 Range1,

29)

30 from 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

53 CONSTANTS_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

59 CONSTANTS_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

65 smoothly.

66

67 References

68----------

69:cite:`InternationalTelecommunicationUnion2015h`

70"""

71

72

73 def 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

134 def 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))