Coverage for models/rgb/tests/test_rgb_colourspace.py: 100%
179 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"""
2Define the unit tests for the :mod:`colour.models.rgb.rgb_colourspace` module.
3"""
5from __future__ import annotations
7import re
8import textwrap
9from itertools import product
11import numpy as np
13from colour.constants import TOLERANCE_ABSOLUTE_TESTS
14from colour.models import (
15 RGB_COLOURSPACE_ACES2065_1,
16 RGB_COLOURSPACES,
17 RGB_Colourspace,
18 RGB_COLOURSPACE_sRGB,
19 RGB_to_RGB,
20 RGB_to_XYZ,
21 XYZ_to_RGB,
22 chromatically_adapted_primaries,
23 eotf_inverse_sRGB,
24 eotf_sRGB,
25 linear_function,
26 matrix_RGB_to_RGB,
27 normalised_primary_matrix,
28)
29from colour.utilities import domain_range_scale, ignore_numpy_errors
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 "TestRGB_Colourspace",
40 "TestXYZ_to_RGB",
41 "TestRGB_to_XYZ",
42 "TestMatrix_RGB_to_RGB",
43 "TestRGB_to_RGB",
44]
47class TestRGB_Colourspace:
48 """
49 Define :class:`colour.colour.models.RGB_Colourspace` class unit
50 tests methods.
51 """
53 def setup_method(self) -> None:
54 """Initialise the common tests attributes."""
56 p = np.array([0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700])
57 whitepoint = np.array([0.32168, 0.33767])
58 matrix_RGB_to_XYZ = np.identity(3)
59 matrix_XYZ_to_RGB = np.identity(3)
60 self._colourspace = RGB_Colourspace(
61 "RGB Colourspace",
62 p,
63 whitepoint,
64 "ACES",
65 matrix_RGB_to_XYZ,
66 matrix_XYZ_to_RGB,
67 linear_function,
68 linear_function,
69 )
71 def test_required_attributes(self) -> None:
72 """Test the presence of required attributes."""
74 required_attributes = (
75 "name",
76 "primaries",
77 "whitepoint",
78 "whitepoint_name",
79 "matrix_RGB_to_XYZ",
80 "matrix_XYZ_to_RGB",
81 "cctf_encoding",
82 "cctf_decoding",
83 "use_derived_matrix_RGB_to_XYZ",
84 "use_derived_matrix_XYZ_to_RGB",
85 )
87 for attribute in required_attributes:
88 assert attribute in dir(RGB_Colourspace)
90 def test_required_methods(self) -> None:
91 """Test the presence of required methods."""
93 required_methods = (
94 "__init__",
95 "__str__",
96 "__repr__",
97 "use_derived_transformation_matrices",
98 "chromatically_adapt",
99 "copy",
100 )
102 for method in required_methods:
103 assert method in dir(RGB_Colourspace)
105 def test__str__(self) -> None:
106 """
107 Test :meth:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.__str__`
108 method.
109 """
111 assert re.sub(" at 0x\\w+>", "", str(self._colourspace)) == (
112 textwrap.dedent(
113 """
114 RGB Colourspace
115 ---------------
117 Primaries : [[ 7.34700000e-01 2.65300000e-01]
118 [ 0.00000000e+00 1.00000000e+00]
119 [ 1.00000000e-04 -7.70000000e-02]]
120 Whitepoint : [ 0.32168 0.33767]
121 Whitepoint Name : ACES
122 Encoding CCTF : <function linear_function
123 Decoding CCTF : <function linear_function
124 NPM : [[ 1. 0. 0.]
125 [ 0. 1. 0.]
126 [ 0. 0. 1.]]
127 NPM -1 : [[ 1. 0. 0.]
128 [ 0. 1. 0.]
129 [ 0. 0. 1.]]
130 Derived NPM : [[ 9.52552396e-01 0.00000000e+00 9.36786317e-05]
131 [ 3.43966450e-01 7.28166097e-01 -7.21325464e-02]
132 [ 0.00000000e+00 0.00000000e+00 1.00882518e+00]]
133 Derived NPM -1 : [[ 1.04981102e+00 0.00000000e+00 -9.74845406e-05]
134 [ -4.95903023e-01 1.37331305e+00 9.82400361e-02]
135 [ 0.00000000e+00 0.00000000e+00 9.91252018e-01]]
136 Use Derived NPM : False
137 Use Derived NPM -1 : False
138 """
139 ).strip()
140 )
142 def test__repr__(self) -> None:
143 """
144 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\
145__repr__` method.
146 """
148 assert re.sub(" at 0x\\w+>", "", repr(self._colourspace)) == (
149 textwrap.dedent(
150 """
151 RGB_Colourspace('RGB Colourspace',
152 [[ 7.34700000e-01, 2.65300000e-01],
153 [ 0.00000000e+00, 1.00000000e+00],
154 [ 1.00000000e-04, -7.70000000e-02]],
155 [ 0.32168, 0.33767],
156 'ACES',
157 [[ 1., 0., 0.],
158 [ 0., 1., 0.],
159 [ 0., 0., 1.]],
160 [[ 1., 0., 0.],
161 [ 0., 1., 0.],
162 [ 0., 0., 1.]],
163 linear_function,
164 linear_function,
165 False,
166 False)
167 """
168 ).strip()
169 )
171 def test_use_derived_transformation_matrices(self) -> None:
172 """
173 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\
174use_derived_transformation_matrices` method.
175 """
177 np.testing.assert_array_equal(
178 self._colourspace.matrix_RGB_to_XYZ, np.identity(3)
179 )
180 np.testing.assert_array_equal(
181 self._colourspace.matrix_XYZ_to_RGB, np.identity(3)
182 )
184 self._colourspace.use_derived_transformation_matrices()
186 np.testing.assert_allclose(
187 self._colourspace.matrix_RGB_to_XYZ,
188 np.array(
189 [
190 [0.95255240, 0.00000000, 0.00009368],
191 [0.34396645, 0.72816610, -0.07213255],
192 [0.00000000, 0.00000000, 1.00882518],
193 ]
194 ),
195 atol=TOLERANCE_ABSOLUTE_TESTS,
196 )
197 np.testing.assert_allclose(
198 self._colourspace.matrix_XYZ_to_RGB,
199 np.array(
200 [
201 [1.04981102, 0.00000000, -0.00009748],
202 [-0.49590302, 1.37331305, 0.09824004],
203 [0.00000000, 0.00000000, 0.99125202],
204 ]
205 ),
206 atol=TOLERANCE_ABSOLUTE_TESTS,
207 )
209 self._colourspace.use_derived_matrix_RGB_to_XYZ = False
210 np.testing.assert_array_equal(
211 self._colourspace.matrix_RGB_to_XYZ, np.identity(3)
212 )
213 self._colourspace.use_derived_matrix_XYZ_to_RGB = False
214 np.testing.assert_array_equal(
215 self._colourspace.matrix_XYZ_to_RGB, np.identity(3)
216 )
218 def test_chromatically_adapt(self) -> None:
219 """
220 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\
221chromatically_adapt` method.
222 """
224 whitepoint_t = np.array([0.31270, 0.32900])
225 colourspace = self._colourspace.chromatically_adapt(
226 whitepoint_t, "D50", "Bradford"
227 )
229 np.testing.assert_allclose(
230 colourspace.primaries,
231 np.array(
232 [
233 [0.73485524, 0.26422533],
234 [-0.00617091, 1.01131496],
235 [0.01596756, -0.06423550],
236 ]
237 ),
238 atol=TOLERANCE_ABSOLUTE_TESTS,
239 )
240 np.testing.assert_allclose(
241 colourspace.whitepoint, whitepoint_t, atol=TOLERANCE_ABSOLUTE_TESTS
242 )
244 assert colourspace.whitepoint_name == "D50"
246 np.testing.assert_allclose(
247 colourspace.primaries,
248 chromatically_adapted_primaries(
249 self._colourspace.primaries,
250 self._colourspace.whitepoint,
251 whitepoint_t,
252 "Bradford",
253 ),
254 atol=TOLERANCE_ABSOLUTE_TESTS,
255 )
257 np.testing.assert_allclose(
258 colourspace.matrix_RGB_to_XYZ,
259 normalised_primary_matrix(colourspace.primaries, colourspace.whitepoint),
260 atol=TOLERANCE_ABSOLUTE_TESTS,
261 )
263 np.testing.assert_allclose(
264 colourspace.matrix_XYZ_to_RGB,
265 np.linalg.inv(
266 normalised_primary_matrix(colourspace.primaries, colourspace.whitepoint)
267 ),
268 atol=TOLERANCE_ABSOLUTE_TESTS,
269 )
271 def test_copy(self) -> None:
272 """
273 Test :meth:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.copy`
274 method.
275 """
277 assert self._colourspace.copy() is not self
280class TestXYZ_to_RGB:
281 """
282 Define :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition
283 unit tests methods.
284 """
286 def test_XYZ_to_RGB(self) -> None:
287 """
288 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB`
289 definition.
290 """
292 np.testing.assert_allclose(
293 XYZ_to_RGB(
294 np.array([0.21638819, 0.12570000, 0.03847493]),
295 RGB_COLOURSPACE_sRGB,
296 np.array([0.34570, 0.35850]),
297 "Bradford",
298 True,
299 ),
300 np.array([0.70556403, 0.19112904, 0.22341005]),
301 atol=TOLERANCE_ABSOLUTE_TESTS,
302 )
304 np.testing.assert_allclose(
305 XYZ_to_RGB(
306 np.array([0.21638819, 0.12570000, 0.03847493]),
307 RGB_COLOURSPACE_sRGB,
308 apply_cctf_encoding=True,
309 ),
310 np.array([0.72794351, 0.18184112, 0.17951801]),
311 atol=TOLERANCE_ABSOLUTE_TESTS,
312 )
314 np.testing.assert_allclose(
315 XYZ_to_RGB(
316 np.array([0.21638819, 0.12570000, 0.03847493]),
317 RGB_COLOURSPACE_ACES2065_1,
318 np.array([0.34570, 0.35850]),
319 ),
320 np.array([0.21959099, 0.06985815, 0.04703704]),
321 atol=TOLERANCE_ABSOLUTE_TESTS,
322 )
324 np.testing.assert_allclose(
325 XYZ_to_RGB(
326 np.array([0.21638819, 0.12570000, 0.03847493]),
327 "sRGB",
328 np.array([0.34570, 0.35850]),
329 "Bradford",
330 True,
331 ),
332 XYZ_to_RGB(
333 np.array([0.21638819, 0.12570000, 0.03847493]),
334 RGB_COLOURSPACE_sRGB,
335 np.array([0.34570, 0.35850]),
336 "Bradford",
337 True,
338 ),
339 atol=TOLERANCE_ABSOLUTE_TESTS,
340 )
342 # TODO: Remove tests when dropping deprecated signature support.
343 np.testing.assert_allclose(
344 XYZ_to_RGB(
345 np.array([0.21638819, 0.12570000, 0.03847493]),
346 np.array([0.34570, 0.35850]), # pyright: ignore
347 np.array([0.31270, 0.32900]),
348 np.array( # pyright: ignore
349 [
350 [3.24062548, -1.53720797, -0.49862860],
351 [-0.96893071, 1.87575606, 0.04151752],
352 [0.05571012, -0.20402105, 1.05699594],
353 ]
354 ),
355 "Bradford", # pyright: ignore
356 eotf_inverse_sRGB,
357 ),
358 np.array([0.70556599, 0.19109268, 0.22340812]),
359 atol=TOLERANCE_ABSOLUTE_TESTS,
360 )
362 np.testing.assert_allclose(
363 XYZ_to_RGB(
364 np.array([0.21638819, 0.12570000, 0.03847493]),
365 np.array([0.34570, 0.35850]), # pyright: ignore
366 np.array([0.31270, 0.32900]),
367 np.array( # pyright: ignore
368 [
369 [3.24062548, -1.53720797, -0.49862860],
370 [-0.96893071, 1.87575606, 0.04151752],
371 [0.05571012, -0.20402105, 1.05699594],
372 ]
373 ),
374 None, # pyright: ignore
375 eotf_inverse_sRGB,
376 ),
377 np.array([0.72794579, 0.18180021, 0.17951580]),
378 atol=TOLERANCE_ABSOLUTE_TESTS,
379 )
381 np.testing.assert_allclose(
382 XYZ_to_RGB(
383 np.array([0.21638819, 0.12570000, 0.03847493]),
384 np.array([0.34570, 0.35850]), # pyright: ignore
385 np.array([0.32168, 0.33767]),
386 np.array( # pyright: ignore
387 [
388 [1.04981102, 0.00000000, -0.00009748],
389 [-0.49590302, 1.37331305, 0.09824004],
390 [0.00000000, 0.00000000, 0.99125202],
391 ]
392 ),
393 ),
394 np.array([0.21959099, 0.06985815, 0.04703704]),
395 atol=TOLERANCE_ABSOLUTE_TESTS,
396 )
398 np.testing.assert_allclose(
399 XYZ_to_RGB(
400 np.array([0.21638819, 0.12570000, 0.03847493]),
401 np.array([0.34570, 0.35850]), # pyright: ignore
402 np.array([0.31270, 0.32900, 1.00000]),
403 np.array( # pyright: ignore
404 [
405 [3.24062548, -1.53720797, -0.49862860],
406 [-0.96893071, 1.87575606, 0.04151752],
407 [0.05571012, -0.20402105, 1.05699594],
408 ]
409 ),
410 ),
411 np.array([0.45620801, 0.03079991, 0.04091883]),
412 atol=TOLERANCE_ABSOLUTE_TESTS,
413 )
415 def test_n_dimensional_XYZ_to_RGB(self) -> None:
416 """
417 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition
418 n-dimensional support.
419 """
421 XYZ = np.array([0.21638819, 0.12570000, 0.03847493])
422 W_R = np.array([0.34570, 0.35850])
423 RGB = XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True)
425 XYZ = np.tile(XYZ, (6, 1))
426 RGB = np.tile(RGB, (6, 1))
427 np.testing.assert_allclose(
428 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True),
429 RGB,
430 atol=TOLERANCE_ABSOLUTE_TESTS,
431 )
433 W_R = np.tile(W_R, (6, 1))
434 np.testing.assert_allclose(
435 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True),
436 RGB,
437 atol=TOLERANCE_ABSOLUTE_TESTS,
438 )
440 XYZ = np.reshape(XYZ, (2, 3, 3))
441 W_R = np.reshape(W_R, (2, 3, 2))
442 RGB = np.reshape(RGB, (2, 3, 3))
443 np.testing.assert_allclose(
444 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True),
445 RGB,
446 atol=TOLERANCE_ABSOLUTE_TESTS,
447 )
449 def test_domain_range_scale_XYZ_to_RGB(self) -> None:
450 """
451 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition
452 domain and range scale support.
453 """
455 XYZ = np.array([0.21638819, 0.12570000, 0.03847493])
456 W_R = np.array([0.34570, 0.35850])
457 RGB = XYZ_to_RGB(XYZ, "sRGB", W_R)
459 d_r = (("reference", 1), ("1", 1), ("100", 100))
460 for scale, factor in d_r:
461 with domain_range_scale(scale):
462 np.testing.assert_allclose(
463 XYZ_to_RGB(XYZ * factor, "sRGB", W_R),
464 RGB * factor,
465 atol=TOLERANCE_ABSOLUTE_TESTS,
466 )
468 @ignore_numpy_errors
469 def test_nan_XYZ_to_RGB(self) -> None:
470 """
471 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition
472 nan support.
473 """
475 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
476 cases = np.array(list(set(product(cases, repeat=3))))
477 XYZ_to_RGB(cases, "sRGB", cases[..., 0:2])
480class TestRGB_to_XYZ:
481 """
482 Define :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition
483 unit tests methods.
484 """
486 def test_RGB_to_XYZ(self) -> None:
487 """
488 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ`
489 definition.
490 """
492 np.testing.assert_allclose(
493 RGB_to_XYZ(
494 np.array([0.70556403, 0.19112904, 0.22341005]),
495 RGB_COLOURSPACE_sRGB,
496 np.array([0.34570, 0.35850]),
497 "Bradford",
498 True,
499 ),
500 np.array([0.21639121, 0.12570714, 0.03847642]),
501 atol=TOLERANCE_ABSOLUTE_TESTS,
502 )
504 np.testing.assert_allclose(
505 RGB_to_XYZ(
506 np.array([0.72794351, 0.18184112, 0.17951801]),
507 RGB_COLOURSPACE_sRGB,
508 apply_cctf_decoding=True,
509 ),
510 np.array([0.21639100, 0.12570754, 0.03847682]),
511 atol=TOLERANCE_ABSOLUTE_TESTS,
512 )
514 np.testing.assert_allclose(
515 RGB_to_XYZ(
516 np.array([0.21959099, 0.06985815, 0.04703704]),
517 RGB_COLOURSPACE_ACES2065_1,
518 np.array([0.34570, 0.35850]),
519 ),
520 np.array([0.21638819, 0.12570000, 0.03847493]),
521 atol=TOLERANCE_ABSOLUTE_TESTS,
522 )
524 np.testing.assert_allclose(
525 RGB_to_XYZ(
526 np.array([0.21638819, 0.12570000, 0.03847493]),
527 "sRGB",
528 np.array([0.34570, 0.35850]),
529 "Bradford",
530 True,
531 ),
532 RGB_to_XYZ(
533 np.array([0.21638819, 0.12570000, 0.03847493]),
534 RGB_COLOURSPACE_sRGB,
535 np.array([0.34570, 0.35850]),
536 "Bradford",
537 True,
538 ),
539 atol=TOLERANCE_ABSOLUTE_TESTS,
540 )
542 # TODO: Remove tests when dropping deprecated signature support.
543 np.testing.assert_allclose(
544 RGB_to_XYZ(
545 np.array([0.70556599, 0.19109268, 0.22340812]),
546 np.array([0.31270, 0.32900]), # pyright: ignore
547 np.array([0.34570, 0.35850]),
548 np.array( # pyright: ignore
549 [
550 [0.41240000, 0.35760000, 0.18050000],
551 [0.21260000, 0.71520000, 0.07220000],
552 [0.01930000, 0.11920000, 0.95050000],
553 ]
554 ),
555 "Bradford", # pyright: ignore
556 eotf_sRGB,
557 ),
558 np.array([0.21638819, 0.12570000, 0.03847493]),
559 atol=TOLERANCE_ABSOLUTE_TESTS,
560 )
562 np.testing.assert_allclose(
563 RGB_to_XYZ(
564 np.array([0.72794579, 0.18180021, 0.17951580]),
565 np.array([0.31270, 0.32900]), # pyright: ignore
566 np.array([0.34570, 0.35850]),
567 np.array( # pyright: ignore
568 [
569 [0.41240000, 0.35760000, 0.18050000],
570 [0.21260000, 0.71520000, 0.07220000],
571 [0.01930000, 0.11920000, 0.95050000],
572 ]
573 ),
574 None, # pyright: ignore
575 eotf_sRGB,
576 ),
577 np.array([0.21638819, 0.12570000, 0.03847493]),
578 atol=TOLERANCE_ABSOLUTE_TESTS,
579 )
581 np.testing.assert_allclose(
582 RGB_to_XYZ(
583 np.array([0.21959099, 0.06985815, 0.04703704]),
584 np.array([0.32168, 0.33767]), # pyright: ignore
585 np.array([0.34570, 0.35850]),
586 np.array( # pyright: ignore
587 [
588 [0.95255240, 0.00000000, 0.00009368],
589 [0.34396645, 0.72816610, -0.07213255],
590 [0.00000000, 0.00000000, 1.00882518],
591 ]
592 ),
593 ),
594 np.array([0.21638819, 0.12570000, 0.03847493]),
595 atol=TOLERANCE_ABSOLUTE_TESTS,
596 )
598 np.testing.assert_allclose(
599 RGB_to_XYZ(
600 np.array([0.45620801, 0.03079991, 0.04091883]),
601 np.array([0.31270, 0.32900, 1.00000]), # pyright: ignore
602 np.array([0.34570, 0.35850]),
603 np.array( # pyright: ignore
604 [
605 [0.41240000, 0.35760000, 0.18050000],
606 [0.21260000, 0.71520000, 0.07220000],
607 [0.01930000, 0.11920000, 0.95050000],
608 ]
609 ),
610 ),
611 np.array([0.21638819, 0.12570000, 0.03847493]),
612 atol=TOLERANCE_ABSOLUTE_TESTS,
613 )
615 def test_n_dimensional_RGB_to_XYZ(self) -> None:
616 """
617 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition
618 n-dimensional support.
619 """
621 RGB = np.array([0.70556599, 0.19109268, 0.22340812])
622 W_R = np.array([0.31270, 0.32900])
623 XYZ = RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True)
625 RGB = np.tile(RGB, (6, 1))
626 XYZ = np.tile(XYZ, (6, 1))
627 np.testing.assert_allclose(
628 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True),
629 XYZ,
630 atol=TOLERANCE_ABSOLUTE_TESTS,
631 )
633 W_R = np.tile(W_R, (6, 1))
634 np.testing.assert_allclose(
635 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True),
636 XYZ,
637 atol=TOLERANCE_ABSOLUTE_TESTS,
638 )
640 RGB = np.reshape(RGB, (2, 3, 3))
641 W_R = np.reshape(W_R, (2, 3, 2))
642 XYZ = np.reshape(XYZ, (2, 3, 3))
643 np.testing.assert_allclose(
644 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True),
645 XYZ,
646 atol=TOLERANCE_ABSOLUTE_TESTS,
647 )
649 def test_domain_range_scale_XYZ_to_RGB(self) -> None:
650 """
651 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition
652 domain and range scale support.
653 """
655 RGB = np.array([0.45620801, 0.03079991, 0.04091883])
656 W_R = np.array([0.31270, 0.32900])
657 XYZ = RGB_to_XYZ(RGB, "sRGB", W_R)
659 d_r = (("reference", 1), ("1", 1), ("100", 100))
660 for scale, factor in d_r:
661 with domain_range_scale(scale):
662 np.testing.assert_allclose(
663 RGB_to_XYZ(RGB * factor, "sRGB", W_R),
664 XYZ * factor,
665 atol=TOLERANCE_ABSOLUTE_TESTS,
666 )
668 @ignore_numpy_errors
669 def test_nan_RGB_to_XYZ(self) -> None:
670 """
671 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition
672 nan support.
673 """
675 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
676 cases = np.array(list(set(product(cases, repeat=3))))
677 RGB_to_XYZ(cases, "sRGB", cases[..., 0:2])
680class TestMatrix_RGB_to_RGB:
681 """
682 Define :func:`colour.models.rgb.rgb_colourspace.matrix_RGB_to_RGB`
683 definition unit tests methods.
684 """
686 def test_matrix_RGB_to_RGB(self) -> None:
687 """
688 Test :func:`colour.models.rgb.rgb_colourspace.matrix_RGB_to_RGB`
689 definition.
690 """
692 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]
693 aces_cg_colourspace = RGB_COLOURSPACES["ACEScg"]
694 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]
696 np.testing.assert_allclose(
697 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace),
698 np.array(
699 [
700 [2.52164943, -1.13688855, -0.38491759],
701 [-0.27521355, 1.36970515, -0.09439245],
702 [-0.01592501, -0.14780637, 1.16380582],
703 ]
704 ),
705 atol=TOLERANCE_ABSOLUTE_TESTS,
706 )
708 np.testing.assert_allclose(
709 matrix_RGB_to_RGB(sRGB_colourspace, aces_2065_1_colourspace),
710 np.array(
711 [
712 [0.43958564, 0.38392940, 0.17653274],
713 [0.08953957, 0.81474984, 0.09568361],
714 [0.01738718, 0.10873911, 0.87382059],
715 ]
716 ),
717 atol=TOLERANCE_ABSOLUTE_TESTS,
718 )
720 np.testing.assert_allclose(
721 matrix_RGB_to_RGB(aces_2065_1_colourspace, aces_cg_colourspace, "Bradford"),
722 np.array(
723 [
724 [1.45143932, -0.23651075, -0.21492857],
725 [-0.07655377, 1.17622970, -0.09967593],
726 [0.00831615, -0.00603245, 0.99771630],
727 ]
728 ),
729 atol=TOLERANCE_ABSOLUTE_TESTS,
730 )
732 np.testing.assert_allclose(
733 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace, "Bradford"),
734 np.array(
735 [
736 [2.52140089, -1.13399575, -0.38756186],
737 [-0.27621406, 1.37259557, -0.09628236],
738 [-0.01532020, -0.15299256, 1.16838720],
739 ]
740 ),
741 atol=TOLERANCE_ABSOLUTE_TESTS,
742 )
744 np.testing.assert_allclose(
745 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace, None),
746 np.array(
747 [
748 [2.55809607, -1.11933692, -0.39181451],
749 [-0.27771575, 1.36589396, -0.09353075],
750 [-0.01711199, -0.14854588, 1.08104848],
751 ]
752 ),
753 atol=TOLERANCE_ABSOLUTE_TESTS,
754 )
756 np.testing.assert_allclose(
757 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace),
758 matrix_RGB_to_RGB("ACES2065-1", "sRGB"),
759 atol=TOLERANCE_ABSOLUTE_TESTS,
760 )
763class TestRGB_to_RGB:
764 """
765 Define :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition
766 unit tests methods.
767 """
769 def test_RGB_to_RGB(self) -> None:
770 """Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition."""
772 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]
773 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]
775 np.testing.assert_allclose(
776 RGB_to_RGB(
777 np.array([0.21931722, 0.06950287, 0.04694832]),
778 aces_2065_1_colourspace,
779 sRGB_colourspace,
780 ),
781 np.array([0.45595289, 0.03040780, 0.04087313]),
782 atol=TOLERANCE_ABSOLUTE_TESTS,
783 )
785 np.testing.assert_allclose(
786 RGB_to_RGB(
787 np.array([0.45595571, 0.03039702, 0.04087245]),
788 sRGB_colourspace,
789 aces_2065_1_colourspace,
790 ),
791 np.array([0.21931722, 0.06950287, 0.04694832]),
792 atol=TOLERANCE_ABSOLUTE_TESTS,
793 )
795 np.testing.assert_allclose(
796 RGB_to_RGB(
797 np.array([0.21931722, 0.06950287, 0.04694832]),
798 aces_2065_1_colourspace,
799 sRGB_colourspace,
800 "Bradford",
801 ),
802 np.array([0.45597530, 0.03030054, 0.04086041]),
803 atol=TOLERANCE_ABSOLUTE_TESTS,
804 )
806 np.testing.assert_allclose(
807 RGB_to_RGB(
808 np.array([0.21931722, 0.06950287, 0.04694832]),
809 aces_2065_1_colourspace,
810 sRGB_colourspace,
811 None,
812 ),
813 np.array([0.46484236, 0.02963459, 0.03667609]),
814 atol=TOLERANCE_ABSOLUTE_TESTS,
815 )
817 aces_cg_colourspace = RGB_COLOURSPACES["ACEScg"]
818 aces_cc_colourspace = RGB_COLOURSPACES["ACEScc"]
820 np.testing.assert_allclose(
821 RGB_to_RGB(
822 np.array([0.21931722, 0.06950287, 0.04694832]),
823 aces_cg_colourspace,
824 aces_cc_colourspace,
825 apply_cctf_decoding=True,
826 apply_cctf_encoding=True,
827 ),
828 np.array([0.42985679, 0.33522924, 0.30292336]),
829 atol=TOLERANCE_ABSOLUTE_TESTS,
830 )
832 np.testing.assert_allclose(
833 RGB_to_RGB(
834 np.array([0.46956438, 0.48137533, 0.43788601]),
835 aces_cc_colourspace,
836 sRGB_colourspace,
837 apply_cctf_decoding=True,
838 apply_cctf_encoding=True,
839 ),
840 np.array([0.60983062, 0.67896356, 0.50435764]),
841 atol=TOLERANCE_ABSOLUTE_TESTS,
842 )
844 np.testing.assert_equal(
845 RGB_to_RGB(
846 np.array([0.21931722, 0.06950287, 0.04694832]),
847 aces_2065_1_colourspace,
848 RGB_COLOURSPACES["ProPhoto RGB"],
849 apply_cctf_encoding=True,
850 out_int=True,
851 ),
852 np.array([120, 59, 46]),
853 )
855 np.testing.assert_allclose(
856 RGB_to_RGB(
857 np.array([0.21931722, 0.06950287, 0.04694832]),
858 aces_2065_1_colourspace,
859 sRGB_colourspace,
860 ),
861 RGB_to_RGB(
862 np.array([0.21931722, 0.06950287, 0.04694832]),
863 "ACES2065-1",
864 "sRGB",
865 ),
866 atol=TOLERANCE_ABSOLUTE_TESTS,
867 )
869 def test_n_dimensional_RGB_to_RGB(self) -> None:
870 """
871 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition
872 n-dimensional support.
873 """
875 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]
876 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]
877 RGB_i = np.array([0.21931722, 0.06950287, 0.04694832])
878 RGB_o = RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace)
880 RGB_i = np.tile(RGB_i, (6, 1))
881 RGB_o = np.tile(RGB_o, (6, 1))
882 np.testing.assert_allclose(
883 RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace),
884 RGB_o,
885 atol=TOLERANCE_ABSOLUTE_TESTS,
886 )
888 RGB_i = np.reshape(RGB_i, (2, 3, 3))
889 RGB_o = np.reshape(RGB_o, (2, 3, 3))
890 np.testing.assert_allclose(
891 RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace),
892 RGB_o,
893 atol=TOLERANCE_ABSOLUTE_TESTS,
894 )
896 def test_domain_range_scale_XYZ_to_RGB(self) -> None:
897 """
898 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition
899 domain and range scale support.
900 """
902 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]
903 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]
904 RGB_i = np.array([0.21931722, 0.06950287, 0.04694832])
905 RGB_o = RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace)
907 d_r = (("reference", 1), ("1", 1), ("100", 100))
908 for scale, factor in d_r:
909 with domain_range_scale(scale):
910 np.testing.assert_allclose(
911 RGB_to_RGB(
912 RGB_i * factor,
913 aces_2065_1_colourspace,
914 sRGB_colourspace,
915 ),
916 RGB_o * factor,
917 atol=TOLERANCE_ABSOLUTE_TESTS,
918 )
920 @ignore_numpy_errors
921 def test_nan_RGB_to_RGB(self) -> None:
922 """
923 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition
924 nan support.
925 """
927 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]
928 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]
930 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
931 cases = np.array(list(set(product(cases, repeat=3))))
932 RGB_to_RGB(cases, aces_2065_1_colourspace, sRGB_colourspace)