Coverage for corresponding/prediction.py: 64%

1"""

2 Corresponding Chromaticities Prediction

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

4

5 Define objects for computing corresponding chromaticities prediction under

6 different chromatic adaptation conditions.

7

8 References

9----------

10- :cite:`Breneman1987b` : Breneman, E. J. (1987). Corresponding

11 chromaticities for different states of adaptation to complex visual fields.

12 Journal of the Optical Society of America A, 4(6), 1115.

13 doi:10.1364/JOSAA.4.001115

14- :cite:`CIETC1-321994b` : CIE TC 1-32. (1994). CIE 109-1994 A Method of

15 Predicting Corresponding Colours under Different Chromatic and Illuminance

16 Adaptations. Commission Internationale de l'Eclairage.

17 ISBN:978-3-900734-51-0

18- :cite:`Fairchild1991a` : Fairchild, M. D. (1991). Formulation and testing

19 of an incomplete-chromatic-adaptation model. Color Research & Application,

20 16(4), 243-250. doi:10.1002/col.5080160406

21- :cite:`Fairchild2013s` : Fairchild, M. D. (2013). FAIRCHILD'S 1990 MODEL.

22 In Color Appearance Models (3rd ed., pp. 4418-4495). Wiley. ISBN:B00DAYO8E2

23- :cite:`Fairchild2013t` : Fairchild, M. D. (2013). Chromatic Adaptation

24 Models. In Color Appearance Models (3rd ed., pp. 4179-4252). Wiley.

25 ISBN:B00DAYO8E2

26- :cite:`Li2002a` : Li, C., Luo, M. R., Rigg, B., & Hunt, R. W. G. (2002).

27 CMC 2000 chromatic adaptation transform: CMCCAT2000. Color Research &

28 Application, 27(1), 49-58. doi:10.1002/col.10005

29- :cite:`Luo1999` : Luo, M. Ronnier, & Rhodes, P. A. (1999).

30 Corresponding-colour datasets. Color Research & Application, 24(4),

31 295-296. doi:10.1002/(SICI)1520-6378(199908)24:4<295::AID-COL10>3.0.CO;2-K

32- :cite:`Westland2012k` : Westland, S., Ripamonti, C., & Cheung, V. (2012).

33 CMCCAT2000. In Computational Colour Science Using MATLAB (2nd ed., pp.

34 83-86). ISBN:978-0-470-66569-5

35- :cite:`Zhai2018` : Zhai, Q., & Luo, M. R. (2018). Study of chromatic

36 adaptation via neutral white matches on different viewing media. Optics

37 Express, 26(6), 7724. doi:10.1364/OE.26.007724

38"""

39

40 from __future__ import annotations

41

42 import typing

43 from dataclasses import dataclass

44

45 import numpy as np

46

47 from colour.adaptation import (

48 chromatic_adaptation_CIE1994,

49 chromatic_adaptation_CMCCAT2000,

50 chromatic_adaptation_Fairchild1990,

51 chromatic_adaptation_VonKries,

52 chromatic_adaptation_Zhai2018,

53)

54 from colour.corresponding import (

55 BRENEMAN_EXPERIMENT_PRIMARIES_CHROMATICITIES,

56 BRENEMAN_EXPERIMENTS,

57)

58

59 if typing.TYPE_CHECKING:

60 from colour.hints import (

61 Any,

62 ArrayLike,

63 Literal,

64 LiteralChromaticAdaptationTransform,

65 NDArrayFloat,

66 Tuple,

67 )

68

69 from colour.models import (

70 Luv_to_uv,

71 Luv_uv_to_xy,

72 XYZ_to_Luv,

73 XYZ_to_xy,

74 xy_to_XYZ,

75 xyY_to_XYZ,

76)

77 from colour.utilities import (

78 CanonicalMapping,

79 MixinDataclassIterable,

80 as_float_array,

81 as_float_scalar,

82 attest,

83 domain_range_scale,

84 filter_kwargs,

85 full,

86)

87

88 __author__ = "Colour Developers"

89 __copyright__ = "Copyright 2013 Colour Developers"

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

91 __maintainer__ = "Colour Developers"

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

93 __status__ = "Production"

94

