Coverage for models/oklab.py: 8%
25 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"""
2Oklab Colourspace
3=================
5Define the *Oklab* colourspace transformations.
7- :func:`colour.XYZ_to_Oklab`
8- :func:`colour.Oklab_to_XYZ`
10References
11----------
12- :cite:`Ottosson2020` : Ottosson, B. (2020). A perceptual color space for
13 image processing. Retrieved December 24, 2020, from
14 https://bottosson.github.io/posts/oklab/
15"""
17from __future__ import annotations
19from functools import partial
21import numpy as np
23from colour.algebra import spow
24from colour.hints import ( # noqa: TC001
25 Domain1,
26 NDArrayFloat,
27 Range1,
28)
29from colour.models import Iab_to_XYZ, XYZ_to_Iab
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 "MATRIX_1_XYZ_TO_LMS",
40 "MATRIX_1_LMS_TO_XYZ",
41 "MATRIX_2_LMS_TO_LAB",
42 "MATRIX_2_LAB_TO_LMS",
43 "XYZ_to_Oklab",
44 "Oklab_to_XYZ",
45]
47MATRIX_1_XYZ_TO_LMS: NDArrayFloat = np.array(
48 [
49 [0.8189330101, 0.3618667424, -0.1288597137],
50 [0.0329845436, 0.9293118715, 0.0361456387],
51 [0.0482003018, 0.2643662691, 0.6338517070],
52 ]
53)
54"""*CIE XYZ* tristimulus values to normalised cone responses matrix."""
56MATRIX_1_LMS_TO_XYZ: NDArrayFloat = np.linalg.inv(MATRIX_1_XYZ_TO_LMS)
57"""Normalised cone responses to *CIE XYZ* tristimulus values matrix."""
59MATRIX_2_LMS_TO_LAB: NDArrayFloat = np.array(
60 [
61 [0.2104542553, 0.7936177850, -0.0040720468],
62 [1.9779984951, -2.4285922050, 0.4505937099],
63 [0.0259040371, 0.7827717662, -0.8086757660],
64 ]
65)
66"""Normalised cone responses to *Oklab* colourspace matrix."""
68MATRIX_2_LAB_TO_LMS: NDArrayFloat = np.linalg.inv(MATRIX_2_LMS_TO_LAB)
69"""*Oklab* colourspace to normalised cone responses matrix."""
72def XYZ_to_Oklab(XYZ: Domain1) -> Range1:
73 """
74 Convert from *CIE XYZ* tristimulus values to *Oklab* colourspace.
76 Parameters
77 ----------
78 XYZ
79 *CIE XYZ* tristimulus values.
81 Returns
82 -------
83 :class:`numpy.ndarray`
84 *Oklab* colourspace array.
86 Notes
87 -----
88 +------------+-----------------------+-----------------+
89 | **Domain** | **Scale - Reference** | **Scale - 1** |
90 +============+=======================+=================+
91 | ``XYZ`` | 1 | 1 |
92 +------------+-----------------------+-----------------+
94 +------------+-----------------------+-----------------+
95 | **Range** | **Scale - Reference** | **Scale - 1** |
96 +============+=======================+=================+
97 | ``Lab`` | 1 | 1 |
98 +------------+-----------------------+-----------------+
100 - Input *CIE XYZ* tristimulus values must be adapted to
101 *CIE Standard Illuminant D Series* *D65*.
103 References
104 ----------
105 :cite:`Ottosson2020`
107 Examples
108 --------
109 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
110 >>> XYZ_to_Oklab(XYZ) # doctest: +ELLIPSIS
111 array([ 0.5163401..., 0.154695 ..., 0.0628957...])
112 """
114 return XYZ_to_Iab(
115 XYZ,
116 partial(spow, p=1 / 3),
117 MATRIX_1_XYZ_TO_LMS,
118 MATRIX_2_LMS_TO_LAB,
119 )
122def Oklab_to_XYZ(Lab: Domain1) -> Range1:
123 """
124 Convert from *Oklab* colourspace to *CIE XYZ* tristimulus values.
126 Parameters
127 ----------
128 Lab
129 *Oklab* colourspace array.
131 Returns
132 -------
133 :class:`numpy.ndarray`
134 *CIE XYZ* tristimulus values.
136 Notes
137 -----
138 +------------+-----------------------+-----------------+
139 | **Domain** | **Scale - Reference** | **Scale - 1** |
140 +============+=======================+=================+
141 | ``Lab`` | 1 | 1 |
142 +------------+-----------------------+-----------------+
144 +------------+-----------------------+-----------------+
145 | **Range** | **Scale - Reference** | **Scale - 1** |
146 +============+=======================+=================+
147 | ``XYZ`` | 1 | 1 |
148 +------------+-----------------------+-----------------+
150 References
151 ----------
152 :cite:`Ottosson2020`
154 Examples
155 --------
156 >>> Lab = np.array([0.51634019, 0.15469500, 0.06289579])
157 >>> Oklab_to_XYZ(Lab) # doctest: +ELLIPSIS
158 array([ 0.2065400..., 0.1219722..., 0.0513695...])
159 """
161 return Iab_to_XYZ(
162 Lab,
163 partial(spow, p=3),
164 MATRIX_2_LAB_TO_LMS,
165 MATRIX_1_LMS_TO_XYZ,
166 )