Coverage for colour/models/rgb/datasets/tests/test__init__.py: 100%

64 statements  

« 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.datasets` module.""" 

2 

3from __future__ import annotations 

4 

5import pickle 

6from copy import deepcopy 

7 

8import numpy as np 

9 

10from colour.constants import TOLERANCE_ABSOLUTE_TESTS 

11from colour.models import RGB_COLOURSPACES, normalised_primary_matrix 

12from colour.utilities import ignore_numpy_errors 

13 

14__author__ = "Colour Developers" 

15__copyright__ = "Copyright 2013 Colour Developers" 

16__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" 

17__maintainer__ = "Colour Developers" 

18__email__ = "colour-developers@colour-science.org" 

19__status__ = "Production" 

20 

21__all__ = [ 

22 "TestRGB_COLOURSPACES", 

23] 

24 

25 

26class TestRGB_COLOURSPACES: 

27 """ 

28 Define :attr:`colour.models.rgb.datasets.RGB_COLOURSPACES` 

29 attribute unit tests methods. 

30 """ 

31 

32 def test_transformation_matrices(self) -> None: 

33 """ 

34 Test the transformations matrices from the 

35 :attr:`colour.models.rgb.datasets.RGB_COLOURSPACES` attribute 

36 colourspace models. 

37 """ 

38 

39 tolerances = { 

40 "Adobe RGB (1998)": 1e-5, 

41 "ARRI Wide Gamut 3": 1e-6, 

42 "DJI D-Gamut": 5e-4, 

43 "ERIMM RGB": 1e-3, 

44 "FilmLight E-Gamut 2": 1e-6, 

45 "Gamma 2.2 Encoded AdobeRGB": 1e-5, 

46 "Linear AdobeRGB": 1e-5, 

47 "ProPhoto RGB": 1e-3, 

48 "REDWideGamutRGB": 1e-6, 

49 "RIMM RGB": 1e-3, 

50 "ROMM RGB": 1e-3, 

51 "sRGB": 1e-4, 

52 "V-Gamut": 1e-6, 

53 } 

54 XYZ_r = np.reshape(np.array([0.5, 0.5, 0.5]), (3, 1)) 

55 for colourspace in RGB_COLOURSPACES.values(): 

56 M = normalised_primary_matrix(colourspace.primaries, colourspace.whitepoint) 

57 

58 tolerance = tolerances.get(colourspace.name, 1e-7) 

59 np.testing.assert_allclose( 

60 colourspace.matrix_RGB_to_XYZ, 

61 M, 

62 atol=tolerance, 

63 ) 

64 

65 RGB = np.dot(colourspace.matrix_XYZ_to_RGB, XYZ_r) 

66 XYZ = np.dot(colourspace.matrix_RGB_to_XYZ, RGB) 

67 np.testing.assert_allclose(XYZ_r, XYZ, atol=tolerance) 

68 

69 # Derived transformation matrices. 

70 colourspace = deepcopy(colourspace) # noqa: PLW2901 

71 colourspace.use_derived_transformation_matrices(True) 

72 RGB = np.dot(colourspace.matrix_XYZ_to_RGB, XYZ_r) 

73 XYZ = np.dot(colourspace.matrix_RGB_to_XYZ, RGB) 

74 np.testing.assert_allclose(XYZ_r, XYZ, atol=tolerance) 

75 

76 def test_cctf(self) -> None: 

77 """ 

78 Test colour component transfer functions from the 

79 :attr:`colour.models.rgb.datasets.RGB_COLOURSPACES` attribute 

80 colourspace models. 

81 """ 

82 

83 ignored_colourspaces = ("ACESproxy",) 

84 

85 tolerance = {"DJI D-Gamut": 0.1, "F-Gamut": 1e-4, "N-Gamut": 1e-3} 

86 

87 samples = np.hstack( 

88 [np.linspace(0, 1, int(1e5)), np.linspace(0, 65504, 65504 * 10)] 

89 ) 

90 

91 for colourspace in RGB_COLOURSPACES.values(): 

92 if colourspace.name in ignored_colourspaces: 

93 continue 

94 

95 cctf_encoding_s = colourspace.cctf_encoding(samples) 

96 cctf_decoding_s = colourspace.cctf_decoding(cctf_encoding_s) 

97 

98 np.testing.assert_allclose( 

99 samples, 

100 cctf_decoding_s, 

101 atol=tolerance.get(colourspace.name, TOLERANCE_ABSOLUTE_TESTS), 

102 ) 

103 

104 def test_n_dimensional_cctf(self) -> None: 

105 """ 

106 Test colour component transfer functions from the 

107 :attr:`colour.models.rgb.datasets.RGB_COLOURSPACES` attribute 

108 colourspace models n-dimensional arrays support. 

109 """ 

110 

111 tolerance = {"DJI D-Gamut": 1e-6, "F-Gamut": 1e-4} 

112 

113 for colourspace in RGB_COLOURSPACES.values(): 

114 value_cctf_encoding = 0.5 

115 value_cctf_decoding = colourspace.cctf_decoding( 

116 colourspace.cctf_encoding(value_cctf_encoding) 

117 ) 

118 np.testing.assert_allclose( 

119 value_cctf_encoding, 

120 value_cctf_decoding, 

121 atol=tolerance.get(colourspace.name, 1e-7), 

122 ) 

123 

124 value_cctf_encoding = np.tile(value_cctf_encoding, 6) 

125 value_cctf_decoding = np.tile(value_cctf_decoding, 6) 

126 np.testing.assert_allclose( 

127 value_cctf_encoding, 

128 value_cctf_decoding, 

129 atol=tolerance.get(colourspace.name, 1e-7), 

130 ) 

131 

132 value_cctf_encoding = np.reshape(value_cctf_encoding, (3, 2)) 

133 value_cctf_decoding = np.reshape(value_cctf_decoding, (3, 2)) 

134 np.testing.assert_allclose( 

135 value_cctf_encoding, 

136 value_cctf_decoding, 

137 atol=tolerance.get(colourspace.name, 1e-7), 

138 ) 

139 

140 value_cctf_encoding = np.reshape(value_cctf_encoding, (3, 2, 1)) 

141 value_cctf_decoding = np.reshape(value_cctf_decoding, (3, 2, 1)) 

142 np.testing.assert_allclose( 

143 value_cctf_encoding, 

144 value_cctf_decoding, 

145 atol=tolerance.get(colourspace.name, 1e-7), 

146 ) 

147 

148 @ignore_numpy_errors 

149 def test_nan_cctf(self) -> None: 

150 """ 

151 Test colour component transfer functions from the 

152 :attr:`colour.models.rgb.datasets.RGB_COLOURSPACES` attribute 

153 colourspace models nan support. 

154 """ 

155 

156 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] 

157 for colourspace in RGB_COLOURSPACES.values(): 

158 colourspace.cctf_encoding(cases) 

159 colourspace.cctf_decoding(cases) 

160 

161 def test_pickle(self) -> None: 

162 """Test the "pickle-ability" of the *RGB* colourspaces.""" 

163 

164 for colourspace in RGB_COLOURSPACES.values(): 

165 pickle.dumps(colourspace)