95 __all__ = [

96 "CorrespondingColourDataset",

97 "CorrespondingChromaticitiesPrediction",

98 "convert_experiment_results_Breneman1987",

99 "corresponding_chromaticities_prediction_Fairchild1990",

100 "corresponding_chromaticities_prediction_CIE1994",

101 "corresponding_chromaticities_prediction_CMCCAT2000",

102 "corresponding_chromaticities_prediction_VonKries",

103 "corresponding_chromaticities_prediction_Zhai2018",

104 "CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS",

105 "corresponding_chromaticities_prediction",

106]

107

108

109@dataclass(frozen=True)

110 class CorrespondingColourDataset(MixinDataclassIterable):

111 """

112 Define a corresponding colour dataset for chromatic adaptation studies.

113

114 Parameters

115 ----------

116 name

117 Corresponding colour dataset name.

118 XYZ_r

119 *CIE XYZ* tristimulus values of the reference illuminant.

120 XYZ_t

121 *CIE XYZ* tristimulus values of the test illuminant.

122 XYZ_cr

123 Corresponding *CIE XYZ* tristimulus values under the reference

124 illuminant.

125 XYZ_ct

126 Corresponding *CIE XYZ* tristimulus values under the test illuminant.

127 Y_r

128 Reference white luminance :math:`Y_r` in :math:`cd/m^2`.

129 Y_t

130 Test white luminance :math:`Y_t` in :math:`cd/m^2`.

131 B_r

132 Luminance factor :math:`B_r` of reference achromatic background as

133 percentage.

134 B_t

135 Luminance factor :math:`B_t` of test achromatic background as

136 percentage.

137 metadata

138 Dataset metadata.

139

140 Notes

141 -----

142 - This class is compatible with *Luo and Rhodes (1999)*

143 *Corresponding-Colour Datasets* datasets.

144

145 References

146 ----------

147 :cite:`Luo1999`

148 """

149

150 name: int

151 XYZ_r: NDArrayFloat

152 XYZ_t: NDArrayFloat

153 XYZ_cr: NDArrayFloat

154 XYZ_ct: NDArrayFloat

155 Y_r: float

156 Y_t: float

157 B_r: float

158 B_t: float

159 metadata: dict

160

161 def __post_init__(self) -> None:

162 """Post-initialise the class."""

163

164 object.__setattr__(self, "XYZ_r", as_float_array(self.XYZ_r))

165 object.__setattr__(self, "XYZ_t", as_float_array(self.XYZ_t))

166 object.__setattr__(self, "XYZ_cr", as_float_array(self.XYZ_cr))

167 object.__setattr__(self, "XYZ_ct", as_float_array(self.XYZ_ct))

168

169

170@dataclass(frozen=True)

171 class CorrespondingChromaticitiesPrediction(MixinDataclassIterable):

172 """

173 Define a chromatic adaptation model prediction for corresponding

174 chromaticities.

175

176 Parameters

177 ----------

178 name

179 Test colour name used to identify the prediction instance.

180 uv_t

181 Chromaticity coordinates :math:`uv_t^p` of the test colour under

182 the test illuminant.

183 uv_m

184 Chromaticity coordinates :math:`uv_m^p` of the matching colour

185 under the reference illuminant.

186 uv_p

187 Chromaticity coordinates :math:`uv_p^p` of the predicted colour

188 as computed by the chromatic adaptation model.

189 """

190

191 name: int

192 uv_t: NDArrayFloat

193 uv_m: NDArrayFloat

194 uv_p: NDArrayFloat

195

196 def __post_init__(self) -> None:

197 """Post-initialise the class."""

198

199 object.__setattr__(self, "uv_t", as_float_array(self.uv_t))

200 object.__setattr__(self, "uv_m", as_float_array(self.uv_m))

201 object.__setattr__(self, "uv_p", as_float_array(self.uv_p))

202

203

204 def convert_experiment_results_Breneman1987(

205 experiment: Literal[1, 2, 3, 4, 6, 8, 9, 11, 12],

206) -> CorrespondingColourDataset:

