Coverage for colorimetry/yellowness.py: 41%

39 statements  

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

1""" 

2Yellowness Index :math:`Y` 

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

4 

5Define the *yellowness* index :math:`Y` computation methods. 

6 

7- :func:`colour.colorimetry.yellowness_ASTMD1925`: Compute *yellowness* 

8 index :math:`YI` using *ASTM D1925* method for plastics. 

9- :func:`colour.colorimetry.yellowness_ASTME313_alternative`: Compute 

10 *yellowness* index :math:`YI` using the alternative *ASTM E313* method. 

11- :func:`colour.colorimetry.yellowness_ASTME313`: Compute *yellowness* 

12 index :math:`YI` using the recommended *ASTM E313* method. 

13- :attr:`colour.YELLOWNESS_METHODS`: Supported *yellowness* computation 

14 methods. 

15- :func:`colour.yellowness`: Compute *yellowness* :math:`YI` using 

16 specified method. 

17 

18References 

19---------- 

20- :cite:`ASTMInternational2015` : ASTM International. (2015). ASTM E313-15e1 

21 - Standard Practice for Calculating Yellowness and Whiteness Indices from 

22 Instrumentally Measured Color Coordinates. doi:10.1520/E0313-20 

23- :cite:`X-Rite2012a` : X-Rite, & Pantone. (2012). Color iQC and Color iMatch 

24 Color Calculations Guide. 

25 https://www.xrite.com/-/media/xrite/files/apps_engineering_techdocuments/\ 

26c/09_color_calculations_en.pdf 

27""" 

28 

29from __future__ import annotations 

30 

31import typing 

32 

33import numpy as np 

34 

35from colour.algebra import sdiv, sdiv_mode 

36 

37if typing.TYPE_CHECKING: 

38 from colour.hints import Any, Literal 

39 

40from colour.hints import ( # noqa: TC001 

41 ArrayLike, 

42 Domain100, 

43 Range100, 

44) 

45from colour.utilities import ( 

46 CanonicalMapping, 

47 as_float, 

48 filter_kwargs, 

49 from_range_100, 

50 to_domain_100, 

51 tsplit, 

52 validate_method, 

53) 

54 

55__author__ = "Colour Developers" 

56__copyright__ = "Copyright 2013 Colour Developers" 

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

58__maintainer__ = "Colour Developers" 

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

60__status__ = "Production" 

61 

62__all__ = [ 

63 "yellowness_ASTMD1925", 

64 "yellowness_ASTME313_alternative", 

65 "YELLOWNESS_COEFFICIENTS_ASTME313", 

66 "yellowness_ASTME313", 

67 "YELLOWNESS_METHODS", 

68 "yellowness", 

69] 

70 

71 

72def yellowness_ASTMD1925( 

73 XYZ: Domain100, 

74) -> Range100: 

75 """ 

76 Compute the *yellowness* index :math:`YI` of the specified sample *CIE XYZ* 

77 tristimulus values using the *ASTM D1925* method. 

78 

79 The *ASTM D1925* method has been specifically developed for defining the 

80 yellowness of homogeneous, non-fluorescent, almost neutral-transparent, 

81 white-scattering or opaque plastics as they will be evaluated under 

82 daylight conditions. The method can be applied to other materials as 

83 well, provided they fit this description. 

84 

85 Parameters 

86 ---------- 

87 XYZ 

88 *CIE XYZ* tristimulus values of the sample. 

89 

90 Returns 

91 ------- 

92 :class:`numpy.ndarray` 

93 *Yellowness* index :math:`YI`. 

94 

95 Notes 

96 ----- 

97 +------------+-----------------------+---------------+ 

98 | **Domain** | **Scale - Reference** | **Scale - 1** | 

99 +============+=======================+===============+ 

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

101 +------------+-----------------------+---------------+ 

102 

103 +------------+-----------------------+---------------+ 

104 | **Range** | **Scale - Reference** | **Scale - 1** | 

105 +============+=======================+===============+ 

106 | ``YI`` | 100 | 1 | 

107 +------------+-----------------------+---------------+ 

108 

109 - Input *CIE XYZ* tristimulus values must be adapted to 

110 *CIE Illuminant C*. 

111 

112 References 

113 ---------- 

114 :cite:`ASTMInternational2015`, :cite:`X-Rite2012a` 

115 

116 Examples 

117 -------- 

118 >>> XYZ = np.array([95.00000000, 100.00000000, 105.00000000]) 

119 >>> yellowness_ASTMD1925(XYZ) # doctest: +ELLIPSIS 

120 10.2999999... 

121 """ 

122 

123 X, Y, Z = tsplit(to_domain_100(XYZ)) 

124 

125 with sdiv_mode(): 

126 YI = sdiv(100 * (1.28 * X - 1.06 * Z), Y) 

127 

