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:
-
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.
-
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.
-
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. -
Mallett 2019: Utilizes
colour.XYZ_to_sdimplementation of the Mallett et al. (2019) algorithm. Generates smooth, physically plausible reflectance spectra designed for computer graphics and color management. -
Otsu 2018: Utilizes
colour.XYZ_to_sdimplementation of the Otsu et al. (2018) algorithm. Constructs smooth non-negative spectra optimized for wide-gamut RGB/XYZ inputs. -
Smits 1999: Utilizes
colour.XYZ_to_sdimplementation of Smits' (1999) classical algorithm. Reconstructs spectra using pre-calculated smooth basis curves for primary, secondary, and white colors.
Functions:
-
XYZ_to_xyS–Convert from XYZ to xyS.
-
apply_2d_lut–Apply a 2D lookup table in chromaticity space with barycentric interpolation.
-
build_binned_triangulation–Bins training spectra into grid resolution and creates Delaunay triangulation.
-
get_barycentric_prior–Computes matrix-solved prior spectrum using the binned Delaunay mesh.
-
get_spectrum_lut–Computes or retrieves a cached 2D spectral lookup table.
-
register_method–Decorator to register a new spectral upsampling LUT generator.
-
xyS_to_XYZ–Convert from xyS to XYZ.
-
xy_to_spectrum_nnls–Finds a non-negative spectrum, optionally guided by a barycentric prior.
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:
-
(methodUpsampleMethod | str, default:'SFL upsampling') –Upsampling method registered in the registry.
-
(resolutionint, default:33) –Grid resolution of the chromaticity LUT (resolution x resolution).
-
(illuminantstuple[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.