207 """

208 Convert *Breneman (1987)* experiment results to a

209 :class:`colour.CorrespondingColourDataset` class instance.

210

211 Parameters

212 ----------

213 experiment

214 *Breneman (1987)* experiment number.

215

216 Returns

217 -------

218 :class:`colour.CorrespondingColourDataset`

219 :class:`colour.CorrespondingColourDataset` class instance.

220

221 Examples

222 --------

223 >>> from pprint import pprint

224 >>> pprint(tuple(convert_experiment_results_Breneman1987(2).values))

225 ... # doctest: +ELLIPSIS

226 (2,

227 array([ 0.9582463..., 1. , 0.9436325...]),

228 array([ 0.9587332..., 1. , 0.4385796...]),

229 array([[ 388.125 , 405. , 345.625 ],

230 [ 266.8957925..., 135. , 28.5983365...],

231 [ 474.5717821..., 405. , 222.75 ...],

232 [ 538.3899082..., 405. , 24.8944954...],

233 [ 178.7430167..., 135. , 19.6089385...],

234 [ 436.6749547..., 405. , 26.5483725...],

235 [ 124.7746282..., 135. , 36.1965613...],

236 [ 77.0794172..., 135. , 60.5850563...],

237 [ 279.9390889..., 405. , 455.8395127...],

238 [ 149.5808157..., 135. , 498.7046827...],

239 [ 372.1113689..., 405. , 669.9883990...],

240 [ 212.3638968..., 135. , 414.6704871...]]),

241 array([[ 400.1039651..., 405. , 191.7287234...],

242 [ 271.0384615..., 135. , 13.5 ...],

243 [ 495.4705323..., 405. , 119.7290874...],

244 [ 580.7967033..., 405. , 6.6758241...],

245 [ 190.1933701..., 135. , 7.4585635...],

246 [ 473.7184115..., 405. , 10.2346570...],

247 [ 135.4936014..., 135. , 20.2376599...],

248 [ 86.4689781..., 135. , 35.2281021...],

249 [ 283.5396281..., 405. , 258.1775929...],

250 [ 119.7044335..., 135. , 282.6354679...],

251 [ 359.9532224..., 405. , 381.0031185...],

252 [ 181.8271461..., 135. , 204.0661252...]]),

253 1500.0,

254 1500.0,

255 0.3,

256 0.3,

257 {})

258 """

259

260 valid_experiment_results = [1, 2, 3, 4, 6, 8, 9, 11, 12]

261 attest(

262 experiment in valid_experiment_results,

263 f'"Breneman (1987)" experiment result is invalid, it must be one of '

264 f'"{valid_experiment_results}"!',

265 )

266

267 samples_luminance = [

268 0.270,

269 0.090,

270 0.270,

271 0.270,

272 0.090,

273 0.270,

274 0.090,

275 0.090,

276 0.270,

277 0.090,

278 0.270,

279 0.090,

280 ]

281

282 experiment_results = list(BRENEMAN_EXPERIMENTS[experiment])

283 illuminant_chromaticities = experiment_results.pop(0)

284 Y_r = Y_t = as_float_scalar(

285 BRENEMAN_EXPERIMENT_PRIMARIES_CHROMATICITIES[experiment].Y

286 )

287 B_r = B_t = 0.3

288

289 XYZ_t, XYZ_r = (

290 xy_to_XYZ(

291 np.hstack(

292 [

293 Luv_uv_to_xy(illuminant_chromaticities.values[1:3]),

294 full((2, 1), Y_r),

295 ]

296 )

297 )

298 / Y_r

299 )

300

301 xyY_cr, xyY_ct = [], []

302 for i, experiment_result in enumerate(experiment_results):

303 xyY_cr.append(

304 np.hstack(

305 [

306 Luv_uv_to_xy(experiment_result.values[2]),

307 samples_luminance[i] * Y_r,

308 ]

309 )

310 )

311 xyY_ct.append(

312 np.hstack(

313 [

314 Luv_uv_to_xy(experiment_result.values[1]),

315 samples_luminance[i] * Y_t,

316 ]

317 )

318 )

319

320 XYZ_cr = xyY_to_XYZ(xyY_cr)

321 XYZ_ct = xyY_to_XYZ(xyY_ct)

322

323 return CorrespondingColourDataset(

324 experiment, XYZ_r, XYZ_t, XYZ_cr, XYZ_ct, Y_r, Y_t, B_r, B_t, {}

325 )

326

327

328 def corresponding_chromaticities_prediction_Fairchild1990(

329 experiment: (Literal[1, 2, 3, 4, 6, 8, 9, 11, 12] | CorrespondingColourDataset) = 1,

330) -> Tuple[CorrespondingChromaticitiesPrediction, ...]:

