Coverage for adaptation/vonkries.py: 48%
31 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"""
2Von Kries Chromatic Adaptation Model
3====================================
5Define the *Von Kries* chromatic adaptation model for predicting corresponding
6colours under different viewing conditions.
8- :func:`colour.adaptation.matrix_chromatic_adaptation_VonKries`
9- :func:`colour.adaptation.chromatic_adaptation_VonKries`
11References
12----------
13- :cite:`Fairchild2013t` : Fairchild, M. D. (2013). Chromatic Adaptation
14 Models. In Color Appearance Models (3rd ed., pp. 4179-4252). Wiley.
15 ISBN:B00DAYO8E2
16"""
18from __future__ import annotations
20import typing
22import numpy as np
24from colour.adaptation import CHROMATIC_ADAPTATION_TRANSFORMS
25from colour.algebra import sdiv, sdiv_mode, vecmul
27if typing.TYPE_CHECKING:
28 from colour.hints import LiteralChromaticAdaptationTransform
30from colour.hints import ( # noqa: TC001
31 ArrayLike,
32 Domain1,
33 NDArrayFloat,
34 Range1,
35)
36from colour.utilities import (
37 as_float_array,
38 from_range_1,
39 row_as_diagonal,
40 to_domain_1,
41 validate_method,
42)
44__author__ = "Colour Developers"
45__copyright__ = "Copyright 2013 Colour Developers"
46__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
47__maintainer__ = "Colour Developers"
48__email__ = "colour-developers@colour-science.org"
49__status__ = "Production"
51__all__ = [
52 "matrix_chromatic_adaptation_VonKries",
53 "chromatic_adaptation_VonKries",
54]
57def matrix_chromatic_adaptation_VonKries(
58 XYZ_w: ArrayLike,
59 XYZ_wr: ArrayLike,
60 transform: LiteralChromaticAdaptationTransform | str = "CAT02",
61) -> NDArrayFloat:
62 """
63 Compute the chromatic adaptation matrix from test viewing conditions
64 to reference viewing conditions.
66 Parameters
67 ----------
68 XYZ_w
69 Test viewing conditions *CIE XYZ* tristimulus values of the
70 whitepoint.
71 XYZ_wr
72 Reference viewing conditions *CIE XYZ* tristimulus values of the
73 whitepoint.
74 transform
75 Chromatic adaptation transform.
77 Returns
78 -------
79 :class:`numpy.ndarray`
80 Chromatic adaptation matrix :math:`M_{cat}`.
82 Notes
83 -----
84 +------------+-----------------------+---------------+
85 | **Domain** | **Scale - Reference** | **Scale - 1** |
86 +============+=======================+===============+
87 | ``XYZ_w`` | 1 | 1 |
88 +------------+-----------------------+---------------+
89 | ``XYZ_wr`` | 1 | 1 |
90 +------------+-----------------------+---------------+
92 References
93 ----------
94 :cite:`Fairchild2013t`
96 Examples
97 --------
98 >>> XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775])
99 >>> XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460])
100 >>> matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr)
101 ... # doctest: +ELLIPSIS
102 array([[ 1.0425738..., 0.0308910..., -0.0528125...],
103 [ 0.0221934..., 1.0018566..., -0.0210737...],
104 [-0.0011648..., -0.0034205..., 0.7617890...]])
106 Using *Bradford* transform:
108 >>> XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775])
109 >>> XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460])
110 >>> transform = "Bradford"
111 >>> matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr, transform)
112 ... # doctest: +ELLIPSIS
113 array([[ 1.0479297..., 0.0229468..., -0.0501922...],
114 [ 0.0296278..., 0.9904344..., -0.0170738...],
115 [-0.0092430..., 0.0150551..., 0.7518742...]])
116 """
118 XYZ_w = as_float_array(XYZ_w)
119 XYZ_wr = as_float_array(XYZ_wr)
121 transform = validate_method(
122 transform,
123 tuple(CHROMATIC_ADAPTATION_TRANSFORMS),
124 '"{0}" chromatic adaptation transform is invalid, it must be one of {1}!',
125 )
127 M = CHROMATIC_ADAPTATION_TRANSFORMS[transform]
129 RGB_w = vecmul(M, XYZ_w)
130 RGB_wr = vecmul(M, XYZ_wr)
132 with sdiv_mode():
133 D = sdiv(RGB_wr, RGB_w)
135 D = row_as_diagonal(D)
137 M_CAT = np.matmul(np.linalg.inv(M), D)
139 return np.matmul(M_CAT, M)
142def chromatic_adaptation_VonKries(
143 XYZ: Domain1,
144 XYZ_w: ArrayLike,
145 XYZ_wr: ArrayLike,
146 transform: LiteralChromaticAdaptationTransform | str = "CAT02",
147) -> Range1:
148 """
149 Adapt the specified stimulus *CIE XYZ* tristimulus values from test
150 viewing conditions to reference viewing conditions using the *Von Kries*
151 chromatic adaptation model.
153 Parameters
154 ----------
155 XYZ
156 *CIE XYZ* tristimulus values of the stimulus to adapt.
157 XYZ_w
158 Test viewing conditions *CIE XYZ* tristimulus values of the
159 whitepoint.
160 XYZ_wr
161 Reference viewing conditions *CIE XYZ* tristimulus values of the
162 whitepoint.
163 transform
164 Chromatic adaptation transform.
166 Returns
167 -------
168 :class:`numpy.ndarray`
169 *CIE XYZ* tristimulus values of the stimulus corresponding colour.
171 Notes
172 -----
173 +------------+-----------------------+---------------+
174 | **Domain** | **Scale - Reference** | **Scale - 1** |
175 +============+=======================+===============+
176 | ``XYZ`` | 1 | 1 |
177 +------------+-----------------------+---------------+
178 | ``XYZ_n`` | 1 | 1 |
179 +------------+-----------------------+---------------+
180 | ``XYZ_r`` | 1 | 1 |
181 +------------+-----------------------+---------------+
183 +------------+-----------------------+---------------+
184 | **Range** | **Scale - Reference** | **Scale - 1** |
185 +============+=======================+===============+
186 | ``XYZ_a`` | 1 | 1 |
187 +------------+-----------------------+---------------+
189 References
190 ----------
191 :cite:`Fairchild2013t`
193 Examples
194 --------
195 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
196 >>> XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775])
197 >>> XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460])
198 >>> chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr) # doctest: +ELLIPSIS
199 array([ 0.2163881..., 0.1257 , 0.0384749...])
201 Using *Bradford* transform:
203 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
204 >>> XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775])
205 >>> XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460])
206 >>> transform = "Bradford"
207 >>> chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr, transform)
208 ... # doctest: +ELLIPSIS
209 array([ 0.2166600..., 0.1260477..., 0.0385506...])
210 """
212 XYZ = to_domain_1(XYZ)
214 M_CAT = matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr, transform)
215 XYZ_a = vecmul(M_CAT, XYZ)
217 return from_range_1(XYZ_a)