Source code for colour.models.yrg

"""
Yrg Colourspace - Kirk (2019)
=============================

Define the *Kirk (2019)* *Yrg* colourspace:

-   :func:`colour.models.LMS_to_Yrg`
-   :func:`colour.models.Yrg_to_LMS`
-   :func:`colour.XYZ_to_Yrg`
-   :func:`colour.Yrg_to_XYZ`

References
----------
-   :cite:`Kirk2019` : Kirk, R. A. (2019). Chromaticity coordinates for graphic
    arts based on CIE 2006 LMS with even spacing of Munsell colours. Color and
    Imaging Conference, 27(1), 215-219. doi:10.2352/issn.2169-2629.2019.27.38
"""

from __future__ import annotations

import numpy as np

from colour.algebra import sdiv, sdiv_mode, vecmul
from colour.hints import ArrayLike, NDArrayFloat
from colour.utilities import (
    from_range_1,
    to_domain_1,
    tsplit,
    tstack,
)

__author__ = "Colour Developers"
__copyright__ = "Copyright 2013 Colour Developers"
__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
__maintainer__ = "Colour Developers"
__email__ = "colour-developers@colour-science.org"
__status__ = "Production"

__all__ = [
    "LMS_to_Yrg",
    "Yrg_to_LMS",
    "XYZ_to_Yrg",
    "Yrg_to_XYZ",
]

MATRIX_XYZ_TO_LMS_KIRK2019: NDArrayFloat = np.array(
    [
        [0.257085, 0.859943, -0.031061],
        [-0.394427, 1.175800, 0.106423],
        [0.064856, -0.076250, 0.559067],
    ]
)
"""
*Kirk (2019)* matrix converting from *CIE XYZ* tristimulus values to *LMS*
colourspace.
"""

MATRIX_LMS_TO_XYZ_KIRK2019: NDArrayFloat = np.linalg.inv(MATRIX_XYZ_TO_LMS_KIRK2019)
"""
*Kirk (2019)* matrix converting from *LMS* colourspace to *CIE XYZ* tristimulus
values.
"""