331 """

332 Predict corresponding chromaticities using the *Fairchild (1990)*

333 chromatic adaptation model.

334

335 Parameters

336 ----------

337 experiment

338 *Breneman (1987)* experiment number or

339 :class:`colour.CorrespondingColourDataset` class instance.

340

341 Returns

342 -------

343 :class:`tuple`

344 Corresponding chromaticities prediction.

345

346 References

347 ----------

348 :cite:`Breneman1987b`, :cite:`Fairchild1991a`, :cite:`Fairchild2013s`

349

350 Examples

351 --------

352 >>> from pprint import pprint

353 >>> pr = corresponding_chromaticities_prediction_Fairchild1990(2)

354 >>> pr = [(p.uv_m, p.uv_p) for p in pr]

355 >>> pprint(pr) # doctest: +ELLIPSIS

356 [(array([ 0.207, 0.486]), array([ 0.2089528..., 0.4724034...])),

357 (array([ 0.449, 0.511]), array([ 0.4375652..., 0.5121030...])),

358 (array([ 0.263, 0.505]), array([ 0.2621362..., 0.4972538...])),

359 (array([ 0.322, 0.545]), array([ 0.3235312..., 0.5475665...])),

360 (array([ 0.316, 0.537]), array([ 0.3151391..., 0.5398333...])),

361 (array([ 0.265, 0.553]), array([ 0.2634745..., 0.5544335...])),

362 (array([ 0.221, 0.538]), array([ 0.2211595..., 0.5324470...])),

363 (array([ 0.135, 0.532]), array([ 0.1396949..., 0.5207234...])),

364 (array([ 0.145, 0.472]), array([ 0.1512288..., 0.4533041...])),

365 (array([ 0.163, 0.331]), array([ 0.1715691..., 0.3026264...])),

366 (array([ 0.176, 0.431]), array([ 0.1825792..., 0.4077892...])),

367 (array([ 0.244, 0.349]), array([ 0.2418905..., 0.3413401...]))]

368 """

369

370 experiment_results = (

371 experiment

372 if isinstance(experiment, CorrespondingColourDataset)

373 else convert_experiment_results_Breneman1987(experiment)

374 )

375

376 with domain_range_scale("1"):

377 XYZ_t, XYZ_r = experiment_results.XYZ_t, experiment_results.XYZ_r

378 xy_t, xy_r = XYZ_to_xy([XYZ_t, XYZ_r])

379

380 uv_t = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_ct, xy_t), xy_t)

381 uv_m = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_cr, xy_r), xy_r)

382

383 Y_n = experiment_results.Y_t

384

385 XYZ_1 = experiment_results.XYZ_ct

386 XYZ_2 = chromatic_adaptation_Fairchild1990(XYZ_1, XYZ_t, XYZ_r, Y_n)

387 uv_p = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_r), xy_r)

388

389 return tuple(

390 CorrespondingChromaticitiesPrediction(

391 experiment_results.name, uv_t[i], uv_m[i], uv_p[i]

392 )

393 for i in range(len(uv_t))

394 )

395

396

397 def corresponding_chromaticities_prediction_CIE1994(

398 experiment: (Literal[1, 2, 3, 4, 6, 8, 9, 11, 12] | CorrespondingColourDataset) = 1,

399) -> Tuple[CorrespondingChromaticitiesPrediction, ...]:

400 """

401 Predict corresponding chromaticities using the *CIE 1994*

402 chromatic adaptation model.

403

404 Parameters

405 ----------

406 experiment

407 *Breneman (1987)* experiment number or

408 :class:`colour.CorrespondingColourDataset` class instance.

409

410 Returns

411 -------

412 :class:`tuple`

413 Corresponding chromaticities prediction.

414

415 References

416 ----------

417 :cite:`Breneman1987b`, :cite:`CIETC1-321994b`

418

419 Examples

420 --------

421 >>> from pprint import pprint

422 >>> pr = corresponding_chromaticities_prediction_CIE1994(2)

423 >>> pr = [(p.uv_m, p.uv_p) for p in pr]

424 >>> pprint(pr) # doctest: +ELLIPSIS

425 [(array([ 0.207, 0.486]), array([ 0.2273130..., 0.5267609...])),

426 (array([ 0.449, 0.511]), array([ 0.4612181..., 0.5191849...])),

427 (array([ 0.263, 0.505]), array([ 0.2872404..., 0.5306938...])),

428 (array([ 0.322, 0.545]), array([ 0.3489822..., 0.5454398...])),

429 (array([ 0.316, 0.537]), array([ 0.3371612..., 0.5421567...])),

430 (array([ 0.265, 0.553]), array([ 0.2889416..., 0.5534074...])),

431 (array([ 0.221, 0.538]), array([ 0.2412195..., 0.5464301...])),

432 (array([ 0.135, 0.532]), array([ 0.1530344..., 0.5488239...])),

433 (array([ 0.145, 0.472]), array([ 0.1568709..., 0.5258835...])),

434 (array([ 0.163, 0.331]), array([ 0.1499762..., 0.4401747...])),

435 (array([ 0.176, 0.431]), array([ 0.1876711..., 0.5039627...])),

436 (array([ 0.244, 0.349]), array([ 0.2560012..., 0.4546263...]))]

437 """

