0
# Chromatic Adaptation
1
2
Comprehensive chromatic adaptation functionality for adapting stimuli between different viewing conditions and illuminants using various chromatic adaptation models and transforms.
3
4
## Capabilities
5
6
### Main Chromatic Adaptation Function
7
8
The primary function for chromatic adaptation with multiple method support.
9
10
```python { .api }
11
def chromatic_adaptation(
12
XYZ: ArrayLike,
13
XYZ_w: ArrayLike,
14
XYZ_wr: ArrayLike,
15
method: Literal["CIE 1994", "CMCCAT2000", "Fairchild 1990", "Von Kries", "Zhai 2018", "vK20"] = "Von Kries",
16
**kwargs: Any
17
) -> NDArrayFloat:
18
"""
19
Adapt given stimulus from test viewing conditions to reference viewing conditions.
20
21
Parameters:
22
- XYZ: CIE XYZ tristimulus values of stimulus to adapt
23
- XYZ_w: test viewing condition CIE XYZ tristimulus values of the whitepoint
24
- XYZ_wr: reference viewing condition CIE XYZ tristimulus values of the whitepoint
25
- method: chromatic adaptation method to use
26
- **kwargs: method-specific parameters (see individual methods for details)
27
28
Returns:
29
CIE XYZ_c tristimulus values of the stimulus corresponding colour
30
31
Supported Methods:
32
- "Von Kries": Classical Von Kries chromatic adaptation
33
- "CIE 1994": CIE 1994 chromatic adaptation model
34
- "CMCCAT2000": CMC CAT2000 chromatic adaptation transform
35
- "Fairchild 1990": Fairchild's 1990 incomplete chromatic adaptation model
36
- "Zhai 2018": Zhai and Luo 2018 two-step chromatic adaptation
37
- "vK20": Von Kries 2020 evolution with degree of adaptation
38
39
Domain/Range: [0, 1] for all XYZ parameters in Scale - 1 mode
40
"""
41
```
42
43
### Von Kries Chromatic Adaptation
44
45
Classical Von Kries chromatic adaptation model implementation.
46
47
```python { .api }
48
def matrix_chromatic_adaptation_VonKries(
49
XYZ_w: ArrayLike,
50
XYZ_wr: ArrayLike,
51
transform: LiteralChromaticAdaptationTransform = "CAT02"
52
) -> NDArrayFloat:
53
"""
54
Compute the chromatic adaptation matrix from test viewing conditions to reference viewing conditions.
55
56
Parameters:
57
- XYZ_w: test viewing conditions CIE XYZ tristimulus values of whitepoint
58
- XYZ_wr: reference viewing conditions CIE XYZ tristimulus values of whitepoint
59
- transform: chromatic adaptation transform matrix to use
60
61
Returns:
62
Chromatic adaptation matrix M_cat
63
64
Available transforms: "XYZ Scaling", "Von Kries", "Bradford", "Sharp",
65
"Fairchild", "CMCCAT97", "CMCCAT2000", "CAT02", "CAT02 Brill 2008",
66
"CAT16", "Bianco 2010", "Bianco PC 2010"
67
"""
68
69
def chromatic_adaptation_VonKries(
70
XYZ: ArrayLike,
71
XYZ_w: ArrayLike,
72
XYZ_wr: ArrayLike,
73
transform: LiteralChromaticAdaptationTransform = "CAT02"
74
) -> NDArrayFloat:
75
"""
76
Adapt given stimulus CIE XYZ tristimulus values from test viewing conditions
77
to reference viewing conditions using Von Kries chromatic adaptation model.
78
79
Parameters:
80
- XYZ: CIE XYZ tristimulus values of stimulus to adapt
81
- XYZ_w: test viewing condition CIE XYZ tristimulus values of whitepoint
82
- XYZ_wr: reference viewing condition CIE XYZ tristimulus values of whitepoint
83
- transform: chromatic adaptation transform matrix to use
84
85
Returns:
86
CIE XYZ_c tristimulus values of the stimulus corresponding colour
87
"""
88
```
89
90
### CMCCAT2000 Chromatic Adaptation
91
92
CMC CAT2000 chromatic adaptation transform with viewing condition support.
93
94
```python { .api }
95
class InductionFactors_CMCCAT2000:
96
"""
97
CMCCAT2000 chromatic adaptation model induction factors.
98
99
Attributes:
100
- F: surround condition factor
101
"""
102
F: float
103
104
def chromatic_adaptation_CMCCAT2000(
105
XYZ: ArrayLike,
106
XYZ_w: ArrayLike,
107
XYZ_wr: ArrayLike,
108
L_A1: ArrayLike,
109
L_A2: ArrayLike,
110
surround: InductionFactors_CMCCAT2000 = None,
111
direction: Literal["Forward", "Inverse"] = "Forward"
112
) -> NDArrayFloat:
113
"""
114
Adapt given stimulus CIE XYZ tristimulus values from test viewing conditions
115
to reference viewing conditions using CMCCAT2000 chromatic adaptation model.
116
117
Parameters:
118
- XYZ: CIE XYZ tristimulus values of the stimulus to adapt
119
- XYZ_w: test viewing condition CIE XYZ tristimulus values of whitepoint
120
- XYZ_wr: reference viewing condition CIE XYZ tristimulus values of whitepoint
121
- L_A1: luminance of test adapting field in cd/m²
122
- L_A2: luminance of reference adapting field in cd/m²
123
- surround: surround viewing conditions induction factors
124
- direction: chromatic adaptation direction ("Forward" or "Inverse")
125
126
Returns:
127
CIE XYZ_c tristimulus values of the stimulus corresponding colour
128
129
Domain/Range: [0, 100] for XYZ in reference scale, [0, 1] in scale-1 mode
130
"""
131
132
def chromatic_adaptation_forward_CMCCAT2000(
133
XYZ: ArrayLike,
134
XYZ_w: ArrayLike,
135
XYZ_wr: ArrayLike,
136
L_A1: ArrayLike,
137
L_A2: ArrayLike,
138
surround: InductionFactors_CMCCAT2000 = None
139
) -> NDArrayFloat:
140
"""
141
Forward CMCCAT2000 chromatic adaptation from test to reference conditions.
142
143
Parameters same as chromatic_adaptation_CMCCAT2000 with direction="Forward"
144
"""
145
146
def chromatic_adaptation_inverse_CMCCAT2000(
147
XYZ: ArrayLike,
148
XYZ_w: ArrayLike,
149
XYZ_wr: ArrayLike,
150
L_A1: ArrayLike,
151
L_A2: ArrayLike,
152
surround: InductionFactors_CMCCAT2000 = None
153
) -> NDArrayFloat:
154
"""
155
Inverse CMCCAT2000 chromatic adaptation from reference to test conditions.
156
157
Parameters same as chromatic_adaptation_CMCCAT2000 with direction="Inverse"
158
"""
159
```
160
161
### CIE 1994 Chromatic Adaptation
162
163
CIE 1994 chromatic adaptation model with illuminance considerations.
164
165
```python { .api }
166
def chromatic_adaptation_CIE1994(
167
XYZ_1: ArrayLike,
168
xy_o1: ArrayLike,
169
xy_o2: ArrayLike,
170
Y_o: ArrayLike,
171
E_o1: ArrayLike,
172
E_o2: ArrayLike,
173
n: ArrayLike = 1
174
) -> NDArrayFloat:
175
"""
176
Adapt given stimulus CIE XYZ tristimulus values from test viewing conditions
177
to reference viewing conditions using CIE 1994 chromatic adaptation model.
178
179
Parameters:
180
- XYZ_1: CIE XYZ tristimulus values of test sample/stimulus
181
- xy_o1: chromaticity coordinates of test illuminant and background
182
- xy_o2: chromaticity coordinates of reference illuminant and background
183
- Y_o: luminance factor of achromatic background as percentage [18, 100]
184
- E_o1: test illuminance in cd/m²
185
- E_o2: reference illuminance in cd/m²
186
- n: noise component in fundamental primary system
187
188
Returns:
189
Adapted CIE XYZ tristimulus values of stimulus
190
191
Domain/Range: [0, 100] for XYZ and Y_o in reference scale
192
"""
193
```
194
195
### Fairchild 1990 Chromatic Adaptation
196
197
Fairchild's 1990 incomplete chromatic adaptation model.
198
199
```python { .api }
200
def chromatic_adaptation_Fairchild1990(
201
XYZ_1: ArrayLike,
202
XYZ_n: ArrayLike,
203
XYZ_r: ArrayLike,
204
Y_n: ArrayLike,
205
discount_illuminant: bool = False
206
) -> NDArrayFloat:
207
"""
208
Adapt given stimulus CIE XYZ tristimulus values from test viewing conditions
209
to reference viewing conditions using Fairchild (1990) chromatic adaptation model.
210
211
Parameters:
212
- XYZ_1: CIE XYZ tristimulus values of test sample/stimulus
213
- XYZ_n: test viewing condition CIE XYZ tristimulus values of whitepoint
214
- XYZ_r: reference viewing condition CIE XYZ tristimulus values of whitepoint
215
- Y_n: luminance of test adapting stimulus in cd/m²
216
- discount_illuminant: whether the illuminant should be discounted
217
218
Returns:
219
Adapted CIE XYZ tristimulus values of stimulus
220
221
Domain/Range: [0, 100] for XYZ in reference scale, [0, 1] in scale-1 mode
222
"""
223
```
224
225
### Von Kries 2020 (vK20) Chromatic Adaptation
226
227
Modern evolution of Von Kries adaptation with degree of adaptation coefficients.
228
229
```python { .api }
230
class Coefficients_DegreeOfAdaptation_vK20:
231
"""
232
Von Kries 2020 (vK20) degree of adaptation coefficients.
233
234
Attributes:
235
- D_n: degree of adaptation for the adapting illuminant
236
- D_r: degree of adaptation for the reference illuminant
237
- D_p: degree of adaptation for the previous illuminant
238
"""
239
D_n: float
240
D_r: float
241
D_p: float
242
243
def matrix_chromatic_adaptation_vk20(
244
XYZ_p: ArrayLike,
245
XYZ_n: ArrayLike,
246
XYZ_r: ArrayLike = None,
247
coefficients: Coefficients_DegreeOfAdaptation_vK20 = None,
248
transform: LiteralChromaticAdaptationTransform = "CAT02"
249
) -> NDArrayFloat:
250
"""
251
Compute the vK20 chromatic adaptation matrix.
252
253
Parameters:
254
- XYZ_p: previous/test viewing conditions XYZ tristimulus values of whitepoint
255
- XYZ_n: current viewing conditions XYZ tristimulus values of whitepoint
256
- XYZ_r: reference viewing conditions XYZ tristimulus values of whitepoint
257
- coefficients: vK20 degree of adaptation coefficients
258
- transform: chromatic adaptation transform matrix to use
259
260
Returns:
261
vK20 chromatic adaptation matrix
262
"""
263
264
def chromatic_adaptation_vK20(
265
XYZ: ArrayLike,
266
XYZ_p: ArrayLike,
267
XYZ_n: ArrayLike,
268
XYZ_r: ArrayLike = None,
269
coefficients: Coefficients_DegreeOfAdaptation_vK20 = None,
270
transform: LiteralChromaticAdaptationTransform = "CAT02"
271
) -> NDArrayFloat:
272
"""
273
Adapt given stimulus CIE XYZ tristimulus values using Von Kries 2020 (vK20)
274
chromatic adaptation model.
275
276
Parameters:
277
- XYZ: CIE XYZ tristimulus values of stimulus to adapt
278
- XYZ_p: previous/test viewing conditions XYZ tristimulus values of whitepoint
279
- XYZ_n: current viewing conditions XYZ tristimulus values of whitepoint
280
- XYZ_r: reference viewing conditions XYZ tristimulus values of whitepoint
281
- coefficients: vK20 degree of adaptation coefficients
282
- transform: chromatic adaptation transform matrix to use
283
284
Returns:
285
CIE XYZ_c tristimulus values of the stimulus corresponding colour
286
"""
287
```
288
289
### Zhai and Luo 2018 Chromatic Adaptation
290
291
Two-step chromatic adaptation model with baseline illuminant concept.
292
293
```python { .api }
294
def chromatic_adaptation_Zhai2018(
295
XYZ_b: ArrayLike,
296
XYZ_wb: ArrayLike,
297
XYZ_wd: ArrayLike,
298
D_b: ArrayLike = 1,
299
D_d: ArrayLike = 1,
300
XYZ_wo: ArrayLike = None,
301
transform: Literal["CAT02", "CAT16"] = "CAT02"
302
) -> NDArrayFloat:
303
"""
304
Adapt given sample colour from input viewing conditions to output viewing conditions
305
using Zhai and Luo (2018) two-step chromatic adaptation model.
306
307
This model uses a baseline illuminant (BI) concept where adaptation is calculated
308
relative to an intrinsic property of the human vision system, allowing for
309
incomplete-to-incomplete adaptation scenarios.
310
311
Parameters:
312
- XYZ_b: sample colour under input illuminant β
313
- XYZ_wb: input illuminant β tristimulus values
314
- XYZ_wd: output illuminant δ tristimulus values
315
- D_b: degree of adaptation of input illuminant β
316
- D_d: degree of adaptation of output illuminant δ
317
- XYZ_wo: baseline illuminant (BI) tristimulus values
318
- transform: chromatic adaptation transform ("CAT02" or "CAT16")
319
320
Returns:
321
Sample corresponding colour XYZ tristimulus values under output illuminant
322
323
Domain/Range: [0, 100] for XYZ in reference scale, [0, 1] in scale-1 mode
324
"""
325
```
326
327
## Chromatic Adaptation Transform Matrices
328
329
Pre-defined chromatic adaptation transform matrices for various CAT models.
330
331
```python { .api }
332
# Primary CAT Matrices (3x3 NDArrayFloat)
333
CAT_XYZ_SCALING: NDArrayFloat
334
"""XYZ Scaling chromatic adaptation transform (identity matrix)."""
335
336
CAT_VON_KRIES: NDArrayFloat
337
"""Von Kries chromatic adaptation transform."""
338
339
CAT_BRADFORD: NDArrayFloat
340
"""Bradford chromatic adaptation transform."""
341
342
CAT_SHARP: NDArrayFloat
343
"""Sharp chromatic adaptation transform."""
344
345
CAT_FAIRCHILD: NDArrayFloat
346
"""Fairchild chromatic adaptation transform."""
347
348
CAT_CMCCAT97: NDArrayFloat
349
"""CMCCAT97 chromatic adaptation transform."""
350
351
CAT_CMCCAT2000: NDArrayFloat
352
"""CMCCAT2000 chromatic adaptation transform."""
353
354
CAT_CAT02: NDArrayFloat
355
"""CAT02 chromatic adaptation transform."""
356
357
CAT_CAT02_BRILL2008: NDArrayFloat
358
"""Brill and Susstrunk (2008) corrected CAT02 chromatic adaptation transform."""
359
360
CAT_CAT16: NDArrayFloat
361
"""CAT16 chromatic adaptation transform."""
362
363
CAT_BIANCO2010: NDArrayFloat
364
"""Bianco and Schettini (2010) chromatic adaptation transform."""
365
366
CAT_PC_BIANCO2010: NDArrayFloat
367
"""Bianco and Schettini PC (2010) chromatic adaptation transform (no negative lobes)."""
368
```
369
370
## Viewing Conditions and Constants
371
372
Standard viewing conditions and adaptation coefficients for chromatic adaptation models.
373
374
```python { .api }
375
# CMCCAT2000 Viewing Conditions
376
VIEWING_CONDITIONS_CMCCAT2000: Dict[str, InductionFactors_CMCCAT2000]
377
"""
378
Reference CMCCAT2000 chromatic adaptation model viewing conditions.
379
380
Available conditions:
381
- "Average": F = 1.0
382
- "Dim": F = 0.8
383
- "Dark": F = 0.8
384
"""
385
386
# vK20 Degree of Adaptation Conditions
387
CONDITIONS_DEGREE_OF_ADAPTATION_VK20: Dict[str, Coefficients_DegreeOfAdaptation_vK20]
388
"""
389
Conditions for the Von Kries 2020 (vK20) degree of adaptation coefficients.
390
391
Available conditions:
392
- "Fairchild": (D_n=0.7, D_r=0.3, D_p=0)
393
- "Hands": (D_n=0.95, D_r=0.05, D_p=0)
394
- "No Hands": (D_n=0.85, D_r=0.15, D_p=0)
395
- "Ordinal 1st": (D_n=0.9, D_r=0.1, D_p=0)
396
- "Ordinal 2nd": (D_n=0.8, D_r=0.1, D_p=0.1)
397
- "Reversibility Trial 1st": (D_n=0.7, D_r=0.3, D_p=0.1)
398
- "Reversibility Trial 2nd": (D_n=0.6, D_r=0.3, D_p=0.1)
399
- "Ma et al.": (D_n=1/3, D_r=1/3, D_p=1/3)
400
- "Hunt & Winter": (D_n=0.6, D_r=0.2, D_p=0.2)
401
- "Hurvich & Jameson": (D_n=0.7, D_r=0.3, D_p=0)
402
- "Simple von Kries": (D_n=1, D_r=0, D_p=0)
403
"""
404
405
TVS_XYZ_R_VK20: NDArrayFloat
406
"""
407
Von Kries 2020 (vK20) reference illuminant tristimulus values.
408
Approximately 15000K sky blue (u'=0.185, v'=0.425).
409
"""
410
411
# Transform Collections
412
CHROMATIC_ADAPTATION_TRANSFORMS: Dict[str, NDArrayFloat]
413
"""
414
Available chromatic adaptation transforms mapping method names to matrices.
415
416
Keys: "XYZ Scaling", "Von Kries", "Bradford", "Sharp", "Fairchild",
417
"CMCCAT97", "CMCCAT2000", "CAT02", "CAT02 Brill 2008", "CAT16",
418
"Bianco 2010", "Bianco PC 2010"
419
"""
420
421
CHROMATIC_ADAPTATION_METHODS: Dict[str, Callable]
422
"""
423
Supported chromatic adaptation methods mapping method names to functions.
424
425
Keys: "CIE 1994", "CMCCAT2000", "Fairchild 1990", "Von Kries",
426
"Zhai 2018", "vK20"
427
"""
428
```
429
430
## Usage Examples
431
432
### Basic Von Kries Adaptation
433
434
```python
435
import numpy as np
436
437
# Basic Von Kries chromatic adaptation
438
XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
439
XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775]) # D65
440
XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460]) # D50
441
442
# Adapt from D65 to D50 using Von Kries (default)
443
XYZ_adapted = chromatic_adaptation(XYZ, XYZ_w, XYZ_wr)
444
# array([0.21638817, 0.1257, 0.03847493])
445
446
# Using Bradford transform explicitly
447
XYZ_adapted_bradford = chromatic_adaptation_VonKries(
448
XYZ, XYZ_w, XYZ_wr, transform="Bradford"
449
)
450
```
451
452
### CMCCAT2000 Adaptation with Viewing Conditions
453
454
```python
455
# CMCCAT2000 adaptation with specific viewing conditions
456
XYZ = np.array([0.2248, 0.2274, 0.0854])
457
XYZ_w = np.array([1.1115, 1.0000, 0.3520])
458
XYZ_wr = np.array([0.9481, 1.0000, 1.0730])
459
L_A = 200
460
461
XYZ_adapted = chromatic_adaptation(
462
XYZ, XYZ_w, XYZ_wr,
463
method="CMCCAT2000",
464
L_A1=L_A,
465
L_A2=L_A,
466
surround=VIEWING_CONDITIONS_CMCCAT2000["Average"]
467
)
468
```
469
470
### vK20 Adaptation with Custom Coefficients
471
472
```python
473
# Von Kries 2020 adaptation with specific coefficients
474
XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
475
XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775])
476
XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460])
477
478
# Using predefined coefficients
479
XYZ_adapted = chromatic_adaptation(
480
XYZ, XYZ_w, XYZ_wr,
481
method="vK20",
482
coefficients=CONDITIONS_DEGREE_OF_ADAPTATION_VK20["Fairchild"]
483
)
484
485
# Using custom coefficients
486
custom_coeffs = Coefficients_DegreeOfAdaptation_vK20(D_n=0.8, D_r=0.2, D_p=0)
487
XYZ_adapted_custom = chromatic_adaptation_vK20(
488
XYZ, XYZ_w, XYZ_wr, coefficients=custom_coeffs
489
)
490
```
491
492
### Two-Step Zhai 2018 Adaptation
493
494
```python
495
# Zhai 2018 two-step adaptation with baseline illuminant
496
XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
497
XYZ_wb = np.array([0.95045593, 1.00000000, 1.08905775]) # Input illuminant
498
XYZ_wd = np.array([0.96429568, 1.00000000, 0.82510460]) # Output illuminant
499
XYZ_wo = np.array([100, 100, 100]) # Baseline illuminant
500
501
XYZ_adapted = chromatic_adaptation(
502
XYZ, XYZ_wb, XYZ_wd,
503
method="Zhai 2018",
504
D_b=0.9, # Degree of adaptation for input
505
D_d=0.95, # Degree of adaptation for output
506
XYZ_wo=XYZ_wo
507
)
508
```
509
510
### Computing Adaptation Matrices
511
512
```python
513
# Compute Von Kries adaptation matrix
514
XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775])
515
XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460])
516
517
# Using CAT02 transform
518
M_cat = matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr, transform="CAT02")
519
520
# Apply matrix directly to adapt colors
521
XYZ_adapted_manual = XYZ @ M_cat.T
522
523
# vK20 adaptation matrix
524
M_vk20 = matrix_chromatic_adaptation_vk20(
525
XYZ_w, XYZ_wr,
526
coefficients=CONDITIONS_DEGREE_OF_ADAPTATION_VK20["Fairchild"]
527
)
528
```
529
530
## Type Definitions
531
532
```python
533
from typing import Literal, Union
534
from numpy.typing import NDArray
535
536
# Type aliases for chromatic adaptation
537
ArrayLike = Union[list, tuple, NDArray]
538
NDArrayFloat = NDArray[float]
539
540
LiteralChromaticAdaptationTransform = Literal[
541
"XYZ Scaling", "Von Kries", "Bradford", "Sharp", "Fairchild",
542
"CMCCAT97", "CMCCAT2000", "CAT02", "CAT02 Brill 2008", "CAT16",
543
"Bianco 2010", "Bianco PC 2010"
544
]
545
546
LiteralChromaticAdaptationMethod = Literal[
547
"CIE 1994", "CMCCAT2000", "Fairchild 1990",
548
"Von Kries", "Zhai 2018", "vK20"
549
]
550
```
551
552
## Notes
553
554
### Domain and Range Scaling
555
556
Most chromatic adaptation functions support dual domain/range scaling:
557
- **Reference Scale**: XYZ values in [0, 100], Y_o in [0, 100]
558
- **Scale-1**: XYZ values in [0, 1], Y_o in [0, 1]
559
560
The scaling mode is controlled by the global domain-range scale setting.
561
562
### Transform Selection Guidelines
563
564
- **CAT02**: Default for most applications, good balance of accuracy and stability
565
- **Bradford**: Widely used, excellent for D-series illuminants
566
- **Von Kries**: Classical choice, simple and robust
567
- **CAT16**: Modern choice, designed for CAM16 color appearance model
568
- **Sharp/Bianco**: Optimized transforms for specific applications
569
- **CMCCAT2000**: Specialized for CMCCAT2000 model usage
570
571
### Method Selection Guidelines
572
573
- **Von Kries**: Fast, simple, suitable for most applications
574
- **CMCCAT2000**: When viewing conditions (luminance, surround) are important
575
- **CIE 1994**: When illuminance levels affect adaptation
576
- **Fairchild 1990**: For incomplete adaptation scenarios
577
- **vK20**: Modern approach with adaptation history consideration
578
- **Zhai 2018**: For complex incomplete-to-incomplete adaptation scenarios
579
580
### Performance Considerations
581
582
- Von Kries methods are fastest (simple matrix operations)
583
- CMCCAT2000 and CIE 1994 have moderate computational overhead
584
- Zhai 2018 is most complex (two-step process with baseline illuminant)
585
- Matrix pre-computation recommended for batch processing