Coverage for models/cie_uvw.py: 56%

34 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1""" 

2CIE 1964 U*V*W* Colourspace 

3=========================== 

4 

5Define the *CIE 1964 U\\*V\\*W\\** colourspace transformations. 

6 

7- :func:`colour.XYZ_to_UVW` 

8- :func:`colour.UVW_to_XYZ` 

9 

10References 

11---------- 

12- :cite:`Wikipedia2008a` : Wikipedia. (2008). CIE 1964 color space. 

13 Retrieved June 10, 2014, from 

14 http://en.wikipedia.org/wiki/CIE_1964_color_space 

15""" 

16 

17from __future__ import annotations 

18 

19from colour.algebra import sdiv, sdiv_mode, spow 

20from colour.colorimetry import CCS_ILLUMINANTS 

21from colour.hints import ( # noqa: TC001 

22 ArrayLike, 

23 Domain100, 

24 Range100, 

25) 

26from colour.models import UCS_uv_to_xy, XYZ_to_xy, xy_to_UCS_uv, xyY_to_xy, xyY_to_XYZ 

27from colour.utilities import from_range_100, to_domain_100, tsplit, tstack 

28 

29__author__ = "Colour Developers" 

30__copyright__ = "Copyright 2013 Colour Developers" 

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

32__maintainer__ = "Colour Developers" 

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

34__status__ = "Production" 

35 

36__all__ = [ 

37 "XYZ_to_UVW", 

38 "UVW_to_XYZ", 

39] 

40 

41 

42def XYZ_to_UVW( 

43 XYZ: Domain100, 

44 illuminant: ArrayLike = CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"][ 

45 "D65" 

46 ], 

47) -> Range100: 

48 """ 

49 Convert from *CIE XYZ* tristimulus values to *CIE 1964 U\\*V\\*W\\** 

50 colourspace. 

51 

52 Parameters 

53 ---------- 

54 XYZ 

55 *CIE XYZ* tristimulus values. 

56 illuminant 

57 Reference *illuminant* *CIE xy* chromaticity coordinates or *CIE xyY* 

58 colourspace array. 

59 

60 Returns 

61 ------- 

62 :class:`numpy.ndarray` 

63 *CIE 1964 U\\*V\\*W\\** colourspace array. 

64 

65 Notes 

66 ----- 

67 +----------------+-----------------------+-----------------+ 

68 | **Domain** | **Scale - Reference** | **Scale - 1** | 

69 +================+=======================+=================+ 

70 | ``XYZ`` | 100 | 1 | 

71 +----------------+-----------------------+-----------------+ 

72 | ``illuminant`` | 1 | 1 | 

73 +----------------+-----------------------+-----------------+ 

74 

75 +----------------+-----------------------+-----------------+ 

76 | **Range** | **Scale - Reference** | **Scale - 1** | 

77 +================+=======================+=================+ 

78 | ``UVW`` | 100 | 1 | 

79 +----------------+-----------------------+-----------------+ 

80 

81 References 

82 ---------- 

83 :cite:`Wikipedia2008a` 

84 

85 Examples 

86 -------- 

87 >>> import numpy as np 

88 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) * 100 

89 >>> XYZ_to_UVW(XYZ) # doctest: +ELLIPSIS 

90 array([ 94.5503572..., 11.5553652..., 40.5475740...]) 

91 """ 

92 

93 XYZ = to_domain_100(XYZ) 

94 

95 xy = XYZ_to_xy(XYZ / 100) 

96 xy_n = xyY_to_xy(illuminant) 

97 Y = XYZ[..., 1] 

98 

99 uv = xy_to_UCS_uv(xy) 

100 uv_0 = xy_to_UCS_uv(xy_n) 

101 

102 W = 25 * spow(Y, 1 / 3) - 17 

103 U, V = tsplit(13 * W[..., None] * (uv - uv_0)) 

104 

105 UVW = tstack([U, V, W]) 

106 

107 return from_range_100(UVW) 

108 

109 

110def UVW_to_XYZ( 

111 UVW: Domain100, 

112 illuminant: ArrayLike = CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"][ 

113 "D65" 

114 ], 

115) -> Range100: 

116 """ 

117 Convert from *CIE 1964 U\\*V\\*W\\** colourspace to *CIE XYZ* tristimulus 

118 values. 

119 

120 Parameters 

121 ---------- 

122 UVW 

123 *CIE 1964 U\\*V\\*W\\** colourspace array. 

124 illuminant 

125 Reference *illuminant* *CIE xy* chromaticity coordinates or *CIE xyY* 

126 colourspace array. 

127 

128 Returns 

129 ------- 

130 :class:`numpy.ndarray` 

131 *CIE XYZ* tristimulus values. 

132 

133 Notes 

134 ----- 

135 +----------------+-----------------------+-----------------+ 

136 | **Domain** | **Scale - Reference** | **Scale - 1** | 

137 +================+=======================+=================+ 

138 | ``UVW`` | 100 | 1 | 

139 +----------------+-----------------------+-----------------+ 

140 | ``illuminant`` | 1 | 1 | 

141 +----------------+-----------------------+-----------------+ 

142 

143 +----------------+-----------------------+-----------------+ 

144 | **Range** | **Scale - Reference** | **Scale - 1** | 

145 +================+=======================+=================+ 

146 | ``XYZ`` | 100 | 1 | 

147 +----------------+-----------------------+-----------------+ 

148 

149 References 

150 ---------- 

151 :cite:`Wikipedia2008a` 

152 

153 Examples 

154 -------- 

155 >>> import numpy as np 

156 >>> UVW = np.array([94.55035725, 11.55536523, 40.54757405]) 

157 >>> UVW_to_XYZ(UVW) 

158 array([ 20.654008, 12.197225, 5.136952]) 

159 """ 

160 

161 U, V, W = tsplit(to_domain_100(UVW)) 

162 

163 u_0, v_0 = tsplit(xy_to_UCS_uv(xyY_to_xy(illuminant))) 

164 

165 Y = ((W + 17) / 25) ** 3 

166 

167 with sdiv_mode(): 

168 u = sdiv(U, 13 * W) + u_0 

169 v = sdiv(V, 13 * W) + v_0 

170 

171 x, y = tsplit(UCS_uv_to_xy(tstack([u, v]))) 

172 

173 XYZ = xyY_to_XYZ(tstack([x, y, Y])) 

174 

175 return from_range_100(XYZ)