438

439 experiment_results = (

440 experiment

441 if isinstance(experiment, CorrespondingColourDataset)

442 else convert_experiment_results_Breneman1987(experiment)

443 )

444

445 with domain_range_scale("1"):

446 XYZ_t, XYZ_r = experiment_results.XYZ_t, experiment_results.XYZ_r

447 xy_o1, xy_o2 = XYZ_to_xy([XYZ_t, XYZ_r])

448

449 uv_t = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_ct, xy_o1), xy_o1)

450 uv_m = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_cr, xy_o2), xy_o2)

451

452 Y_r = experiment_results.B_r

453 E_o1, E_o2 = experiment_results.Y_t, experiment_results.Y_r

454

455 XYZ_1 = experiment_results.XYZ_ct

456 XYZ_2 = chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_r, E_o1, E_o2)

457 uv_p = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_o2), xy_o2)

458

459 return tuple(

460 CorrespondingChromaticitiesPrediction(

461 experiment_results.name, uv_t[i], uv_m[i], uv_p[i]

462 )

463 for i in range(len(uv_t))

464 )

465

466

467 def corresponding_chromaticities_prediction_CMCCAT2000(

468 experiment: (Literal[1, 2, 3, 4, 6, 8, 9, 11, 12] | CorrespondingColourDataset) = 1,

469) -> Tuple[CorrespondingChromaticitiesPrediction, ...]:

470 """

471 Predict corresponding chromaticities using the *CMCCAT2000*

472 chromatic adaptation model.

473

474 Parameters

475 ----------

476 experiment

477 *Breneman (1987)* experiment number or

478 :class:`colour.CorrespondingColourDataset` class instance.

479

480 Returns

481 -------

482 :class:`tuple`

483 Corresponding chromaticities prediction.

484

485 References

486 ----------

487 :cite:`Breneman1987b`, :cite:`Li2002a`, :cite:`Westland2012k`

488

489 Examples

490 --------

491 >>> from pprint import pprint

492 >>> pr = corresponding_chromaticities_prediction_CMCCAT2000(2)

493 >>> pr = [(p.uv_m, p.uv_p) for p in pr]

494 >>> pprint(pr) # doctest: +ELLIPSIS

495 [(array([ 0.207, 0.486]), array([ 0.2083210..., 0.4727168...])),

496 (array([ 0.449, 0.511]), array([ 0.4459270..., 0.5077735...])),

497 (array([ 0.263, 0.505]), array([ 0.2640262..., 0.4955361...])),

498 (array([ 0.322, 0.545]), array([ 0.3316884..., 0.5431580...])),

499 (array([ 0.316, 0.537]), array([ 0.3222624..., 0.5357624...])),

500 (array([ 0.265, 0.553]), array([ 0.2710705..., 0.5501997...])),

501 (array([ 0.221, 0.538]), array([ 0.2261826..., 0.5294740...])),

502 (array([ 0.135, 0.532]), array([ 0.1439693..., 0.5190984...])),

503 (array([ 0.145, 0.472]), array([ 0.1494835..., 0.4556760...])),

504 (array([ 0.163, 0.331]), array([ 0.1563172..., 0.3164151...])),

505 (array([ 0.176, 0.431]), array([ 0.1763199..., 0.4127589...])),

506 (array([ 0.244, 0.349]), array([ 0.2287638..., 0.3499324...]))]

507 """

508

509 experiment_results = (

510 experiment

511 if isinstance(experiment, CorrespondingColourDataset)

512 else convert_experiment_results_Breneman1987(experiment)

513 )

