0
# Color Appearance Models
1
2
Color appearance models provide advanced predictions of how colors appear under different viewing conditions. These models account for factors like ambient lighting, surround conditions, and adaptation state to predict color appearance more accurately than basic colorimetric calculations.
3
4
## Capabilities
5
6
### CIE CAM02
7
8
The most widely adopted color appearance model, providing comprehensive color appearance predictions.
9
10
```python { .api }
11
class CIECAM02:
12
"""CIE CAM02 color appearance model."""
13
def __init__(self, xyz_color, **viewing_conditions):
14
"""
15
Initialize CIE CAM02 model.
16
17
Parameters:
18
- xyz_color: XYZ color values under test illuminant
19
- viewing_conditions: Dictionary with keys:
20
- 'white_point': XYZ values of reference white
21
- 'L_A': Adapting luminance (cd/m²)
22
- 'Y_b': Background luminance factor
23
- 'surround': Surround condition ('average', 'dim', 'dark')
24
- 'discount_illuminant': Boolean for discount-the-illuminant mode
25
26
Attributes:
27
- J: Lightness
28
- C: Chroma
29
- h: Hue angle
30
- H: Hue quadrature
31
- M: Colorfulness
32
- s: Saturation
33
- Q: Brightness
34
"""
35
36
def correlates(self):
37
"""Get all appearance correlates as dictionary."""
38
39
def to_xyz(self):
40
"""Convert back to XYZ color space."""
41
```
42
43
### Modified CIE CAM02
44
45
Enhanced version of CIE CAM02 with improved performance.
46
47
```python { .api }
48
class CIECAM02m1:
49
"""Modified CIE CAM02 color appearance model."""
50
def __init__(self, xyz_color, **viewing_conditions):
51
"""
52
Initialize modified CIE CAM02 model.
53
54
Parameters:
55
- xyz_color: XYZ color values
56
- viewing_conditions: Same as CIECAM02 with modifications
57
58
Notes:
59
- Improved chromatic adaptation transform
60
- Better performance in extreme viewing conditions
61
- Enhanced numerical stability
62
"""
63
```
64
65
### RLAB Color Appearance Model
66
67
Rochester Institute of Technology color appearance model.
68
69
```python { .api }
70
class RLAB:
71
"""RLAB color appearance model."""
72
def __init__(self, xyz_color, **parameters):
73
"""
74
Initialize RLAB model.
75
76
Parameters:
77
- xyz_color: XYZ color values
78
- parameters: Dictionary with model parameters:
79
- 'reference_white': XYZ white point
80
- 'reference_illuminant': Reference illuminant
81
- 'sigma': Surround parameter
82
- 'D': Degree of adaptation
83
84
Attributes:
85
- L_R: RLAB lightness
86
- a_R: RLAB red-green
87
- b_R: RLAB yellow-blue
88
"""
89
```
90
91
### LLAB Color Appearance Model
92
93
Large field color appearance model optimized for large visual fields.
94
95
```python { .api }
96
class LLAB:
97
"""LLAB color appearance model."""
98
def __init__(self, xyz_color, **parameters):
99
"""
100
Initialize LLAB model.
101
102
Parameters:
103
- xyz_color: XYZ color values
104
- parameters: Dictionary with model parameters:
105
- 'reference_white': XYZ white point
106
- 'D': Degree of adaptation
107
- 'F_S': Surround factor
108
- 'F_L': Luminance factor
109
110
Attributes:
111
- L_L: LLAB lightness
112
- C_L: LLAB chroma
113
- h_L: LLAB hue
114
"""
115
```
116
117
### ATD95 Color Vision Model
118
119
Guth ATD95 color vision model based on cone response.
120
121
```python { .api }
122
class ATD95:
123
"""ATD95 color vision model."""
124
def __init__(self, xyz_color, **parameters):
125
"""
126
Initialize ATD95 model.
127
128
Parameters:
129
- xyz_color: XYZ color values
130
- parameters: Dictionary with model parameters:
131
- 'sigma': Noise parameter
132
- 'k_1': First constant
133
- 'k_2': Second constant
134
135
Attributes:
136
- A: Achromatic response
137
- T: Tritanopic response
138
- D: Deuteranopic response
139
"""
140
```
141
142
### Nayatani95 Color Appearance Model
143
144
Nayatani color appearance model with brightness prediction.
145
146
```python { .api }
147
class Nayatani95:
148
"""Nayatani95 color appearance model."""
149
def __init__(self, xyz_color, **parameters):
150
"""
151
Initialize Nayatani95 model.
152
153
Parameters:
154
- xyz_color: XYZ color values
155
- parameters: Dictionary with model parameters:
156
- 'L_o': Luminance of reference white
157
- 'theta': Surround angle
158
- 'background': Background specification
159
160
Attributes:
161
- L_N: Lightness
162
- C_N: Chroma
163
- H_N: Hue
164
- B_r: Brightness
165
"""
166
```
167
168
### Hunt Color Appearance Model
169
170
Hunt color appearance model with comprehensive appearance prediction.
171
172
```python { .api }
173
class Hunt:
174
"""Hunt color appearance model."""
175
def __init__(self, xyz_color, **parameters):
176
"""
177
Initialize Hunt model.
178
179
Parameters:
180
- xyz_color: XYZ color values
181
- parameters: Dictionary with extensive model parameters:
182
- 'L_A': Adapting luminance
183
- 'N_c': Chromatic induction factor
184
- 'N_b': Brightness induction factor
185
- 'surround': Surround conditions
186
- Many additional parameters for comprehensive modeling
187
188
Attributes:
189
- J: Lightness
190
- C: Chroma
191
- h: Hue angle
192
- Q: Brightness
193
- M: Colorfulness
194
- s: Saturation
195
"""
196
```
197
198
## Usage Examples
199
200
### Basic CIE CAM02 Usage
201
202
```python
203
from colormath.color_objects import XYZColor
204
from colormath.color_appearance_models import CIECAM02
205
206
# Define viewing conditions
207
viewing_conditions = {
208
'white_point': (95.047, 100.000, 108.883), # D65 white point
209
'L_A': 64.0, # Adapting luminance (cd/m²)
210
'Y_b': 20.0, # Background luminance factor
211
'surround': 'average', # Surround condition
212
'discount_illuminant': False
213
}
214
215
# Create XYZ color
216
xyz_color = XYZColor(xyz_x=19.01, xyz_y=20.00, xyz_z=21.78)
217
218
# Apply CAM02 model
219
cam02 = CIECAM02(xyz_color, **viewing_conditions)
220
221
# Get appearance correlates
222
correlates = cam02.correlates()
223
print(f"Lightness (J): {correlates['J']:.2f}")
224
print(f"Chroma (C): {correlates['C']:.2f}")
225
print(f"Hue angle (h): {correlates['h']:.2f}")
226
print(f"Brightness (Q): {correlates['Q']:.2f}")
227
print(f"Colorfulness (M): {correlates['M']:.2f}")
228
print(f"Saturation (s): {correlates['s']:.2f}")
229
```
230
231
### Color Appearance Under Different Illuminants
232
233
```python
234
from colormath.color_objects import XYZColor
235
from colormath.color_appearance_models import CIECAM02
236
from colormath.color_constants import ILLUMINANTS
237
238
# Sample color
239
xyz_color = XYZColor(xyz_x=25.0, xyz_y=20.0, xyz_z=15.0)
240
241
# Different illuminants
242
illuminants = {
243
'D65': ILLUMINANTS['2']['d65'],
244
'A': ILLUMINANTS['2']['a'],
245
'D50': ILLUMINANTS['2']['d50']
246
}
247
248
# Compare appearance under different illuminants
249
for illum_name, illum_xyz in illuminants.items():
250
white_point = [val * 100 for val in illum_xyz] # Scale to 100
251
252
viewing_conditions = {
253
'white_point': white_point,
254
'L_A': 64.0,
255
'Y_b': 20.0,
256
'surround': 'average',
257
'discount_illuminant': False
258
}
259
260
cam02 = CIECAM02(xyz_color, **viewing_conditions)
261
correlates = cam02.correlates()
262
263
print(f"\n{illum_name} Illuminant:")
264
print(f" Lightness: {correlates['J']:.2f}")
265
print(f" Chroma: {correlates['C']:.2f}")
266
print(f" Hue: {correlates['h']:.2f}")
267
```
268
269
### Surround Effect Comparison
270
271
```python
272
from colormath.color_objects import XYZColor
273
from colormath.color_appearance_models import CIECAM02
274
275
xyz_color = XYZColor(xyz_x=30.0, xyz_y=25.0, xyz_z=20.0)
276
base_conditions = {
277
'white_point': (95.047, 100.000, 108.883),
278
'L_A': 64.0,
279
'Y_b': 20.0,
280
'discount_illuminant': False
281
}
282
283
# Different surround conditions
284
surrounds = ['average', 'dim', 'dark']
285
286
for surround in surrounds:
287
conditions = base_conditions.copy()
288
conditions['surround'] = surround
289
290
cam02 = CIECAM02(xyz_color, **conditions)
291
correlates = cam02.correlates()
292
293
print(f"\n{surround.title()} Surround:")
294
print(f" Brightness (Q): {correlates['Q']:.2f}")
295
print(f" Colorfulness (M): {correlates['M']:.2f}")
296
print(f" Lightness (J): {correlates['J']:.2f}")
297
```
298
299
### Multi-Model Comparison
300
301
```python
302
from colormath.color_objects import XYZColor
303
from colormath.color_appearance_models import CIECAM02, RLAB, LLAB
304
305
xyz_color = XYZColor(xyz_x=20.0, xyz_y=18.0, xyz_z=22.0)
306
307
# CIE CAM02
308
cam02_conditions = {
309
'white_point': (95.047, 100.000, 108.883),
310
'L_A': 64.0,
311
'Y_b': 20.0,
312
'surround': 'average',
313
'discount_illuminant': False
314
}
315
cam02 = CIECAM02(xyz_color, **cam02_conditions)
316
cam02_correlates = cam02.correlates()
317
318
# RLAB
319
rlab_params = {
320
'reference_white': (95.047, 100.000, 108.883),
321
'reference_illuminant': 'd65',
322
'sigma': 1.0,
323
'D': 1.0
324
}
325
rlab = RLAB(xyz_color, **rlab_params)
326
327
# LLAB
328
llab_params = {
329
'reference_white': (95.047, 100.000, 108.883),
330
'D': 1.0,
331
'F_S': 1.0,
332
'F_L': 1.0
333
}
334
llab = LLAB(xyz_color, **llab_params)
335
336
print("Model Comparison:")
337
print(f"CAM02 Lightness: {cam02_correlates['J']:.2f}")
338
print(f"RLAB Lightness: {rlab.L_R:.2f}")
339
print(f"LLAB Lightness: {llab.L_L:.2f}")
340
```
341
342
### Display Calibration Application
343
344
```python
345
from colormath.color_objects import XYZColor
346
from colormath.color_appearance_models import CIECAM02
347
348
def predict_display_appearance(rgb_values, display_profile, viewing_environment):
349
"""
350
Predict color appearance on display under specific viewing conditions.
351
352
Parameters:
353
- rgb_values: List of RGB color tuples
354
- display_profile: Display characteristics
355
- viewing_environment: Viewing condition parameters
356
357
Returns:
358
List of appearance predictions
359
"""
360
results = []
361
362
for rgb in rgb_values:
363
# Convert RGB to XYZ (simplified - would use display profile)
364
xyz = XYZColor(
365
xyz_x=rgb[0] * 0.95047,
366
xyz_y=rgb[1] * 1.00000,
367
xyz_z=rgb[2] * 1.08883
368
)
369
370
# Apply appearance model
371
cam02 = CIECAM02(xyz, **viewing_environment)
372
correlates = cam02.correlates()
373
374
results.append({
375
'rgb': rgb,
376
'lightness': correlates['J'],
377
'chroma': correlates['C'],
378
'hue': correlates['h'],
379
'brightness': correlates['Q']
380
})
381
382
return results
383
384
# Example usage
385
rgb_colors = [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)]
386
display_profile = {} # Would contain display characteristics
387
viewing_env = {
388
'white_point': (95.047, 100.000, 108.883),
389
'L_A': 200.0, # Bright office environment
390
'Y_b': 10.0,
391
'surround': 'average',
392
'discount_illuminant': True
393
}
394
395
appearance_predictions = predict_display_appearance(rgb_colors, display_profile, viewing_env)
396
for prediction in appearance_predictions:
397
print(f"RGB {prediction['rgb']}: J={prediction['lightness']:.1f}, C={prediction['chroma']:.1f}")
398
```
399
400
### Color Matching Under Different Viewing Conditions
401
402
```python
403
from colormath.color_objects import XYZColor
404
from colormath.color_appearance_models import CIECAM02
405
406
def match_colors_across_conditions(source_xyz, source_conditions, target_conditions):
407
"""
408
Predict what color would match the source under target conditions.
409
410
Parameters:
411
- source_xyz: XYZ color under source conditions
412
- source_conditions: Source viewing conditions
413
- target_conditions: Target viewing conditions
414
415
Returns:
416
XYZ color that appears the same under target conditions
417
"""
418
# Get appearance under source conditions
419
source_cam02 = CIECAM02(source_xyz, **source_conditions)
420
source_correlates = source_cam02.correlates()
421
422
# Find XYZ that produces same appearance under target conditions
423
# This would require inverse CAM02 calculation (simplified here)
424
target_xyz = source_cam02.to_xyz() # Simplified
425
426
return target_xyz, source_correlates
427
428
# Example: Match color from office to home lighting
429
office_xyz = XYZColor(xyz_x=25.0, xyz_y=20.0, xyz_z=18.0)
430
431
office_conditions = {
432
'white_point': (95.047, 100.000, 108.883), # D65
433
'L_A': 200.0, # Bright office
434
'Y_b': 20.0,
435
'surround': 'average',
436
'discount_illuminant': False
437
}
438
439
home_conditions = {
440
'white_point': (109.85, 100.000, 35.585), # Illuminant A
441
'L_A': 20.0, # Dim home lighting
442
'Y_b': 15.0,
443
'surround': 'dim',
444
'discount_illuminant': False
445
}
446
447
matched_xyz, appearance = match_colors_across_conditions(
448
office_xyz, office_conditions, home_conditions
449
)
450
451
print(f"Original appearance: J={appearance['J']:.1f}, C={appearance['C']:.1f}, h={appearance['h']:.1f}")
452
```
453
454
## Model Selection Guidelines
455
456
### When to Use Each Model
457
458
| Model | Best For | Strengths | Limitations |
459
|-------|----------|-----------|-------------|
460
| CIE CAM02 | General purpose, displays | Well-validated, comprehensive | Complex parameters |
461
| CIE CAM02m1 | Extreme conditions | Improved stability | Less widely adopted |
462
| RLAB | Print reproduction | Simple, fast | Limited scope |
463
| LLAB | Large field viewing | Large field optimization | Specialized use |
464
| ATD95 | Color vision research | Physiological basis | Research-oriented |
465
| Nayatani95 | Brightness prediction | Brightness focus | Less comprehensive |
466
| Hunt | Research applications | Very comprehensive | Extremely complex |
467
468
### Parameter Guidelines
469
470
#### CIE CAM02 Parameter Ranges
471
- **L_A (Adapting luminance)**: 0.2-4000 cd/m²
472
- **Y_b (Background factor)**: 10-25% typically
473
- **Surround**: 'average' (>20% of white), 'dim' (20%), 'dark' (<20%)
474
475
#### Typical Viewing Conditions
476
- **Office**: L_A=200, Y_b=20, surround='average'
477
- **Home**: L_A=20, Y_b=15, surround='dim'
478
- **Cinema**: L_A=1, Y_b=5, surround='dark'
479
- **Print viewing**: L_A=64, Y_b=20, surround='average'