128 return as_float(from_range_100(YI)) 

129 

130 

131def yellowness_ASTME313_alternative( 

132 XYZ: Domain100, 

133) -> Range100: 

134 """ 

135 Compute the *yellowness* index :math:`YI` of the specified sample *CIE XYZ* 

136 tristimulus values using the alternative *ASTM E313* method. 

137 

138 In the original form of *Test Method E313*, an alternative equation was 

139 recommended for a *yellowness* index. In terms of colorimeter readings, 

140 it was :math:`YI = 100(1 - B/G)` where :math:`B` and :math:`G` are, 

141 respectively, blue and green colorimeter readings. Its derivation 

142 assumed that, because of the limitation of the concept to yellow (or 

143 blue) colors, it was not necessary to take account of variations in the 

144 amber or red colorimeter reading :math:`A`. This equation is no longer 

145 recommended. 

146 

147 Parameters 

148 ---------- 

149 XYZ 

150 *CIE XYZ* tristimulus values of the sample. 

151 

152 Returns 

153 ------- 

154 :class:`numpy.ndarray` 

155 *Yellowness* index :math:`YI`. 

156 

157 Notes 

158 ----- 

159 +------------+-----------------------+---------------+ 

160 | **Domain** | **Scale - Reference** | **Scale - 1** | 

161 +============+=======================+===============+ 

162 | ``XYZ`` | 100 | 1 | 

163 +------------+-----------------------+---------------+ 

164 

165 +------------+-----------------------+---------------+ 

166 | **Range** | **Scale - Reference** | **Scale - 1** | 

167 +============+=======================+===============+ 

168 | ``YI`` | 100 | 1 | 

169 +------------+-----------------------+---------------+ 

170 

171 - Input *CIE XYZ* tristimulus values must be adapted to 

172 *CIE Illuminant C*. 

173 

174 References 

175 ---------- 

176 :cite:`ASTMInternational2015`, :cite:`X-Rite2012a` 

177 

178 Examples 

179 -------- 

180 >>> XYZ = np.array([95.00000000, 100.00000000, 105.00000000]) 

181 >>> yellowness_ASTME313_alternative(XYZ) # doctest: +ELLIPSIS 

182 11.0650000... 

183 """ 

184 

185 _X, Y, Z = tsplit(to_domain_100(XYZ)) 

186 

187 with sdiv_mode(): 

188 YI = 100 * (1 - sdiv(0.847 * Z, Y)) 

189 

190 return as_float(from_range_100(YI)) 

191 

192 

193YELLOWNESS_COEFFICIENTS_ASTME313: CanonicalMapping = CanonicalMapping( 

194 { 

195 "CIE 1931 2 Degree Standard Observer": CanonicalMapping( 

196 { 

197 "C": np.array([1.2769, 1.0592]), 

198 "D65": np.array([1.2985, 1.1335]), 

199 } 

200 ), 

201 "CIE 1964 10 Degree Standard Observer": CanonicalMapping( 

202 { 

203 "C": np.array([1.2871, 1.0781]), 

204 "D65": np.array([1.3013, 1.1498]), 

205 } 

206 ), 

207 } 

208) 

209YELLOWNESS_COEFFICIENTS_ASTME313.__doc__ = """ 

210Coefficients :math:`C_X` and :math:`C_Z` for the *ASTM E313* 

211*yellowness* index :math:`YI` computation method. 

212 

213References 

214---------- 

215:cite:`ASTMInternational2015` 

216 

217Aliases: 

218 

219- 'cie_2_1931': 'CIE 1931 2 Degree Standard Observer' 

220- 'cie_10_1964': 'CIE 1964 10 Degree Standard Observer' 

221""" 

222YELLOWNESS_COEFFICIENTS_ASTME313["cie_2_1931"] = YELLOWNESS_COEFFICIENTS_ASTME313[ 

223 "CIE 1931 2 Degree Standard Observer" 

224] 

225YELLOWNESS_COEFFICIENTS_ASTME313["cie_10_1964"] = YELLOWNESS_COEFFICIENTS_ASTME313[ 

226 "CIE 1964 10 Degree Standard Observer" 

227] 

228 

229 

230def yellowness_ASTME313( 

231 XYZ: Domain100, 

232 C_XZ: ArrayLike = YELLOWNESS_COEFFICIENTS_ASTME313[ 

233 "CIE 1931 2 Degree Standard Observer" 

234 ]["D65"], 

235) -> Range100: 