514

515 with domain_range_scale("1"):

516 XYZ_w, XYZ_wr = experiment_results.XYZ_t, experiment_results.XYZ_r

517 xy_w, xy_wr = XYZ_to_xy([XYZ_w, XYZ_wr])

518

519 uv_t = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_ct, xy_w), xy_w)

520 uv_m = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_cr, xy_wr), xy_wr)

521

522 L_A1 = experiment_results.Y_t

523 L_A2 = experiment_results.Y_r

524

525 XYZ_1 = experiment_results.XYZ_ct

526 XYZ_2 = chromatic_adaptation_CMCCAT2000(XYZ_1, XYZ_w, XYZ_wr, L_A1, L_A2)

527 uv_p = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_wr), xy_wr)

528

529 return tuple(

530 CorrespondingChromaticitiesPrediction(

531 experiment_results.name, uv_t[i], uv_m[i], uv_p[i]

532 )

533 for i in range(len(uv_t))

534 )

535

536

537 def corresponding_chromaticities_prediction_VonKries(

538 experiment: (Literal[1, 2, 3, 4, 6, 8, 9, 11, 12] | CorrespondingColourDataset) = 1,

539 transform: LiteralChromaticAdaptationTransform | str = "CAT02",

540) -> Tuple[CorrespondingChromaticitiesPrediction, ...]:

541 """

542 Predict corresponding chromaticities using the *Von Kries*

543 chromatic adaptation model.

544

545 Parameters

546 ----------

547 experiment

548 *Breneman (1987)* experiment number or

549 :class:`colour.CorrespondingColourDataset` class instance.

550 transform

551 Chromatic adaptation transform.

552

553 Returns

554 -------

555 :class:`tuple`

556 Corresponding chromaticities prediction.

557

558 References

559 ----------

560 :cite:`Breneman1987b`, :cite:`Fairchild2013t`

561

562 Examples

563 --------

564 >>> from pprint import pprint

565 >>> pr = corresponding_chromaticities_prediction_VonKries(2, "Bradford")

566 >>> pr = [(p.uv_m, p.uv_p) for p in pr]

567 >>> pprint(pr) # doctest: +ELLIPSIS

568 [(array([ 0.207, 0.486]), array([ 0.2082014..., 0.4722922...])),

569 (array([ 0.449, 0.511]), array([ 0.4489102..., 0.5071602...])),

570 (array([ 0.263, 0.505]), array([ 0.2643545..., 0.4959631...])),

571 (array([ 0.322, 0.545]), array([ 0.3348730..., 0.5471220...])),

572 (array([ 0.316, 0.537]), array([ 0.3248758..., 0.5390589...])),

573 (array([ 0.265, 0.553]), array([ 0.2733105..., 0.5555028...])),

574 (array([ 0.221, 0.538]), array([ 0.227148 ..., 0.5331318...])),

575 (array([ 0.135, 0.532]), array([ 0.1442730..., 0.5226804...])),

576 (array([ 0.145, 0.472]), array([ 0.1498745..., 0.4550785...])),

577 (array([ 0.163, 0.331]), array([ 0.1564975..., 0.3148796...])),

578 (array([ 0.176, 0.431]), array([ 0.1760593..., 0.4103772...])),

579 (array([ 0.244, 0.349]), array([ 0.2259805..., 0.3465291...]))]

580 """

581

582 experiment_results = (

583 experiment

584 if isinstance(experiment, CorrespondingColourDataset)

585 else convert_experiment_results_Breneman1987(experiment)

586 )

587

588 with domain_range_scale("1"):

589 XYZ_w, XYZ_wr = experiment_results.XYZ_t, experiment_results.XYZ_r

590 xy_w, xy_wr = XYZ_to_xy([XYZ_w, XYZ_wr])

591

592 uv_t = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_ct, xy_w), xy_w)

593 uv_m = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_cr, xy_wr), xy_wr)

594

595 XYZ_1 = experiment_results.XYZ_ct

596 XYZ_2 = chromatic_adaptation_VonKries(XYZ_1, XYZ_w, XYZ_wr, transform)

597 uv_p = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_wr), xy_wr)

598

599 return tuple(

600 CorrespondingChromaticitiesPrediction(

601 experiment_results.name, uv_t[i], uv_m[i], uv_p[i]

602 )

603 for i in range(len(uv_t))

604 )

