Coverage for models/cie_xyy.py: 60%
45 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-16 22:49 +1300
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-16 22:49 +1300
1"""
2Tristimulus Values, CIE xyY Colourspace and Chromaticity Coordinates
3====================================================================
5Define the *CIE xyY* colourspace transformations.
7- :func:`colour.XYZ_to_xyY`
8- :func:`colour.xyY_to_XYZ`
9- :func:`colour.xyY_to_xy`
10- :func:`colour.xy_to_xyY`
11- :func:`colour.XYZ_to_xy`
12- :func:`colour.xy_to_XYZ`
14References
15----------
16- :cite:`CIETC1-482004h` : CIE TC 1-48. (2004). CIE 015:2004 Colorimetry,
17 3rd Edition. In CIE 015:2004 Colorimetry, 3rd Edition. Commission
18 Internationale de l'Eclairage. ISBN:978-3-901906-33-6
19- :cite:`Wikipedia2005` : Wikipedia. (2005). CIE 1931 color space. Retrieved
20 February 24, 2014, from http://en.wikipedia.org/wiki/CIE_1931_color_space
21"""
23from __future__ import annotations
25import numpy as np
27from colour.algebra import sdiv, sdiv_mode
28from colour.hints import ( # noqa: TC001
29 ArrayLike,
30 Domain1,
31 NDArrayFloat,
32 Range1,
33)
34from colour.utilities import as_float_array, from_range_1, to_domain_1, tsplit, tstack
36__author__ = "Colour Developers"
37__copyright__ = "Copyright 2013 Colour Developers"
38__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
39__maintainer__ = "Colour Developers"
40__email__ = "colour-developers@colour-science.org"
41__status__ = "Production"
43__all__ = [
44 "XYZ_to_xyY",
45 "xyY_to_XYZ",
46 "xy_to_xyY",
47 "xyY_to_xy",
48 "XYZ_to_xy",
49 "xy_to_XYZ",
50]
53def XYZ_to_xyY(XYZ: Domain1) -> Range1:
54 """
55 Convert from *CIE XYZ* tristimulus values to *CIE xyY* colourspace.
57 Parameters
58 ----------
59 XYZ
60 *CIE XYZ* tristimulus values.
62 Returns
63 -------
64 :class:`numpy.ndarray`
65 *CIE xyY* colourspace array with chromaticity coordinates
66 :math:`x, y` and luminance :math:`Y`.
68 Notes
69 -----
70 +------------+-----------------------+---------------+
71 | **Domain** | **Scale - Reference** | **Scale - 1** |
72 +============+=======================+===============+
73 | ``XYZ`` | 1 | 1 |
74 +------------+-----------------------+---------------+
76 +------------+-----------------------+---------------+
77 | **Range** | **Scale - Reference** | **Scale - 1** |
78 +============+=======================+===============+
79 | ``xyY`` | 1 | 1 |
80 +------------+-----------------------+---------------+
82 References
83 ----------
84 :cite:`CIETC1-482004h`, :cite:`Wikipedia2005`
86 Examples
87 --------
88 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
89 >>> XYZ_to_xyY(XYZ) # doctest: +ELLIPSIS
90 array([ 0.5436955..., 0.3210794..., 0.1219722...])
91 """
93 XYZ = to_domain_1(XYZ)
95 X, Y, Z = tsplit(XYZ)
97 X_Y_Z = X + Y + Z
99 with sdiv_mode():
100 x = sdiv(X, X_Y_Z)
101 y = sdiv(Y, X_Y_Z)
103 return tstack([x, y, from_range_1(Y)])
106def xyY_to_XYZ(xyY: Domain1) -> Range1:
107 """
108 Convert from *CIE xyY* colourspace to *CIE XYZ* tristimulus values.
110 Parameters
111 ----------
112 xyY
113 *CIE xyY* colourspace array with chromaticity coordinates
114 :math:`x, y` and luminance :math:`Y`.
116 Returns
117 -------
118 :class:`numpy.ndarray`
119 *CIE XYZ* tristimulus values.
121 Notes
122 -----
123 +------------+-----------------------+---------------+
124 | **Domain** | **Scale - Reference** | **Scale - 1** |
125 +============+=======================+===============+
126 | ``xyY`` | 1 | 1 |
127 +------------+-----------------------+---------------+
129 +------------+-----------------------+---------------+
130 | **Range** | **Scale - Reference** | **Scale - 1** |
131 +============+=======================+===============+
132 | ``XYZ`` | 1 | 1 |
133 +------------+-----------------------+---------------+
135 References
136 ----------
137 :cite:`CIETC1-482004h`, :cite:`Wikipedia2005`
139 Examples
140 --------
141 >>> xyY = np.array([0.54369557, 0.32107944, 0.12197225])
142 >>> xyY_to_XYZ(xyY) # doctest: +ELLIPSIS
143 array([ 0.2065400..., 0.1219722..., 0.0513695...])
144 """
146 xyY = as_float_array(xyY)
148 x, y, Y = tsplit(xyY)
149 Y = to_domain_1(Y)
151 with sdiv_mode():
152 Y_y = sdiv(Y, y)
154 XYZ = tstack([x * Y_y, Y, (1 - (x + y)) * Y_y])
156 return from_range_1(XYZ)
159def xyY_to_xy(xyY: Domain1) -> NDArrayFloat:
160 """
161 Convert from *CIE xyY* colourspace to *CIE xy* chromaticity
162 coordinates.
164 ``xyY`` argument with last dimension being equal to 2 will be
165 assumed to be a *CIE xy* chromaticity coordinates argument and will
166 be returned directly by the definition.
168 Parameters
169 ----------
170 xyY
171 *CIE xyY* colourspace array or *CIE xy* chromaticity
172 coordinates.
174 Returns
175 -------
176 :class:`numpy.ndarray`
177 *CIE xy* chromaticity coordinates.
179 Notes
180 -----
181 +------------+-----------------------+---------------+
182 | **Domain** | **Scale - Reference** | **Scale - 1** |
183 +============+=======================+===============+
184 | ``xyY`` | 1 | 1 |
185 +------------+-----------------------+---------------+
187 References
188 ----------
189 :cite:`CIETC1-482004h`, :cite:`Wikipedia2005`
191 Examples
192 --------
193 >>> xyY = np.array([0.54369557, 0.32107944, 0.12197225])
194 >>> xyY_to_xy(xyY) # doctest: +ELLIPSIS
195 array([ 0.54369557..., 0.32107944...])
196 >>> xy = np.array([0.54369557, 0.32107944])
197 >>> xyY_to_xy(xy) # doctest: +ELLIPSIS
198 array([ 0.54369557..., 0.32107944...])
199 """
201 xyY = as_float_array(xyY)
203 # Assuming ``xyY`` is actually a *CIE xy* chromaticity coordinates argument
204 # and returning it directly.
205 if xyY.shape[-1] == 2:
206 return xyY
208 return xyY[..., 0:2]
211def xy_to_xyY(xy: ArrayLike, Y: Domain1 = 1) -> Range1:
212 """
213 Convert from *CIE xy* chromaticity coordinates to *CIE xyY*
214 colourspace by extending the array's last dimension with the
215 specified :math:`Y` *luminance*.
217 ``xy`` argument with last dimension equal to 3 will be assumed
218 to be a *CIE xyY* colourspace array and will be returned
219 directly by the definition.
221 Parameters
222 ----------
223 xy
224 *CIE xy* chromaticity coordinates or *CIE xyY* colourspace
225 array.
226 Y
227 Optional :math:`Y` *luminance* value used to construct the
228 *CIE xyY* colourspace array. The default :math:`Y`
229 *luminance* value is 1.
231 Returns
232 -------
233 :class:`numpy.ndarray`
234 *CIE xyY* colourspace array.
236 Notes
237 -----
238 +------------+-----------------------+---------------+
239 | **Domain** | **Scale - Reference** | **Scale - 1** |
240 +============+=======================+===============+
241 | ``xy`` | 1 | 1 |
242 +------------+-----------------------+---------------+
243 | ``Y`` | 1 | 1 |
244 +------------+-----------------------+---------------+
246 +------------+-----------------------+---------------+
247 | **Range** | **Scale - Reference** | **Scale - 1** |
248 +============+=======================+===============+
249 | ``xyY`` | 1 | 1 |
250 +------------+-----------------------+---------------+
252 - This definition is a convenient object provided to
253 implement support of illuminant argument luminance value
254 in various :mod:`colour.models` package objects such as
255 :func:`colour.Lab_to_XYZ` or :func:`colour.Luv_to_XYZ`.
257 References
258 ----------
259 :cite:`CIETC1-482004h`, :cite:`Wikipedia2005`
261 Examples
262 --------
263 >>> xy = np.array([0.54369557, 0.32107944])
264 >>> xy_to_xyY(xy) # doctest: +ELLIPSIS
265 array([ 0.5436955..., 0.3210794..., 1. ])
266 >>> xy = np.array([0.54369557, 0.32107944, 1.00000000])
267 >>> xy_to_xyY(xy) # doctest: +ELLIPSIS
268 array([ 0.5436955..., 0.3210794..., 1. ])
269 >>> xy = np.array([0.54369557, 0.32107944])
270 >>> xy_to_xyY(xy, 100) # doctest: +ELLIPSIS
271 array([ 0.5436955..., 0.3210794..., 100. ])
272 """
274 xy = as_float_array(xy)
275 Y = as_float_array(to_domain_1(Y))
277 # Assuming ``xy`` is actually a *CIE xyY* colourspace array argument and
278 # returning it directly.
279 if xy.shape[-1] == 3:
280 return xy
282 x, y = tsplit(xy)
284 xyY = tstack([x, y, np.resize(Y, x.shape)])
286 return from_range_1(xyY, np.array([1, 1, 100]))
289def XYZ_to_xy(XYZ: Domain1) -> NDArrayFloat:
290 """
291 Convert from *CIE XYZ* tristimulus values to *CIE xy* chromaticity
292 coordinates.
294 Parameters
295 ----------
296 XYZ
297 *CIE XYZ* tristimulus values.
299 Returns
300 -------
301 :class:`numpy.ndarray`
302 *CIE xy* chromaticity coordinates.
304 Notes
305 -----
306 +------------+-----------------------+---------------+
307 | **Domain** | **Scale - Reference** | **Scale - 1** |
308 +============+=======================+===============+
309 | ``XYZ`` | 1 | 1 |
310 +------------+-----------------------+---------------+
312 References
313 ----------
314 :cite:`CIETC1-482004h`, :cite:`Wikipedia2005`
316 Examples
317 --------
318 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
319 >>> XYZ_to_xy(XYZ) # doctest: +ELLIPSIS
320 array([ 0.5436955..., 0.3210794...])
321 """
323 return xyY_to_xy(XYZ_to_xyY(XYZ))
326def xy_to_XYZ(xy: ArrayLike) -> Range1:
327 """
328 Convert from *CIE xy* chromaticity coordinates to *CIE XYZ* tristimulus values.
330 Parameters
331 ----------
332 xy
333 *CIE xy* chromaticity coordinates.
335 Returns
336 -------
337 :class:`numpy.ndarray`
338 *CIE XYZ* tristimulus values.
340 Notes
341 -----
342 +------------+-----------------------+---------------+
343 | **Domain** | **Scale - Reference** | **Scale - 1** |
344 +============+=======================+===============+
345 | ``xy`` | 1 | 1 |
346 +------------+-----------------------+---------------+
348 +------------+-----------------------+---------------+
349 | **Range** | **Scale - Reference** | **Scale - 1** |
350 +============+=======================+===============+
351 | ``XYZ`` | 1 | 1 |
352 +------------+-----------------------+---------------+
354 References
355 ----------
356 :cite:`CIETC1-482004h`, :cite:`Wikipedia2005`
358 Examples
359 --------
360 >>> xy = np.array([0.54369557, 0.32107944])
361 >>> xy_to_XYZ(xy) # doctest: +ELLIPSIS
362 array([ 1.6933366..., 1. , 0.4211574...])
363 """
365 return xyY_to_XYZ(xy_to_xyY(xy))