Skip to content

XY LUT

xy_lut

2D LUT application in chromaticity space using barycentric interpolation and spectral upsampling.

This module provides tools for transforming trichromatic colors (XYZ / xyS) into high-dimensional spectral distributions across targeted wavelength bins, applying high-performance 2D lookup tables in normalized chromaticity space, and caching generated lookup tables on demand.

Supported Spectral Upsampling Algorithms:

  1. SFL upsampling: A custom hybrid method combining empirical spectral data with constrained optimization. It builds a 2D Delaunay triangulation mesh in chromaticity space from training spectra (RawToACES dataset multiplied across 12 standard illuminants) to derive a barycentric prior spectrum, which is then refined using Non-Negative Least Squares (NNLS) with smoothness and data regularizers.

  2. Pure NNLS Optimization: Reconstructs spectra by solving a non-negative least-squares problem matching target XYZ values, constrained purely by a 1D first-derivative smoothness loss penalty without relying on dataset priors.

  3. Simple Matrix: A fast linear least-squares model (XYZ -> Spectrum) fitted to D65-illuminated spectral datasets. Reconstructed spectra are clamped to non-negative bounds and re-normalized to unit chromaticity sum S.

  4. Mallett 2019: Utilizes colour.XYZ_to_sd implementation of the Mallett et al. (2019) algorithm. Generates smooth, physically plausible reflectance spectra designed for computer graphics and color management.

  5. Otsu 2018: Utilizes colour.XYZ_to_sd implementation of the Otsu et al. (2018) algorithm. Constructs smooth non-negative spectra optimized for wide-gamut RGB/XYZ inputs.

  6. Smits 1999: Utilizes colour.XYZ_to_sd implementation of Smits' (1999) classical algorithm. Reconstructs spectra using pre-calculated smooth basis curves for primary, secondary, and white colors.

Functions:

XYZ_to_xyS

XYZ_to_xyS(XYZ: ndarray) -> ndarray

Convert from XYZ to xyS.

apply_2d_lut

apply_2d_lut(image: ndarray, lut: ndarray) -> ndarray

Apply a 2D lookup table in chromaticity space with barycentric interpolation.

build_binned_triangulation

build_binned_triangulation(
    all_xy: ndarray, all_spectra_norm: ndarray, grid_res: int
) -> tuple[Delaunay, ndarray]

Bins training spectra into grid resolution and creates Delaunay triangulation.

get_barycentric_prior

get_barycentric_prior(
    xy: tuple[float, float],
    triangulation: Delaunay,
    reduced_spectra: ndarray,
    cmfs: ndarray,
) -> tuple[ndarray | None, bool]

Computes matrix-solved prior spectrum using the binned Delaunay mesh.

get_spectrum_lut cached

get_spectrum_lut(
    method: UpsampleMethod | str = "SFL upsampling",
    resolution: int = 33,
    illuminants: tuple[str, ...] | None = None,
) -> ndarray

Computes or retrieves a cached 2D spectral lookup table.

Parameters:

  • method

    (UpsampleMethod | str, default: 'SFL upsampling' ) –

    Upsampling method registered in the registry.

  • resolution

    (int, default: 33 ) –

    Grid resolution of the chromaticity LUT (resolution x resolution).

  • illuminants

    (tuple[str, ...] | None, default: None ) –

    Tuple of illuminant keys for dataset preparation. If None, defaults to ALL_ILLUMINANT_KEYS.

Returns:

  • ndarray –

    np.ndarray: LUT array of shape (resolution, resolution, n_bins).

register_method

register_method(name: str)

Decorator to register a new spectral upsampling LUT generator.

xyS_to_XYZ

xyS_to_XYZ(xyS: ndarray) -> ndarray

Convert from xyS to XYZ.

xy_to_spectrum_nnls

xy_to_spectrum_nnls(
    xy: tuple[float, float],
    smoothness_loss_factor: float,
    data_loss_factor: float,
    cmfs: ndarray,
    triangulation: Delaunay | None = None,
    reduced_spectra: ndarray | None = None,
) -> ndarray

Finds a non-negative spectrum, optionally guided by a barycentric prior.