Coverage for colour/models/rgb/transfer_functions/itur_bt_2020.py: 100%
31 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-15 19:01 +1300
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-15 19:01 +1300
1"""
2Recommendation ITU-R BT.2020
3============================
5Define the *Recommendation ITU-R BT.2020* opto-electrical transfer function
6(OETF) and its inverse.
8- :func:`colour.models.oetf_BT2020`
9- :func:`colour.models.oetf_inverse_BT2020`
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"""
21from __future__ import annotations
23import numpy as np
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)
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"
46__all__ = [
47 "CONSTANTS_BT2020",
48 "CONSTANTS_BT2020_PRECISE",
49 "oetf_BT2020",
50 "oetf_inverse_BT2020",
51]
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."""
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.
67References
68----------
69:cite:`InternationalTelecommunicationUnion2015h`
70"""
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).
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.
94 Returns
95 -------
96 :class:`numpy.ndarray`
97 Non-linear signal :math:`E'`.
99 Notes
100 -----
101 +------------+-----------------------+---------------+
102 | **Domain** | **Scale - Reference** | **Scale - 1** |
103 +============+=======================+===============+
104 | ``E`` | 1 | 1 |
105 +------------+-----------------------+---------------+
107 +------------+-----------------------+---------------+
108 | **Range** | **Scale - Reference** | **Scale - 1** |
109 +============+=======================+===============+
110 | ``E_p`` | 1 | 1 |
111 +------------+-----------------------+---------------+
113 References
114 ----------
115 :cite:`InternationalTelecommunicationUnion2015h`
117 Examples
118 --------
119 >>> oetf_BT2020(0.18) # doctest: +ELLIPSIS
120 0.4090077...
121 """
123 E = to_domain_1(E)
124 constants = optional(constants, CONSTANTS_BT2020)
126 a = constants.alpha(is_12_bits_system)
127 b = constants.beta(is_12_bits_system)
129 E_p = np.where(b > E, E * 4.5, a * spow(E, 0.45) - (a - 1))
131 return as_float(from_range_1(E_p))
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).
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.
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.
160 Notes
161 -----
162 +------------+-----------------------+---------------+
163 | **Domain** | **Scale - Reference** | **Scale - 1** |
164 +============+=======================+===============+
165 | ``E_p`` | 1 | 1 |
166 +------------+-----------------------+---------------+
168 +------------+-----------------------+---------------+
169 | **Range** | **Scale - Reference** | **Scale - 1** |
170 +============+=======================+===============+
171 | ``E`` | 1 | 1 |
172 +------------+-----------------------+---------------+
174 References
175 ----------
176 :cite:`InternationalTelecommunicationUnion2015h`
178 Examples
179 --------
180 >>> oetf_inverse_BT2020(0.705515089922121) # doctest: +ELLIPSIS
181 0.4999999...
182 """
184 E_p = to_domain_1(E_p)
185 constants = optional(constants, CONSTANTS_BT2020)
187 a = constants.alpha(is_12_bits_system)
188 b = constants.beta(is_12_bits_system)
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 )
197 return as_float(from_range_1(E))