605

606

607 def corresponding_chromaticities_prediction_Zhai2018(

608 experiment: (Literal[1, 2, 3, 4, 6, 8, 9, 11, 12] | CorrespondingColourDataset) = 1,

609 D_b: ArrayLike = 1,

610 D_d: ArrayLike = 1,

611 XYZ_wo: ArrayLike = (1, 1, 1),

612 transform: Literal["CAT02", "CAT16"] | str = "CAT02",

613) -> Tuple[CorrespondingChromaticitiesPrediction, ...]:

614 """

615 Predict corresponding chromaticities using the *Zhai and Luo (2018)*

616 chromatic adaptation model.

617

618 Parameters

619 ----------

620 experiment

621 *Breneman (1987)* experiment number or

622 :class:`colour.CorrespondingColourDataset` class instance.

623 D_b

624 Degree of adaptation :math:`D_{\\beta}` of input illuminant

625 :math:`\\beta`.

626 D_d

627 Degree of adaptation :math:`D_{\\delta}` of output illuminant

628 :math:`\\delta`.

629 XYZ_wo

630 Baseline illuminant (:math:`BI`) :math:`o`.

631 transform

632 Chromatic adaptation transform.

633

634 Returns

635 -------

636 :class:`tuple`

637 Corresponding chromaticities prediction.

638

639 References

640 ----------

641 :cite:`Breneman1987b`, :cite:`Zhai2018`

642

643 Examples

644 --------

645 >>> from pprint import pprint

646 >>> pr = corresponding_chromaticities_prediction_Zhai2018(2)

647 >>> pr = [(p.uv_m, p.uv_p) for p in pr]

648 >>> pprint(pr) # doctest: +ELLIPSIS

649 [(array([ 0.207, 0.486]), array([ 0.2082238..., 0.4727943...])),

650 (array([ 0.449, 0.511]), array([ 0.4474691..., 0.5076681...])),

651 (array([ 0.263, 0.505]), array([ 0.2640379..., 0.4954003...])),

652 (array([ 0.322, 0.545]), array([ 0.3336937..., 0.5435500...])),

653 (array([ 0.316, 0.537]), array([ 0.3238490..., 0.5359889...])),

654 (array([ 0.265, 0.553]), array([ 0.2724846..., 0.5506939...])),

655 (array([ 0.221, 0.538]), array([ 0.2267596..., 0.5295259...])),

656 (array([ 0.135, 0.532]), array([ 0.1443208..., 0.5190035...])),

657 (array([ 0.145, 0.472]), array([ 0.1500723..., 0.4561352...])),

658 (array([ 0.163, 0.331]), array([ 0.1570902..., 0.3245137...])),

659 (array([ 0.176, 0.431]), array([ 0.1763887..., 0.4146000...])),

660 (array([ 0.244, 0.349]), array([ 0.2267005..., 0.3551480...]))]

661 """

662

663 experiment_results = (

664 experiment

665 if isinstance(experiment, CorrespondingColourDataset)

666 else convert_experiment_results_Breneman1987(experiment)

667 )

668

669 with domain_range_scale("1"):

670 XYZ_w, XYZ_wr = experiment_results.XYZ_t, experiment_results.XYZ_r

671 xy_w, xy_wr = XYZ_to_xy([XYZ_w, XYZ_wr])

672

673 uv_t = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_ct, xy_w), xy_w)

674 uv_m = Luv_to_uv(XYZ_to_Luv(experiment_results.XYZ_cr, xy_wr), xy_wr)

675

676 XYZ_1 = experiment_results.XYZ_ct

677 XYZ_2 = chromatic_adaptation_Zhai2018(

678 XYZ_1, XYZ_w, XYZ_wr, D_b, D_d, XYZ_wo, transform

679 )

680 uv_p = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_wr), xy_wr)

681

682 return tuple(

683 CorrespondingChromaticitiesPrediction(

684 experiment_results.name, uv_t[i], uv_m[i], uv_p[i]

685 )

686 for i in range(len(uv_t))

687 )

688

689

690 CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS = CanonicalMapping(

691 {

692 "CIE 1994": corresponding_chromaticities_prediction_CIE1994,

693 "CMCCAT2000": corresponding_chromaticities_prediction_CMCCAT2000,

694 "Fairchild 1990": corresponding_chromaticities_prediction_Fairchild1990,

695 "Von Kries": corresponding_chromaticities_prediction_VonKries,

696 "Zhai 2018": corresponding_chromaticities_prediction_Zhai2018,

697 }

698)

