CIE LAB Color Space

Perceptually uniform color space designed for measuring color differences.

Overview

CIE LAB (also written as CIELAB or L*a*b*) is designed to be perceptually uniform, meaning that equal distances in LAB space correspond to roughly equal perceived color differences. This makes it ideal for:

  • Color difference calculations (Delta E)
  • Color matching and quality control
  • Image processing where perceptual uniformity matters

Components

  • L*: Lightness (0 = black, 100 = white)
  • a*: Green (-) to Red (+)
  • b*: Blue (-) to Yellow (+)

XYZ to LAB Conversion

Forward Transform

$$ L^* = 116 \cdot f(Y/Y_n) - 16 $$

$$ a^* = 500 \cdot [f(X/X_n) - f(Y/Y_n)] $$

$$ b^* = 200 \cdot [f(Y/Y_n) - f(Z/Z_n)] $$

Where the function $f(t)$ is defined as:

$$ f(t) = \begin{cases} t^{1/3} & \text{if } t > \delta^3 \ \frac{t}{3\delta^2} + \frac{4}{29} & \text{otherwise} \end{cases} $$

Constants:

  • $\delta = 6/29 \approx 0.2069$
  • $\delta^3 \approx 0.008856$
  • $(X_n, Y_n, Z_n)$ are reference white values (D65: 95.047, 100.0, 108.883)

Inverse Transform (LAB to XYZ)

$$ X = X_n \cdot f^{-1}\left(\frac{L^* + 16}{116} + \frac{a^*}{500}\right) $$

$$ Y = Y_n \cdot f^{-1}\left(\frac{L^* + 16}{116}\right) $$

$$ Z = Z_n \cdot f^{-1}\left(\frac{L^* + 16}{116} - \frac{b^*}{200}\right) $$

Where the inverse function $f^{-1}(t)$ is:

$$ f^{-1}(t) = \begin{cases} t^3 & \text{if } t > \delta \ 3\delta^2(t - 4/29) & \text{otherwise} \end{cases} $$


Practical Implementation

Python

 1import numpy as np
 2
 3# D65 reference white
 4XYZ_N = np.array([95.047, 100.0, 108.883])
 5
 6DELTA = 6.0 / 29.0
 7DELTA_CUBE = DELTA ** 3
 8
 9def f_lab(t):
10    """LAB f function"""
11    return np.where(
12        t > DELTA_CUBE,
13        np.cbrt(t),
14        t / (3 * DELTA**2) + 4/29
15    )
16
17def f_lab_inv(t):
18    """LAB inverse f function"""
19    return np.where(
20        t > DELTA,
21        t ** 3,
22        3 * DELTA**2 * (t - 4/29)
23    )
24
25def xyz_to_lab(x, y, z, white=XYZ_N):
26    """Convert XYZ to LAB"""
27    xyz = np.array([x, y, z])
28    xyz_n = xyz / white
29    
30    fx, fy, fz = f_lab(xyz_n)
31    
32    L = 116 * fy - 16
33    a = 500 * (fx - fy)
34    b = 200 * (fy - fz)
35    
36    return L, a, b
37
38def lab_to_xyz(L, a, b, white=XYZ_N):
39    """Convert LAB to XYZ"""
40    fy = (L + 16) / 116
41    fx = a / 500 + fy
42    fz = fy - b / 200
43    
44    xyz_n = f_lab_inv(np.array([fx, fy, fz]))
45    xyz = xyz_n * white
46    
47    return xyz[0], xyz[1], xyz[2]

Go

 1package color
 2
 3import "math"
 4
 5type LAB struct {
 6    L, A, B float64
 7}
 8
 9var (
10    // D65 reference white
11    XN = 95.047
12    YN = 100.0
13    ZN = 108.883
14    
15    delta     = 6.0 / 29.0
16    deltaCube = delta * delta * delta
17)
18
19func fLab(t float64) float64 {
20    if t > deltaCube {
21        return math.Cbrt(t)
22    }
23    return t/(3*delta*delta) + 4.0/29.0
24}
25
26func fLabInv(t float64) float64 {
27    if t > delta {
28        return t * t * t
29    }
30    return 3 * delta * delta * (t - 4.0/29.0)
31}
32
33func XYZToLAB(xyz XYZ) LAB {
34    fx := fLab(xyz.X / XN)
35    fy := fLab(xyz.Y / YN)
36    fz := fLab(xyz.Z / ZN)
37    
38    return LAB{
39        L: 116*fy - 16,
40        A: 500 * (fx - fy),
41        B: 200 * (fy - fz),
42    }
43}
44
45func LABToXYZ(lab LAB) XYZ {
46    fy := (lab.L + 16) / 116
47    fx := lab.A/500 + fy
48    fz := fy - lab.B/200
49    
50    return XYZ{
51        X: XN * fLabInv(fx),
52        Y: YN * fLabInv(fy),
53        Z: ZN * fLabInv(fz),
54    }
55}

Color Difference (Delta E)

Delta E 1976 (CIE76)

The simplest color difference formula:

$$ \Delta E_{76} = \sqrt{(L_2^* - L_1^)^2 + (a_2^ - a_1^)^2 + (b_2^ - b_1^*)^2} $$

1def delta_e_76(lab1, lab2):
2    """Calculate Delta E 1976"""
3    return np.sqrt(
4        (lab2[0] - lab1[0])**2 +
5        (lab2[1] - lab1[1])**2 +
6        (lab2[2] - lab1[2])**2
7    )

Interpretation

  • $\Delta E < 1$: Not perceptible by human eyes
  • $1 < \Delta E < 2$: Perceptible through close observation
  • $2 < \Delta E < 10$: Perceptible at a glance
  • $\Delta E > 10$: Colors are more different than similar

Note: More advanced formulas exist (Delta E 2000, Delta E CMC) that better account for perceptual non-uniformities.


Common Use Cases

  1. Quality control: Comparing manufactured colors to target
  2. Color matching: Finding similar colors
  3. Image processing: Perceptually uniform adjustments
  4. Color grading: Professional color correction

Key Properties

  • Perceptually uniform: Equal distances ≈ equal perceived differences
  • Device-independent: Based on XYZ
  • Cylindrical variant: LCH (Lightness, Chroma, Hue) uses polar coordinates

Further Reading

Related Snippets