Coverage for colour/models/tests/test_cie_lab.py: 100%
81 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"""Define the unit tests for the :mod:`colour.models.cie_lab` module."""
3from __future__ import annotations
5from itertools import product
7import numpy as np
9from colour.constants import TOLERANCE_ABSOLUTE_TESTS
10from colour.models import Lab_to_XYZ, XYZ_to_Lab
11from colour.utilities import domain_range_scale, ignore_numpy_errors
13__author__ = "Colour Developers"
14__copyright__ = "Copyright 2013 Colour Developers"
15__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
16__maintainer__ = "Colour Developers"
17__email__ = "colour-developers@colour-science.org"
18__status__ = "Production"
20__all__ = [
21 "TestXYZ_to_Lab",
22 "TestLab_to_XYZ",
23]
26class TestXYZ_to_Lab:
27 """
28 Define :func:`colour.models.cie_lab.XYZ_to_Lab` definition unit tests
29 methods.
30 """
32 def test_XYZ_to_Lab(self) -> None:
33 """Test :func:`colour.models.cie_lab.XYZ_to_Lab` definition."""
35 np.testing.assert_allclose(
36 XYZ_to_Lab(np.array([0.20654008, 0.12197225, 0.05136952])),
37 np.array([41.52787529, 52.63858304, 26.92317922]),
38 atol=TOLERANCE_ABSOLUTE_TESTS,
39 )
41 np.testing.assert_allclose(
42 XYZ_to_Lab(np.array([0.14222010, 0.23042768, 0.10495772])),
43 np.array([55.11636304, -41.08791787, 30.91825778]),
44 atol=TOLERANCE_ABSOLUTE_TESTS,
45 )
47 np.testing.assert_allclose(
48 XYZ_to_Lab(np.array([0.07818780, 0.06157201, 0.28099326])),
49 np.array([29.80565520, 20.01830466, -48.34913874]),
50 atol=TOLERANCE_ABSOLUTE_TESTS,
51 )
53 np.testing.assert_allclose(
54 XYZ_to_Lab(
55 np.array([0.20654008, 0.12197225, 0.05136952]),
56 np.array([0.44757, 0.40745]),
57 ),
58 np.array([41.52787529, 38.48089305, -5.73295122]),
59 atol=TOLERANCE_ABSOLUTE_TESTS,
60 )
62 np.testing.assert_allclose(
63 XYZ_to_Lab(
64 np.array([0.20654008, 0.12197225, 0.05136952]),
65 np.array([0.34570, 0.35850]),
66 ),
67 np.array([41.52787529, 51.19354174, 19.91843098]),
68 atol=TOLERANCE_ABSOLUTE_TESTS,
69 )
71 np.testing.assert_allclose(
72 XYZ_to_Lab(
73 np.array([0.20654008, 0.12197225, 0.05136952]),
74 np.array([0.34570, 0.35850, 1.00000]),
75 ),
76 np.array([41.52787529, 51.19354174, 19.91843098]),
77 atol=TOLERANCE_ABSOLUTE_TESTS,
78 )
80 def test_n_dimensional_XYZ_to_Lab(self) -> None:
81 """
82 Test :func:`colour.models.cie_lab.XYZ_to_Lab` definition n-dimensional
83 support.
84 """
86 XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
87 illuminant = np.array([0.31270, 0.32900])
88 Lab = XYZ_to_Lab(XYZ, illuminant)
90 XYZ = np.tile(XYZ, (6, 1))
91 Lab = np.tile(Lab, (6, 1))
92 np.testing.assert_allclose(
93 XYZ_to_Lab(XYZ, illuminant), Lab, atol=TOLERANCE_ABSOLUTE_TESTS
94 )
96 illuminant = np.tile(illuminant, (6, 1))
97 np.testing.assert_allclose(
98 XYZ_to_Lab(XYZ, illuminant), Lab, atol=TOLERANCE_ABSOLUTE_TESTS
99 )
101 XYZ = np.reshape(XYZ, (2, 3, 3))
102 illuminant = np.reshape(illuminant, (2, 3, 2))
103 Lab = np.reshape(Lab, (2, 3, 3))
104 np.testing.assert_allclose(
105 XYZ_to_Lab(XYZ, illuminant), Lab, atol=TOLERANCE_ABSOLUTE_TESTS
106 )
108 def test_domain_range_scale_XYZ_to_Lab(self) -> None:
109 """
110 Test :func:`colour.models.cie_lab.XYZ_to_Lab` definition
111 domain and range scale support.
112 """
114 XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
115 illuminant = np.array([0.31270, 0.32900])
116 Lab = XYZ_to_Lab(XYZ, illuminant)
118 d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1))
119 for scale, factor_a, factor_b in d_r:
120 with domain_range_scale(scale):
121 np.testing.assert_allclose(
122 XYZ_to_Lab(XYZ * factor_a, illuminant),
123 Lab * factor_b,
124 atol=TOLERANCE_ABSOLUTE_TESTS,
125 )
127 @ignore_numpy_errors
128 def test_nan_XYZ_to_Lab(self) -> None:
129 """Test :func:`colour.models.cie_lab.XYZ_to_Lab` definition nan support."""
131 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
132 cases = np.array(list(set(product(cases, repeat=3))))
133 XYZ_to_Lab(cases, cases[..., 0:2])
136class TestLab_to_XYZ:
137 """
138 Define :func:`colour.models.cie_lab.Lab_to_XYZ` definition unit tests
139 methods.
140 """
142 def test_Lab_to_XYZ(self) -> None:
143 """Test :func:`colour.models.cie_lab.Lab_to_XYZ` definition."""
145 np.testing.assert_allclose(
146 Lab_to_XYZ(np.array([41.52787529, 52.63858304, 26.92317922])),
147 np.array([0.20654008, 0.12197225, 0.05136952]),
148 atol=TOLERANCE_ABSOLUTE_TESTS,
149 )
151 np.testing.assert_allclose(
152 Lab_to_XYZ(np.array([55.11636304, -41.08791787, 30.91825778])),
153 np.array([0.14222010, 0.23042768, 0.10495772]),
154 atol=TOLERANCE_ABSOLUTE_TESTS,
155 )
157 np.testing.assert_allclose(
158 Lab_to_XYZ(np.array([29.80565520, 20.01830466, -48.34913874])),
159 np.array([0.07818780, 0.06157201, 0.28099326]),
160 atol=TOLERANCE_ABSOLUTE_TESTS,
161 )
163 np.testing.assert_allclose(
164 Lab_to_XYZ(
165 np.array([41.52787529, 38.48089305, -5.73295122]),
166 np.array([0.44757, 0.40745]),
167 ),
168 np.array([0.20654008, 0.12197225, 0.05136952]),
169 atol=TOLERANCE_ABSOLUTE_TESTS,
170 )
172 np.testing.assert_allclose(
173 Lab_to_XYZ(
174 np.array([41.52787529, 51.19354174, 19.91843098]),
175 np.array([0.34570, 0.35850]),
176 ),
177 np.array([0.20654008, 0.12197225, 0.05136952]),
178 atol=TOLERANCE_ABSOLUTE_TESTS,
179 )
181 np.testing.assert_allclose(
182 Lab_to_XYZ(
183 np.array([41.52787529, 51.19354174, 19.91843098]),
184 np.array([0.34570, 0.35850, 1.00000]),
185 ),
186 np.array([0.20654008, 0.12197225, 0.05136952]),
187 atol=TOLERANCE_ABSOLUTE_TESTS,
188 )
190 def test_n_dimensional_Lab_to_XYZ(self) -> None:
191 """
192 Test :func:`colour.models.cie_lab.Lab_to_XYZ` definition n-dimensional
193 support.
194 """
196 Lab = np.array([41.52787529, 52.63858304, 26.92317922])
197 illuminant = np.array([0.31270, 0.32900])
198 XYZ = Lab_to_XYZ(Lab, illuminant)
200 Lab = np.tile(Lab, (6, 1))
201 XYZ = np.tile(XYZ, (6, 1))
202 np.testing.assert_allclose(
203 Lab_to_XYZ(Lab, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS
204 )
206 illuminant = np.tile(illuminant, (6, 1))
207 np.testing.assert_allclose(
208 Lab_to_XYZ(Lab, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS
209 )
211 Lab = np.reshape(Lab, (2, 3, 3))
212 illuminant = np.reshape(illuminant, (2, 3, 2))
213 XYZ = np.reshape(XYZ, (2, 3, 3))
214 np.testing.assert_allclose(
215 Lab_to_XYZ(Lab, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS
216 )
218 def test_domain_range_scale_Lab_to_XYZ(self) -> None:
219 """
220 Test :func:`colour.models.cie_lab.Lab_to_XYZ` definition
221 domain and range scale support.
222 """
224 Lab = np.array([41.52787529, 52.63858304, 26.92317922])
225 illuminant = np.array([0.31270, 0.32900])
226 XYZ = Lab_to_XYZ(Lab, illuminant)
228 d_r = (("reference", 1, 1), ("1", 0.01, 1), ("100", 1, 100))
229 for scale, factor_a, factor_b in d_r:
230 with domain_range_scale(scale):
231 np.testing.assert_allclose(
232 Lab_to_XYZ(Lab * factor_a, illuminant),
233 XYZ * factor_b,
234 atol=TOLERANCE_ABSOLUTE_TESTS,
235 )
237 @ignore_numpy_errors
238 def test_nan_Lab_to_XYZ(self) -> None:
239 """Test :func:`colour.models.cie_lab.Lab_to_XYZ` definition nan support."""
241 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
242 cases = np.array(list(set(product(cases, repeat=3))))
243 Lab_to_XYZ(cases, cases[..., 0:2])