[docs] def LMS_to_Yrg(LMS: ArrayLike) -> NDArrayFloat: """ Convert from *LMS* colourspace to *Kirk (2019)* *Yrg* colourspace. Parameters ---------- LMS *LMS* colourspace values. Returns ------- :class:`numpy.ndarray` *Kirk (2019)* *Yrg* :math:`Yrg` luminance, redness, and greenness. Notes ----- +------------+-----------------------+----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+================+ | ``LMS`` | [0, 100] | [0, 1] | +------------+-----------------------+----------------+ +------------+-----------------------+----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+================+ | ``Yrg`` | ``Y`` : [0, 1] | ``Y`` : [0, 1] | | | | | | | ``r`` : [0, 1] | ``r`` : [0, 1] | | | | | | | ``g`` : [0, 1] | ``g`` : [0, 1] | +------------+-----------------------+----------------+ References ---------- :cite:`Kirk2019` Examples -------- >>> import numpy as np >>> LMS = np.array([0.15639195, 0.06741689, 0.03281398]) >>> LMS_to_Yrg(LMS) # doctest: +ELLIPSIS array([ 0.1313780..., 0.4903764..., 0.3777739...]) """ L, M, S = tsplit(to_domain_1(LMS)) Y = 0.68990272 * L + 0.34832189 * M a = L + M + S with sdiv_mode(): l = sdiv(L, a) # noqa: E741 m = sdiv(M, a) r = 1.0671 * l - 0.6873 * m + 0.02062 g = -0.0362 * l + 1.7182 * m - 0.05155 Yrg = tstack([Y, r, g]) return from_range_1(Yrg)
[docs] def Yrg_to_LMS(Yrg: ArrayLike) -> NDArrayFloat: """ Convert from *Kirk (2019)* *Yrg* colourspace to *LMS* colourspace. Parameters ---------- Yrg *Kirk (2019)* *Yrg* :math:`Yrg` luminance, redness, and greenness. Returns ------- :class:`numpy.ndarray` *LMS* colourspace values. Notes ----- +------------+-----------------------+----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+================+ | ``Yrg`` | ``Y`` : [0, 1] | ``Y`` : [0, 1] | | | | | | | ``r`` : [0, 1] | ``r`` : [0, 1] | | | | | | | ``g`` : [0, 1] | ``g`` : [0, 1] | +------------+-----------------------+----------------+ +------------+-----------------------+----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+================+ | ``LMS`` | [0, 100] | [0, 1] | +------------+-----------------------+----------------+ References ---------- :cite:`Kirk2019` Examples -------- >>> import numpy as np >>> Yrg = np.array([0.13137801, 0.49037644, 0.37777391]) >>> Yrg_to_LMS(Yrg) # doctest: +ELLIPSIS array([ 0.1563929..., 0.0674150..., 0.0328213...]) """ Y, r, g = tsplit(to_domain_1(Yrg)) l = 0.95 * r + 0.38 * g # noqa: E741 m = 0.02 * r + 0.59 * g + 0.03 a = Y / (0.68990272 * l + 0.34832189 * m) L = l * a M = m * a S = (1 - l - m) * a LMS = tstack([L, M, S]) return from_range_1(LMS)
[docs] def XYZ_to_Yrg(XYZ: ArrayLike) -> NDArrayFloat: """ Convert from *CIE XYZ* tristimulus values to *Kirk (2019)* *Yrg* colourspace. Parameters ---------- XYZ *CIE XYZ* tristimulus values values. Returns ------- :class:`numpy.ndarray` *Kirk (2019)* *Yrg* :math:`Yrg` luminance, redness, and greenness. Notes ----- +------------+-----------------------+----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+================+ | ``XYZ`` | [0, 100] | [0, 1] | +------------+-----------------------+----------------+ +------------+-----------------------+----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+================+ | ``Yrg`` | ``Y`` : [0, 1] | ``Y`` : [0, 1] | | | | | | | ``r`` : [0, 1] | ``r`` : [0, 1] | | | | | | | ``g`` : [0, 1] | ``g`` : [0, 1] | +------------+-----------------------+----------------+ References ---------- :cite:`Kirk2019` Examples -------- >>> import numpy as np >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) >>> XYZ_to_Yrg(XYZ) # doctest: +ELLIPSIS array([ 0.1313780..., 0.4903764..., 0.3777738...]) """ return LMS_to_Yrg(vecmul(MATRIX_XYZ_TO_LMS_KIRK2019, XYZ))
[docs] def Yrg_to_XYZ(Yrg: ArrayLike) -> NDArrayFloat: """ Convert from *Kirk (2019)* *Yrg* colourspace to *CIE XYZ* tristimulus values. Parameters ---------- Yrg *Kirk (2019)* *Yrg* :math:`Yrg` luminance, redness, and greenness. Returns ------- :class:`numpy.ndarray` *CIE XYZ* tristimulus values values. Notes ----- +------------+-----------------------+----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+================+ | ``Yrg`` | ``Y`` : [0, 1] | ``Y`` : [0, 1] | | | | | | | ``r`` : [0, 1] | ``r`` : [0, 1] | | | | | | | ``g`` : [0, 1] | ``g`` : [0, 1] | +------------+-----------------------+----------------+ +------------+-----------------------+----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+================+ | ``XYZ`` | [0, 100] | [0, 1] | +------------+-----------------------+----------------+ References ---------- :cite:`Kirk2019` Examples -------- >>> import numpy as np >>> Yrg = np.array([0.13137801, 0.49037645, 0.37777388]) >>> Yrg_to_XYZ(Yrg) # doctest: +ELLIPSIS array([ 0.2065468..., 0.1219717..., 0.0513819...]) """ return vecmul(MATRIX_LMS_TO_XYZ_KIRK2019, Yrg_to_LMS(Yrg))