Back to blog
October 30, 2024 · 12 min read

Color Science for Developers: Understanding LUTs

A deep dive into color lookup tables, their mathematical foundations, and building a color grading pipeline in Python.

python filmmaking creative

Look Up Tables (LUTs) are fundamental to modern color grading, yet their inner workings remain mysterious to many developers. Let’s demystify them by building a color grading pipeline from scratch.

What is a LUT?

A LUT is essentially a function that maps input colors to output colors. Think of it as a giant lookup table where you can find any RGB input value and see what output value it should become.

The Mathematics

A 3D LUT creates a cubic lattice in color space. Each point in the cube represents a specific RGB combination, and the values stored at that point define the transformation.

import numpy as np

def apply_lut(image, lut, size=33):
    """Apply a 3D LUT to an image."""
    # Normalize to 0-1 range
    normalized = image / 255.0
    
    # Scale to LUT indices
    indices = normalized * (size - 1)
    
    # Trilinear interpolation for smooth results
    return trilinear_interpolate(lut, indices)

Building Cinegrade

This understanding led me to build Cinegrade, an open-source tool that generates custom LUTs based on film stock characteristics. The key insight was treating historical film data as training data for the color transformations.