Coverage for colour/models/rgb/tests/test_ictcp.py: 100%
137 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.rgb.ictcp` module."""
3from __future__ import annotations
5from itertools import product
7import numpy as np
9from colour.constants import TOLERANCE_ABSOLUTE_TESTS
10from colour.models.rgb import ICtCp_to_RGB, ICtCp_to_XYZ, RGB_to_ICtCp, XYZ_to_ICtCp
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 "TestRGB_to_ICtCp",
22 "TestICtCp_to_RGB",
23 "TestXYZ_to_ICtCp",
24 "TestICtCp_to_XYZ",
25]
28class TestRGB_to_ICtCp:
29 """
30 Define :func:`colour.models.rgb.ictcp.TestRGB_to_ICtCp` definition unit
31 tests methods.
32 """
34 def test_RGB_to_ICtCp(self) -> None:
35 """Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition."""
37 np.testing.assert_allclose(
38 RGB_to_ICtCp(np.array([0.45620519, 0.03081071, 0.04091952])),
39 np.array([0.07351364, 0.00475253, 0.09351596]),
40 atol=TOLERANCE_ABSOLUTE_TESTS,
41 )
43 np.testing.assert_allclose(
44 RGB_to_ICtCp(np.array([0.45620519, 0.03081071, 0.04091952]), L_p=4000),
45 np.array([0.10516931, 0.00514031, 0.12318730]),
46 atol=TOLERANCE_ABSOLUTE_TESTS,
47 )
49 np.testing.assert_allclose(
50 RGB_to_ICtCp(np.array([0.45620519, 0.03081071, 0.04091952]), L_p=1000),
51 np.array([0.17079612, 0.00485580, 0.17431356]),
52 atol=TOLERANCE_ABSOLUTE_TESTS,
53 )
55 np.testing.assert_allclose(
56 RGB_to_ICtCp(
57 np.array([0.45620519, 0.03081071, 0.04091952]),
58 method="ITU-R BT.2100-1 PQ",
59 ),
60 np.array([0.07351364, 0.00475253, 0.09351596]),
61 atol=TOLERANCE_ABSOLUTE_TESTS,
62 )
64 np.testing.assert_allclose(
65 RGB_to_ICtCp(
66 np.array([0.45620519, 0.03081071, 0.04091952]),
67 method="ITU-R BT.2100-2 PQ",
68 ),
69 np.array([0.07351364, 0.00475253, 0.09351596]),
70 atol=TOLERANCE_ABSOLUTE_TESTS,
71 )
73 np.testing.assert_allclose(
74 RGB_to_ICtCp(
75 np.array([0.45620519, 0.03081071, 0.04091952]),
76 method="ITU-R BT.2100-1 HLG",
77 ),
78 np.array([0.62567899, -0.03622422, 0.67786522]),
79 atol=TOLERANCE_ABSOLUTE_TESTS,
80 )
82 np.testing.assert_allclose(
83 RGB_to_ICtCp(
84 np.array([0.45620519, 0.03081071, 0.04091952]),
85 method="ITU-R BT.2100-2 HLG",
86 ),
87 np.array([0.62567899, -0.01984490, 0.35911259]),
88 atol=TOLERANCE_ABSOLUTE_TESTS,
89 )
91 def test_n_dimensional_RGB_to_ICtCp(self) -> None:
92 """
93 Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition
94 n-dimensional support.
95 """
97 RGB = np.array([0.45620519, 0.03081071, 0.04091952])
98 ICtCp = RGB_to_ICtCp(RGB)
100 RGB = np.tile(RGB, (6, 1))
101 ICtCp = np.tile(ICtCp, (6, 1))
102 np.testing.assert_allclose(
103 RGB_to_ICtCp(RGB), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS
104 )
106 RGB = np.reshape(RGB, (2, 3, 3))
107 ICtCp = np.reshape(ICtCp, (2, 3, 3))
108 np.testing.assert_allclose(
109 RGB_to_ICtCp(RGB), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS
110 )
112 def test_domain_range_scale_RGB_to_ICtCp(self) -> None:
113 """
114 Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition domain
115 and range scale support.
116 """
118 RGB = np.array([0.45620519, 0.03081071, 0.04091952])
119 ICtCp = RGB_to_ICtCp(RGB)
121 d_r = (("reference", 1), ("1", 1), ("100", 1))
122 for scale, factor in d_r:
123 with domain_range_scale(scale):
124 np.testing.assert_allclose(
125 RGB_to_ICtCp(RGB * factor),
126 ICtCp * factor,
127 atol=TOLERANCE_ABSOLUTE_TESTS,
128 )
130 @ignore_numpy_errors
131 def test_nan_RGB_to_ICtCp(self) -> None:
132 """
133 Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition nan
134 support.
135 """
137 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
138 cases = np.array(list(set(product(cases, repeat=3))))
139 RGB_to_ICtCp(cases)
142class TestICtCp_to_RGB:
143 """
144 Define :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition unit tests
145 methods.
146 """
148 def test_ICtCp_to_RGB(self) -> None:
149 """Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition."""
151 np.testing.assert_allclose(
152 ICtCp_to_RGB(np.array([0.07351364, 0.00475253, 0.09351596])),
153 np.array([0.45620519, 0.03081071, 0.04091952]),
154 atol=TOLERANCE_ABSOLUTE_TESTS,
155 )
157 np.testing.assert_allclose(
158 ICtCp_to_RGB(np.array([0.10516931, 0.00514031, 0.12318730]), L_p=4000),
159 np.array([0.45620519, 0.03081071, 0.04091952]),
160 atol=TOLERANCE_ABSOLUTE_TESTS,
161 )
163 np.testing.assert_allclose(
164 ICtCp_to_RGB(np.array([0.17079612, 0.00485580, 0.17431356]), L_p=1000),
165 np.array([0.45620519, 0.03081071, 0.04091952]),
166 atol=TOLERANCE_ABSOLUTE_TESTS,
167 )
169 np.testing.assert_allclose(
170 ICtCp_to_RGB(
171 np.array([0.07351364, 0.00475253, 0.09351596]),
172 method="ITU-R BT.2100-1 PQ",
173 ),
174 np.array([0.45620519, 0.03081071, 0.04091952]),
175 atol=TOLERANCE_ABSOLUTE_TESTS,
176 )
178 np.testing.assert_allclose(
179 ICtCp_to_RGB(
180 np.array([0.07351364, 0.00475253, 0.09351596]),
181 method="ITU-R BT.2100-2 PQ",
182 ),
183 np.array([0.45620519, 0.03081071, 0.04091952]),
184 atol=TOLERANCE_ABSOLUTE_TESTS,
185 )
187 np.testing.assert_allclose(
188 ICtCp_to_RGB(
189 np.array([0.62567899, -0.03622422, 0.67786522]),
190 method="ITU-R BT.2100-1 HLG",
191 ),
192 np.array([0.45620519, 0.03081071, 0.04091952]),
193 atol=TOLERANCE_ABSOLUTE_TESTS,
194 )
196 np.testing.assert_allclose(
197 ICtCp_to_RGB(
198 np.array([0.62567899, -0.01984490, 0.35911259]),
199 method="ITU-R BT.2100-2 HLG",
200 ),
201 np.array([0.45620519, 0.03081071, 0.04091952]),
202 atol=TOLERANCE_ABSOLUTE_TESTS,
203 )
205 def test_n_dimensional_ICtCp_to_RGB(self) -> None:
206 """
207 Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition
208 n-dimensional support.
209 """
211 ICtCp = np.array([0.07351364, 0.00475253, 0.09351596])
212 RGB = ICtCp_to_RGB(ICtCp)
214 ICtCp = np.tile(ICtCp, (6, 1))
215 RGB = np.tile(RGB, (6, 1))
216 np.testing.assert_allclose(
217 ICtCp_to_RGB(ICtCp), RGB, atol=TOLERANCE_ABSOLUTE_TESTS
218 )
220 ICtCp = np.reshape(ICtCp, (2, 3, 3))
221 RGB = np.reshape(RGB, (2, 3, 3))
222 np.testing.assert_allclose(
223 ICtCp_to_RGB(ICtCp), RGB, atol=TOLERANCE_ABSOLUTE_TESTS
224 )
226 def test_domain_range_scale_ICtCp_to_RGB(self) -> None:
227 """
228 Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition domain
229 and range scale support.
230 """
232 ICtCp = np.array([0.07351364, 0.00475253, 0.09351596])
233 RGB = ICtCp_to_RGB(ICtCp)
235 d_r = (("reference", 1), ("1", 1), ("100", 1))
236 for scale, factor in d_r:
237 with domain_range_scale(scale):
238 np.testing.assert_allclose(
239 ICtCp_to_RGB(ICtCp * factor),
240 RGB * factor,
241 atol=TOLERANCE_ABSOLUTE_TESTS,
242 )
244 @ignore_numpy_errors
245 def test_nan_ICtCp_to_RGB(self) -> None:
246 """
247 Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition nan
248 support.
249 """
251 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
252 cases = np.array(list(set(product(cases, repeat=3))))
253 ICtCp_to_RGB(cases)
256class TestXYZ_to_ICtCp:
257 """
258 Define :func:`colour.models.rgb.ictcp.TestXYZ_to_ICtCp` definition unit
259 tests methods.
260 """
262 def test_XYZ_to_ICtCp(self) -> None:
263 """Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition."""
265 np.testing.assert_allclose(
266 XYZ_to_ICtCp(np.array([0.20654008, 0.12197225, 0.05136952])),
267 np.array([0.06858097, -0.00283842, 0.06020983]),
268 atol=TOLERANCE_ABSOLUTE_TESTS,
269 )
271 np.testing.assert_allclose(
272 XYZ_to_ICtCp(
273 np.array([0.20654008, 0.12197225, 0.05136952]),
274 np.array([0.34570, 0.35850]),
275 ),
276 np.array([0.06792437, 0.00452089, 0.05514480]),
277 atol=TOLERANCE_ABSOLUTE_TESTS,
278 )
280 np.testing.assert_allclose(
281 XYZ_to_ICtCp(
282 np.array([0.20654008, 0.12197225, 0.05136952]),
283 np.array([0.34570, 0.35850]),
284 chromatic_adaptation_transform="Bradford",
285 ),
286 np.array([0.06783951, 0.00476111, 0.05523093]),
287 atol=TOLERANCE_ABSOLUTE_TESTS,
288 )
290 np.testing.assert_allclose(
291 XYZ_to_ICtCp(np.array([0.20654008, 0.12197225, 0.05136952]), L_p=4000),
292 np.array([0.09871102, -0.00447247, 0.07984812]),
293 atol=TOLERANCE_ABSOLUTE_TESTS,
294 )
296 np.testing.assert_allclose(
297 XYZ_to_ICtCp(np.array([0.20654008, 0.12197225, 0.05136952]), L_p=1000),
298 np.array([0.16173872, -0.00792543, 0.11409458]),
299 atol=TOLERANCE_ABSOLUTE_TESTS,
300 )
302 np.testing.assert_allclose(
303 XYZ_to_ICtCp(
304 np.array([0.20654008, 0.12197225, 0.05136952]),
305 method="ITU-R BT.2100-1 PQ",
306 ),
307 np.array([0.06858097, -0.00283842, 0.06020983]),
308 atol=TOLERANCE_ABSOLUTE_TESTS,
309 )
311 np.testing.assert_allclose(
312 XYZ_to_ICtCp(
313 np.array([0.20654008, 0.12197225, 0.05136952]),
314 method="ITU-R BT.2100-2 PQ",
315 ),
316 np.array([0.06858097, -0.00283842, 0.06020983]),
317 atol=TOLERANCE_ABSOLUTE_TESTS,
318 )
320 np.testing.assert_allclose(
321 XYZ_to_ICtCp(
322 np.array([0.20654008, 0.12197225, 0.05136952]),
323 method="ITU-R BT.2100-1 HLG",
324 ),
325 np.array([0.59242792, -0.06824263, 0.47421473]),
326 atol=TOLERANCE_ABSOLUTE_TESTS,
327 )
329 np.testing.assert_allclose(
330 XYZ_to_ICtCp(
331 np.array([0.20654008, 0.12197225, 0.05136952]),
332 method="ITU-R BT.2100-2 HLG",
333 ),
334 np.array([0.59242792, -0.03740730, 0.25122675]),
335 atol=TOLERANCE_ABSOLUTE_TESTS,
336 )
338 def test_n_dimensional_XYZ_to_ICtCp(self) -> None:
339 """
340 Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition
341 n-dimensional support.
342 """
344 XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
345 ICtCp = XYZ_to_ICtCp(XYZ)
347 XYZ = np.tile(XYZ, (6, 1))
348 ICtCp = np.tile(ICtCp, (6, 1))
349 np.testing.assert_allclose(
350 XYZ_to_ICtCp(XYZ), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS
351 )
353 XYZ = np.reshape(XYZ, (2, 3, 3))
354 ICtCp = np.reshape(ICtCp, (2, 3, 3))
355 np.testing.assert_allclose(
356 XYZ_to_ICtCp(XYZ), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS
357 )
359 def test_domain_range_scale_XYZ_to_ICtCp(self) -> None:
360 """
361 Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition domain
362 and range scale support.
363 """
365 XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
366 ICtCp = XYZ_to_ICtCp(XYZ)
368 d_r = (("reference", 1), ("1", 1), ("100", 1))
369 for scale, factor in d_r:
370 with domain_range_scale(scale):
371 np.testing.assert_allclose(
372 XYZ_to_ICtCp(XYZ * factor),
373 ICtCp * factor,
374 atol=TOLERANCE_ABSOLUTE_TESTS,
375 )
377 @ignore_numpy_errors
378 def test_nan_XYZ_to_ICtCp(self) -> None:
379 """
380 Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition nan
381 support.
382 """
384 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
385 cases = np.array(list(set(product(cases, repeat=3))))
386 XYZ_to_ICtCp(cases)
389class TestICtCp_to_XYZ:
390 """
391 Define :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition unit tests
392 methods.
393 """
395 def test_ICtCp_to_XYZ(self) -> None:
396 """Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition."""
398 np.testing.assert_allclose(
399 ICtCp_to_XYZ(np.array([0.06858097, -0.00283842, 0.06020983])),
400 np.array([0.20654008, 0.12197225, 0.05136952]),
401 atol=TOLERANCE_ABSOLUTE_TESTS,
402 )
404 np.testing.assert_allclose(
405 ICtCp_to_XYZ(
406 np.array([0.06792437, 0.00452089, 0.05514480]),
407 np.array([0.34570, 0.35850]),
408 ),
409 np.array([0.20654008, 0.12197225, 0.05136952]),
410 atol=TOLERANCE_ABSOLUTE_TESTS,
411 )
413 np.testing.assert_allclose(
414 ICtCp_to_XYZ(
415 np.array([0.06783951, 0.00476111, 0.05523093]),
416 np.array([0.34570, 0.35850]),
417 chromatic_adaptation_transform="Bradford",
418 ),
419 np.array([0.20654008, 0.12197225, 0.05136952]),
420 atol=TOLERANCE_ABSOLUTE_TESTS,
421 )
423 np.testing.assert_allclose(
424 ICtCp_to_XYZ(np.array([0.09871102, -0.00447247, 0.07984812]), L_p=4000),
425 np.array([0.20654008, 0.12197225, 0.05136952]),
426 atol=TOLERANCE_ABSOLUTE_TESTS,
427 )
429 np.testing.assert_allclose(
430 ICtCp_to_XYZ(np.array([0.16173872, -0.00792543, 0.11409458]), L_p=1000),
431 np.array([0.20654008, 0.12197225, 0.05136952]),
432 atol=TOLERANCE_ABSOLUTE_TESTS,
433 )
435 np.testing.assert_allclose(
436 ICtCp_to_XYZ(
437 np.array([0.06858097, -0.00283842, 0.06020983]),
438 method="ITU-R BT.2100-1 PQ",
439 ),
440 np.array([0.20654008, 0.12197225, 0.05136952]),
441 atol=TOLERANCE_ABSOLUTE_TESTS,
442 )
444 np.testing.assert_allclose(
445 ICtCp_to_XYZ(
446 np.array([0.06858097, -0.00283842, 0.06020983]),
447 method="ITU-R BT.2100-2 PQ",
448 ),
449 np.array([0.20654008, 0.12197225, 0.05136952]),
450 atol=TOLERANCE_ABSOLUTE_TESTS,
451 )
453 np.testing.assert_allclose(
454 ICtCp_to_XYZ(
455 np.array([0.59242792, -0.06824263, 0.47421473]),
456 method="ITU-R BT.2100-1 HLG",
457 ),
458 np.array([0.20654008, 0.12197225, 0.05136952]),
459 atol=TOLERANCE_ABSOLUTE_TESTS,
460 )
462 np.testing.assert_allclose(
463 ICtCp_to_XYZ(
464 np.array([0.59242792, -0.03740730, 0.25122675]),
465 method="ITU-R BT.2100-2 HLG",
466 ),
467 np.array([0.20654008, 0.12197225, 0.05136952]),
468 atol=TOLERANCE_ABSOLUTE_TESTS,
469 )
471 def test_n_dimensional_ICtCp_to_XYZ(self) -> None:
472 """
473 Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition
474 n-dimensional support.
475 """
477 ICtCp = np.array([0.06858097, -0.00283842, 0.06020983])
478 XYZ = ICtCp_to_XYZ(ICtCp)
480 ICtCp = np.tile(ICtCp, (6, 1))
481 XYZ = np.tile(XYZ, (6, 1))
482 np.testing.assert_allclose(
483 ICtCp_to_XYZ(ICtCp), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS
484 )
486 ICtCp = np.reshape(ICtCp, (2, 3, 3))
487 XYZ = np.reshape(XYZ, (2, 3, 3))
488 np.testing.assert_allclose(
489 ICtCp_to_XYZ(ICtCp), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS
490 )
492 def test_domain_range_scale_ICtCp_to_XYZ(self) -> None:
493 """
494 Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition domain
495 and range scale support.
496 """
498 ICtCp = np.array([0.06858097, -0.00283842, 0.06020983])
499 XYZ = ICtCp_to_XYZ(ICtCp)
501 d_r = (("reference", 1), ("1", 1), ("100", 1))
502 for scale, factor in d_r:
503 with domain_range_scale(scale):
504 np.testing.assert_allclose(
505 ICtCp_to_XYZ(ICtCp * factor),
506 XYZ * factor,
507 atol=TOLERANCE_ABSOLUTE_TESTS,
508 )
510 @ignore_numpy_errors
511 def test_nan_ICtCp_to_XYZ(self) -> None:
512 """
513 Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition nan
514 support.
515 """
517 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
518 cases = np.array(list(set(product(cases, repeat=3))))
519 ICtCp_to_XYZ(cases)