Coverage for colour/models/yrg.py: 100%
41 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"""
2Yrg Colourspace - Kirk (2019)
3=============================
5Define the *Kirk (2019)* *Yrg* colourspace transformations.
7- :func:`colour.models.LMS_to_Yrg`
8- :func:`colour.models.Yrg_to_LMS`
9- :func:`colour.XYZ_to_Yrg`
10- :func:`colour.Yrg_to_XYZ`
12References
13----------
14- :cite:`Kirk2019` : Kirk, R. A. (2019). Chromaticity coordinates for graphic
15 arts based on CIE 2006 LMS with even spacing of Munsell colours. Color and
16 Imaging Conference, 27(1), 215-219. doi:10.2352/issn.2169-2629.2019.27.38
17"""
19from __future__ import annotations
21import numpy as np
23from colour.algebra import sdiv, sdiv_mode, vecmul
24from colour.hints import ( # noqa: TC001
25 Domain1,
26 NDArrayFloat,
27 Range1,
28)
29from colour.utilities import from_range_1, to_domain_1, tsplit, tstack
31__author__ = "Colour Developers"
32__copyright__ = "Copyright 2013 Colour Developers"
33__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
34__maintainer__ = "Colour Developers"
35__email__ = "colour-developers@colour-science.org"
36__status__ = "Production"
38__all__ = [
39 "LMS_to_Yrg",
40 "Yrg_to_LMS",
41 "XYZ_to_Yrg",
42 "Yrg_to_XYZ",
43]
45MATRIX_XYZ_TO_LMS_KIRK2019: NDArrayFloat = np.array(
46 [
47 [0.257085, 0.859943, -0.031061],
48 [-0.394427, 1.175800, 0.106423],
49 [0.064856, -0.076250, 0.559067],
50 ]
51)
52"""
53*Kirk (2019)* matrix converting from *CIE XYZ* tristimulus values to *LMS*
54colourspace.
55"""
57MATRIX_LMS_TO_XYZ_KIRK2019: NDArrayFloat = np.linalg.inv(MATRIX_XYZ_TO_LMS_KIRK2019)
58"""
59*Kirk (2019)* matrix converting from *LMS* colourspace to *CIE XYZ* tristimulus
60values.
61"""
64def LMS_to_Yrg(LMS: Domain1) -> Range1:
65 """
66 Convert from *LMS* cone fundamentals colourspace to *Kirk (2019)* *Yrg*
67 colourspace.
69 Parameters
70 ----------
71 LMS
72 *LMS* cone fundamentals colourspace values.
74 Returns
75 -------
76 :class:`numpy.ndarray`
77 *Kirk (2019)* *Yrg* colourspace array with :math:`Y` luminance,
78 :math:`r` redness, and :math:`g` greenness components.
80 Notes
81 -----
82 +------------+-----------------------+----------------+
83 | **Domain** | **Scale - Reference** | **Scale - 1** |
84 +============+=======================+================+
85 | ``LMS`` | 1 | 1 |
86 +------------+-----------------------+----------------+
88 +------------+-----------------------+----------------+
89 | **Range** | **Scale - Reference** | **Scale - 1** |
90 +============+=======================+================+
91 | ``Yrg`` | 1 | 1 |
92 +------------+-----------------------+----------------+
94 References
95 ----------
96 :cite:`Kirk2019`
98 Examples
99 --------
100 >>> import numpy as np
101 >>> LMS = np.array([0.15639195, 0.06741689, 0.03281398])
102 >>> LMS_to_Yrg(LMS) # doctest: +ELLIPSIS
103 array([ 0.1313780..., 0.4903764..., 0.3777739...])
104 """
106 L, M, S = tsplit(to_domain_1(LMS))
108 Y = 0.68990272 * L + 0.34832189 * M
110 a = L + M + S
112 with sdiv_mode():
113 l = sdiv(L, a) # noqa: E741
114 m = sdiv(M, a)
116 r = 1.0671 * l - 0.6873 * m + 0.02062
117 g = -0.0362 * l + 1.7182 * m - 0.05155
119 Yrg = tstack([Y, r, g])
121 return from_range_1(Yrg)
124def Yrg_to_LMS(Yrg: Domain1) -> Range1:
125 """
126 Convert from *Kirk (2019)* *Yrg* colourspace to *LMS* cone
127 fundamentals colourspace.
129 Parameters
130 ----------
131 Yrg
132 *Kirk (2019)* *Yrg* colourspace array with :math:`Y` luminance,
133 :math:`r` redness, and :math:`g` greenness components.
135 Returns
136 -------
137 :class:`numpy.ndarray`
138 *LMS* cone fundamentals colourspace values.
140 Notes
141 -----
142 +------------+-----------------------+----------------+
143 | **Domain** | **Scale - Reference** | **Scale - 1** |
144 +============+=======================+================+
145 | ``Yrg`` | 1 | 1 |
146 +------------+-----------------------+----------------+
148 +------------+-----------------------+----------------+
149 | **Range** | **Scale - Reference** | **Scale - 1** |
150 +============+=======================+================+
151 | ``LMS`` | 1 | 1 |
152 +------------+-----------------------+----------------+
154 References
155 ----------
156 :cite:`Kirk2019`
158 Examples
159 --------
160 >>> import numpy as np
161 >>> Yrg = np.array([0.13137801, 0.49037644, 0.37777391])
162 >>> Yrg_to_LMS(Yrg) # doctest: +ELLIPSIS
163 array([ 0.1563929..., 0.0674150..., 0.0328213...])
164 """
166 Y, r, g = tsplit(to_domain_1(Yrg))
168 l = 0.95 * r + 0.38 * g # noqa: E741
169 m = 0.02 * r + 0.59 * g + 0.03
170 a = Y / (0.68990272 * l + 0.34832189 * m)
171 L = l * a
172 M = m * a
173 S = (1 - l - m) * a
175 LMS = tstack([L, M, S])
177 return from_range_1(LMS)
180def XYZ_to_Yrg(XYZ: Domain1) -> Range1:
181 """
182 Convert from *CIE XYZ* tristimulus values to *Kirk (2019)* *Yrg*
183 colourspace.
185 Parameters
186 ----------
187 XYZ
188 *CIE XYZ* tristimulus values.
190 Returns
191 -------
192 :class:`numpy.ndarray`
193 *Kirk (2019)* *Yrg* colourspace array with :math:`Y` luminance,
194 :math:`r` redness, and :math:`g` greenness components.
196 Notes
197 -----
198 +------------+-----------------------+----------------+
199 | **Domain** | **Scale - Reference** | **Scale - 1** |
200 +============+=======================+================+
201 | ``XYZ`` | 1 | 1 |
202 +------------+-----------------------+----------------+
204 +------------+-----------------------+----------------+
205 | **Range** | **Scale - Reference** | **Scale - 1** |
206 +============+=======================+================+
207 | ``Yrg`` | 1 | 1 |
208 +------------+-----------------------+----------------+
210 References
211 ----------
212 :cite:`Kirk2019`
214 Examples
215 --------
216 >>> import numpy as np
217 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
218 >>> XYZ_to_Yrg(XYZ) # doctest: +ELLIPSIS
219 array([ 0.1313780..., 0.4903764..., 0.3777738...])
220 """
222 return LMS_to_Yrg(vecmul(MATRIX_XYZ_TO_LMS_KIRK2019, XYZ))
225def Yrg_to_XYZ(Yrg: Domain1) -> Range1:
226 """
227 Convert from *Kirk (2019)* *Yrg* colourspace to *CIE XYZ* tristimulus
228 values.
230 Parameters
231 ----------
232 Yrg
233 *Kirk (2019)* *Yrg* colourspace array with :math:`Y` luminance,
234 :math:`r` redness, and :math:`g` greenness components.
236 Returns
237 -------
238 :class:`numpy.ndarray`
239 *CIE XYZ* tristimulus values.
241 Notes
242 -----
243 +------------+-----------------------+----------------+
244 | **Domain** | **Scale - Reference** | **Scale - 1** |
245 +============+=======================+================+
246 | ``Yrg`` | 1 | 1 |
247 +------------+-----------------------+----------------+
249 +------------+-----------------------+----------------+
250 | **Range** | **Scale - Reference** | **Scale - 1** |
251 +============+=======================+================+
252 | ``XYZ`` | 1 | 1 |
253 +------------+-----------------------+----------------+
255 References
256 ----------
257 :cite:`Kirk2019`
259 Examples
260 --------
261 >>> import numpy as np
262 >>> Yrg = np.array([0.13137801, 0.49037645, 0.37777388])
263 >>> Yrg_to_XYZ(Yrg) # doctest: +ELLIPSIS
264 array([ 0.2065468..., 0.1219717..., 0.0513819...])
265 """
267 return vecmul(MATRIX_LMS_TO_XYZ_KIRK2019, Yrg_to_LMS(Yrg))