Coverage for colour/models/rgb/prismatic.py: 100%
29 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"""
2Prismatic Colourspace
3=====================
5Define transformations for the *Prismatic* colourspace, a perceptually-based
6colour representation that separates lightness from chromaticity components.
8- :func:`colour.RGB_to_Prismatic`
9- :func:`colour.Prismatic_to_RGB`
11References
12----------
13- :cite:`Shirley2015a` : Shirley, P., & Hart, D. (2015). The prismatic color
14 space for rgb computations (pp. 2-7).
15"""
17from __future__ import annotations
19import numpy as np
21from colour.algebra import sdiv, sdiv_mode
22from colour.hints import ( # noqa: TC001
23 Domain1,
24 Range1,
25)
26from colour.utilities import from_range_1, to_domain_1, tsplit, tstack
28__author__ = "Colour Developers"
29__copyright__ = "Copyright 2013 Colour Developers"
30__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
31__maintainer__ = "Colour Developers"
32__email__ = "colour-developers@colour-science.org"
33__status__ = "Production"
35__all__ = [
36 "RGB_to_Prismatic",
37 "Prismatic_to_RGB",
38]
41def RGB_to_Prismatic(RGB: Domain1) -> Range1:
42 """
43 Convert from *RGB* colourspace to *Prismatic* :math:`L\\rho\\gamma\\beta`
44 colourspace array.
46 Parameters
47 ----------
48 RGB
49 *RGB* colourspace array.
51 Returns
52 -------
53 :class:`numpy.ndarray`
54 *Prismatic* :math:`L\\rho\\gamma\\beta` colourspace array.
56 Notes
57 -----
58 +------------+-----------------------+---------------+
59 | **Domain** | **Scale - Reference** | **Scale - 1** |
60 +============+=======================+===============+
61 | ``RGB`` | 1 | 1 |
62 +------------+-----------------------+---------------+
64 +------------+-----------------------+---------------+
65 | **Range** | **Scale - Reference** | **Scale - 1** |
66 +============+=======================+===============+
67 | ``Lrgb`` | 1 | 1 |
68 +------------+-----------------------+---------------+
70 References
71 ----------
72 :cite:`Shirley2015a`
74 Examples
75 --------
76 >>> RGB = np.array([0.25, 0.50, 0.75])
77 >>> RGB_to_Prismatic(RGB) # doctest: +ELLIPSIS
78 array([ 0.75... , 0.1666666..., 0.3333333..., 0.5... ])
80 Adjusting saturation of the specified *RGB* colourspace array:
81 >>> saturation = 0.5
82 >>> Lrgb = RGB_to_Prismatic(RGB)
83 >>> Lrgb[..., 1:] = 1 / 3 + saturation * (Lrgb[..., 1:] - 1 / 3)
84 >>> Prismatic_to_RGB(Lrgb) # doctest: +ELLIPSIS
85 array([ 0.45..., 0.6..., 0.75...])
86 """
88 RGB = to_domain_1(RGB)
90 L = np.max(RGB, axis=-1)
91 s = np.sum(RGB, axis=-1)
93 with sdiv_mode():
94 one_s = sdiv(1, s[..., None])
96 r, g, b = tsplit(one_s * RGB)
98 Lrgb = tstack([L, r, g, b])
100 return from_range_1(Lrgb)
103def Prismatic_to_RGB(Lrgb: Domain1) -> Range1:
104 """
105 Convert from *Prismatic* :math:`L\\rho\\gamma\\beta` colourspace array to
106 *RGB* colourspace.
108 Parameters
109 ----------
110 Lrgb
111 *Prismatic* :math:`L\\rho\\gamma\\beta` colourspace array.
113 Returns
114 -------
115 :class:`numpy.ndarray`
116 *RGB* colourspace array.
118 Notes
119 -----
120 +------------+-----------------------+---------------+
121 | **Domain** | **Scale - Reference** | **Scale - 1** |
122 +============+=======================+===============+
123 | ``Lrgb`` | 1 | 1 |
124 +------------+-----------------------+---------------+
126 +------------+-----------------------+---------------+
127 | **Range** | **Scale - Reference** | **Scale - 1** |
128 +============+=======================+===============+
129 | ``RGB`` | 1 | 1 |
130 +------------+-----------------------+---------------+
132 References
133 ----------
134 :cite:`Shirley2015a`
136 Examples
137 --------
138 >>> Lrgb = np.array([0.75000000, 0.16666667, 0.33333333, 0.50000000])
139 >>> Prismatic_to_RGB(Lrgb) # doctest: +ELLIPSIS
140 array([ 0.25... , 0.4999999..., 0.75... ])
141 """
143 Lrgb = to_domain_1(Lrgb)
145 rgb = Lrgb[..., 1:]
146 m = np.max(rgb, axis=-1)
148 with sdiv_mode():
149 RGB = sdiv(Lrgb[..., 0][..., None], m[..., None])
151 RGB = RGB * rgb
153 return from_range_1(RGB)