699 CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS.__doc__ = """

700 Supported corresponding chromaticities prediction models.

701

702 References

703----------

704:cite:`Breneman1987b`, :cite:`CIETC1-321994b`, :cite:`Fairchild1991a`,

705:cite:`Fairchild2013s`, :cite:`Fairchild2013t`, :cite:`Li2002a`,

706:cite:`Westland2012k`, :cite:`Zhai2018`

707

708 Aliases:

709

710- 'vonkries': 'Von Kries'

711"""

712 CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS["vonkries"] = (

713 CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS["Von Kries"]

714)

715

716

717 def corresponding_chromaticities_prediction(

718 experiment: (Literal[1, 2, 3, 4, 6, 8, 9, 11, 12] | CorrespondingColourDataset) = 1,

719 model: (

720 Literal[

721 "CIE 1994",

722 "CMCCAT2000",

723 "Fairchild 1990",

724 "Von Kries",

725 "Zhai 2018",

726 ]

727 | str

728 ) = "Von Kries",

729 **kwargs: Any,

730) -> Tuple[CorrespondingChromaticitiesPrediction, ...]:

731 """

732 Predict corresponding chromaticities.

733

734 Parameters

735 ----------

736 experiment

737 *Breneman (1987)* experiment number or

738 :class:`colour.CorrespondingColourDataset` class instance.

739 model

740 Chromatic adaptation model.

741

742 Other Parameters

743 ----------------

744 D_b

745 {:func:`colour.corresponding.\

746 corresponding_chromaticities_prediction_Zhai2018`},

747 Degree of adaptation :math:`D_{\\beta}` of input illuminant

748 :math:`\\beta`.

749 D_d

750 {:func:`colour.corresponding.\

751 corresponding_chromaticities_prediction_Zhai2018`},

752 Degree of adaptation :math:`D_{\\delta}` of output illuminant

753 :math:`\\delta`.

754 transform

755 {:func:`colour.corresponding.\

756 corresponding_chromaticities_prediction_VonKries`,

757 :func:`colour.corresponding.\

758 corresponding_chromaticities_prediction_Zhai2018`},

759 Chromatic adaptation transform.

760 XYZ_wo

761 {:func:`colour.corresponding.\

762 corresponding_chromaticities_prediction_Zhai2018`},

763 Baseline illuminant (:math:`BI`) :math:`o`.

764

765 Returns

766 -------

767 :class:`tuple`

768 Corresponding chromaticities prediction.

769

770 References

771 ----------

772 :cite:`Breneman1987b`, :cite:`CIETC1-321994b`, :cite:`Fairchild1991a`,

773 :cite:`Fairchild2013s`, :cite:`Fairchild2013t`, :cite:`Li2002a`,

774 :cite:`Westland2012k`, :cite:`Zhai2018`

775

776 Examples

777 --------

778 >>> from pprint import pprint

779 >>> pr = corresponding_chromaticities_prediction(2, "CMCCAT2000")

780 >>> pr = [(p.uv_m, p.uv_p) for p in pr]

781 >>> pprint(pr) # doctest: +SKIP

782 [((0.207, 0.486), (0.2083210..., 0.4727168...)),

783 ((0.449, 0.511), (0.4459270..., 0.5077735...)),

784 ((0.263, 0.505), (0.2640262..., 0.4955361...)),

785 ((0.322, 0.545), (0.3316884..., 0.5431580...)),

786 ((0.316, 0.537), (0.3222624..., 0.5357624...)),

787 ((0.265, 0.553), (0.2710705..., 0.5501997...)),

788 ((0.221, 0.538), (0.2261826..., 0.5294740...)),

789 ((0.135, 0.532), (0.1439693..., 0.5190984...)),

790 ((0.145, 0.472), (0.1494835..., 0.4556760...)),

791 ((0.163, 0.331), (0.1563172..., 0.3164151...)),

792 ((0.176, 0.431), (0.1763199..., 0.4127589...)),

793 ((0.244, 0.349), (0.2287638..., 0.3499324...))]

794 """

795

796 function = CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS[model]

797

798 return function(experiment, **filter_kwargs(function, **kwargs))