236 """ 

237 Compute the *yellowness* index :math:`YI` of the specified sample *CIE XYZ* 

238 tristimulus values using the *ASTM E313* method. 

239 

240 *ASTM E313* has been successfully used for a variety of white or near white 

241 materials. This includes coatings, plastics, and textiles. 

242 

243 Parameters 

244 ---------- 

245 XYZ 

246 *CIE XYZ* tristimulus values of the sample. 

247 C_XZ 

248 Coefficients :math:`C_X` and :math:`C_Z` for the 

249 *CIE 1931 2 Degree Standard Observer* and 

250 *CIE 1964 10 Degree Standard Observer* with *CIE Illuminant C* and 

251 *CIE Standard Illuminant D65*. 

252 

253 Returns 

254 ------- 

255 :class:`numpy.ndarray` 

256 *Yellowness* index :math:`YI`. 

257 

258 Notes 

259 ----- 

260 +------------+-----------------------+---------------+ 

261 | **Domain** | **Scale - Reference** | **Scale - 1** | 

262 +============+=======================+===============+ 

263 | ``XYZ`` | 100 | 1 | 

264 +------------+-----------------------+---------------+ 

265 

266 +------------+-----------------------+---------------+ 

267 | **Range** | **Scale - Reference** | **Scale - 1** | 

268 +============+=======================+===============+ 

269 | ``YI`` | 100 | 1 | 

270 +------------+-----------------------+---------------+ 

271 

272 References 

273 ---------- 

274 :cite:`ASTMInternational2015` 

275 

276 Examples 

277 -------- 

278 >>> XYZ = np.array([95.00000000, 100.00000000, 105.00000000]) 

279 >>> yellowness_ASTME313(XYZ) # doctest: +ELLIPSIS 

280 4.3400000... 

281 """ 

282 

283 X, Y, Z = tsplit(to_domain_100(XYZ)) 

284 C_X, C_Z = tsplit(C_XZ) 

285 

286 with sdiv_mode(): 

287 YI = 100 * sdiv(C_X * X - C_Z * Z, Y) 

288 

289 return as_float(from_range_100(YI)) 

290 

291 

292YELLOWNESS_METHODS = CanonicalMapping( 

293 { 

294 "ASTM D1925": yellowness_ASTMD1925, 

295 "ASTM E313 Alternative": yellowness_ASTME313_alternative, 

296 "ASTM E313": yellowness_ASTME313, 

297 } 

298) 

299YELLOWNESS_METHODS.__doc__ = """ 

300Supported *yellowness* computation methods. 

301 

302References 

303---------- 

304:cite:`ASTMInternational2015`, :cite:`X-Rite2012a` 

305""" 

306 

307 

308def yellowness( 

309 XYZ: Domain100, 

310 method: ( 

311 Literal["ASTM D1925", "ASTM E313", "ASTM E313 Alternative"] | str 

312 ) = "ASTM E313", 

313 **kwargs: Any, 

314) -> Range100: 

315 """ 

316 Compute the *yellowness* index :math:`YI` using the specified method. 

317 

318 Parameters 

319 ---------- 

320 XYZ 

321 *CIE XYZ* tristimulus values of the sample. 

322 method 

323 Computation method. 

324 

325 Other Parameters 

326 ---------------- 

327 C_XZ 

328 {:func:`colour.colorimetry.yellowness_ASTME313`}, 

329 Coefficients :math:`C_X` and :math:`C_Z` for the 

330 *CIE 1931 2 Degree Standard Observer* and 

331 *CIE 1964 10 Degree Standard Observer* with *CIE Illuminant C* and 

332 *CIE Standard Illuminant D65*. 

333 

334 Returns 

335 ------- 

336 :class:`numpy.ndarray` 

337 *Yellowness* index :math:`YI`. 

338 

339 Notes 

340 ----- 

341 +------------+-----------------------+---------------+ 

342 | **Domain** | **Scale - Reference** | **Scale - 1** | 

343 +============+=======================+===============+ 

344 | ``XYZ`` | 100 | 1 | 

345 +------------+-----------------------+---------------+ 

346 

347 +------------+-----------------------+---------------+ 

348 | **Range** | **Scale - Reference** | **Scale - 1** | 

349 +============+=======================+===============+ 

350 | ``YI`` | 100 | 1 | 

351 +------------+-----------------------+---------------+ 

352 

353 References 

354 ---------- 

355 :cite:`ASTMInternational2015`, :cite:`X-Rite2012a` 

356 

357 Examples 

358 -------- 

359 >>> XYZ = np.array([95.00000000, 100.00000000, 105.00000000]) 

360 >>> yellowness(XYZ) # doctest: +ELLIPSIS 

361 4.3400000... 

362 >>> yellowness(XYZ, method="ASTM E313 Alternative") # doctest: +ELLIPSIS 

363 11.0650000... 

364 >>> yellowness(XYZ, method="ASTM D1925") # doctest: +ELLIPSIS 

365 10.2999999... 

366 """ 

367 

368 method = validate_method(method, tuple(YELLOWNESS_METHODS)) 

369 

370 function = YELLOWNESS_METHODS[method] 

371 

372 return function(XYZ, **filter_kwargs(function, **kwargs))