Coverage for temperature/kang2002.py: 65%

40 statements  

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

1""" 

2Kang, Moon, Hong, Lee, Cho and Kim (2002) Correlated Colour Temperature 

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

4 

5Define the *Kang et al. (2002)* correlated colour temperature :math:`T_{cp}` 

6computation objects. 

7 

8- :func:`colour.temperature.xy_to_CCT_Kang2002`: Compute correlated colour 

9 temperature :math:`T_{cp}` from specified *CIE xy* chromaticity 

10 coordinates using the *Kang, Moon, Hong, Lee, Cho and Kim (2002)* method. 

11- :func:`colour.temperature.CCT_to_xy_Kang2002`: Compute *CIE xy* 

12 chromaticity coordinates from specified correlated colour temperature 

13 :math:`T_{cp}` using the *Kang, Moon, Hong, Lee, Cho and Kim (2002)* 

14 method. 

15 

16References 

17---------- 

18- :cite:`Kang2002a` : Kang, B., Moon, O., Hong, C., Lee, H., Cho, B., & Kim, 

19 Y. (2002). Design of advanced color: Temperature control system for HDTV 

20 applications. Journal of the Korean Physical Society, 41(6), 865-871. 

21""" 

22 

23from __future__ import annotations 

24 

25import typing 

26 

27import numpy as np 

28 

29if typing.TYPE_CHECKING: 

30 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat 

31 

32from colour.utilities import as_float, as_float_array, required, tstack, usage_warning 

33 

34__author__ = "Colour Developers" 

35__copyright__ = "Copyright 2013 Colour Developers" 

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

37__maintainer__ = "Colour Developers" 

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

39__status__ = "Production" 

40 

41__all__ = [ 

42 "xy_to_CCT_Kang2002", 

43 "CCT_to_xy_Kang2002", 

44] 

45 

46 

47@required("SciPy") 

48def xy_to_CCT_Kang2002( 

49 xy: ArrayLike, optimisation_kwargs: dict | None = None 

50) -> NDArrayFloat: 

51 """ 

52 Compute the correlated colour temperature :math:`T_{cp}` from the 

53 specified *CIE xy* chromaticity coordinates using *Kang et al. (2002)* 

54 method. 

55 

56 Parameters 

57 ---------- 

58 xy 

59 *CIE xy* chromaticity coordinates. 

60 optimisation_kwargs 

61 Parameters for :func:`scipy.optimize.minimize` definition. 

62 

63 Returns 

64 ------- 

65 :class:`numpy.ndarray` 

66 Correlated colour temperature :math:`T_{cp}`. 

67 

68 Warnings 

69 -------- 

70 The *Kang et al. (2002)* method does not provide an analytical inverse 

71 transformation to compute the correlated colour temperature 

72 :math:`T_{cp}` from the specified *CIE xy* chromaticity coordinates. 

73 The current implementation relies on optimisation using 

74 :func:`scipy.optimize.minimize` definition and thus has reduced 

75 precision and poor performance. 

76 

77 References 

78 ---------- 

79 :cite:`Kang2002a` 

80 

81 Examples 

82 -------- 

83 >>> xy_to_CCT_Kang2002(np.array([0.31342600, 0.32359597])) 

84 ... # doctest: +ELLIPSIS 

85 6504.3893128... 

86 """ 

87 

88 from scipy.optimize import minimize # noqa: PLC0415 

89 

90 xy = as_float_array(xy) 

91 shape = xy.shape 

92 xy = np.atleast_1d(np.reshape(xy, (-1, 2))) 

93 

94 def objective_function(CCT: NDArrayFloat, xy: NDArrayFloat) -> DTypeFloat: 

95 """Objective function.""" 

96 

97 objective = np.linalg.norm(CCT_to_xy_Kang2002(CCT) - xy) 

98 

99 return as_float(objective) 

100 

101 optimisation_settings = { 

102 "method": "Nelder-Mead", 

103 "options": { 

104 "fatol": 1e-10, 

105 }, 

106 } 

107 if optimisation_kwargs is not None: 

108 optimisation_settings.update(optimisation_kwargs) 

109 

110 CCT = as_float_array( 

111 [ 

112 minimize( 

113 objective_function, 

114 x0=[6500], 

115 args=(xy_i,), 

116 **optimisation_settings, 

117 ).x 

118 for xy_i in xy 

119 ] 

120 ) 

121 

122 return as_float(np.reshape(CCT, shape[:-1])) 

123 

124 

125def CCT_to_xy_Kang2002(CCT: ArrayLike) -> NDArrayFloat: 

126 """ 

127 Compute the *CIE xy* chromaticity coordinates from the specified 

128 correlated colour temperature :math:`T_{cp}` using *Kang et al. (2002)* 

129 method. 

130 

131 Parameters 

132 ---------- 

133 CCT 

134 Correlated colour temperature :math:`T_{cp}`. 

135 

136 Returns 

137 ------- 

138 :class:`numpy.ndarray` 

139 *CIE xy* chromaticity coordinates. 

140 

141 Raises 

142 ------ 

143 ValueError 

144 If the correlated colour temperature is not in appropriate domain. 

145 

146 References 

147 ---------- 

148 :cite:`Kang2002a` 

149 

150 Examples 

151 -------- 

152 >>> CCT_to_xy_Kang2002(6504.38938305) # doctest: +ELLIPSIS 

153 array([ 0.313426 ..., 0.3235959...]) 

154 """ 

155 

156 CCT = as_float_array(CCT) 

157 

158 if np.any(CCT[np.asarray(np.logical_or(CCT < 1667, CCT > 25000))]): 

159 usage_warning( 

160 "Correlated colour temperature must be in domain " 

161 "[1667, 25000], unpredictable results may occur!" 

162 ) 

163 

164 CCT_3 = CCT**3 

165 CCT_2 = CCT**2 

166 

167 x = np.where( 

168 CCT <= 4000, 

169 -0.2661239 * 10**9 / CCT_3 

170 - 0.2343589 * 10**6 / CCT_2 

171 + 0.8776956 * 10**3 / CCT 

172 + 0.179910, 

173 -3.0258469 * 10**9 / CCT_3 

174 + 2.1070379 * 10**6 / CCT_2 

175 + 0.2226347 * 10**3 / CCT 

176 + 0.24039, 

177 ) 

178 

179 x_3 = x**3 

180 x_2 = x**2 

181 

182 cnd_l = [CCT <= 2222, np.logical_and(CCT > 2222, CCT <= 4000), CCT > 4000] 

183 i = -1.1063814 * x_3 - 1.34811020 * x_2 + 2.18555832 * x - 0.20219683 

184 j = -0.9549476 * x_3 - 1.37418593 * x_2 + 2.09137015 * x - 0.16748867 

185 k = 3.0817580 * x_3 - 5.8733867 * x_2 + 3.75112997 * x - 0.37001483 

186 y = np.select(cnd_l, [i, j, k]) 

187 

188 return tstack([x, y])