This is the open source repository for Adaptive Color Grading which will be presented at the 34th Color and Imaging Conference.
The tool consists of the following key classes:
colorEngine splits an image into four tonescale regions — darkest, dark, light,
lightest — each with a tonescale region threshold (TRT) (where the region begins, in relative luminance) and a
falloff (how quickly it blends out). An independent CIELAB a*b*
color offset can be applied to each region. The four region adjustments are composed into a single 3D LUT and applied to
the image, as in standard color grading modules.
The tool is novel in that it can automatically predict TRTs using the adapt class, fitting the 3D LUT to the intensity distribution of each new input image.
Via this mechanism, a set of color offsets can be batch applied to a whole project.
Users can interact with these classes via the nested color grading interface adaCG.py and database manager interface dBadaCG.py. The package also contains an example training dataset from the experiments in the paper, and a number of demo images for users to experiment with.
The associated dataset of RAW HDR videos will be hosted on the HDRVS webpage.
The processed stills and annotations (same as demoProject/trainDemo8b.pkl) used in the experiments for the paper are now available on Hugging Face.
Python 3.12. Direct runtime dependencies:
colour-science— color space conversion and 3D LUTsnumpyscikit-learn—KNeighborsRegressor,StandardScalerPillow— image resizing, thumbnail JPEG encode/decodematplotlib— the histogram and 3D LUT panes indBadaCGtkinter— the UI. Ships with the Python install itself and is not pip-installable. Ifimport tkinterfails, the interpreter was built without Tk.
From your preferred python environment (e.g., miniconda):
conda create -n acg python=3.12conda activate acgpip install -r requirements.txtFor the grading interface with database manager:
python dBadaCG.pyFor the grading interface alone:
python adaCG.pySee classes colorEngine and adapt in adaCG.py for the color grading engine and adaptation model alone, respectively.
- Import. The Project pane's
importbutton adds a directory of images, computing a luminance histogram and a thumbnail for each. - Grade. Select a grade to load it into the editor. Drag on the chroma box to set the
a*b* offset for the region chosen in the dropdown; drag on the tonescale ramp to move
that region's pivot. Set
color offset applies to:tobatchto drive the whole Project selection at once. - Curate.
add,remove,label,filterand visualize training set examples and their grades. - Apply.
apply model to selectedfits the KNN on the Train pane's filtered grades and writes predicted pivots onto the selected Project grades. Only the four pivots change; a*b* offsets and falloffs are left alone. - Save.
save projectwrites the ProjectgradeDict;save modelwrites the TraingradeDict.
Nothing on disk is written except by Save Project, Save Project As, Save Model,
Save Model As, and the image/LUT export commands. Unsaved edits are marked with * in the
title bar and confirmed on quit.
Every component (dBadaCG, adaCG, colorEngine, adapt) communicates through the project dictionary.
{
'root': 'C:/path/to/images', # where the images live
'IMG_0001.tif': { # key: path relative to root
'set': {'darkest': [a, b], 'dark': [a, b], 'light': [a, b], 'lightest': [a, b]},
'reg': {'darkest': [pivot, falloff], ...},
'hist': np.ndarray, # luminance histogram, the adapt input feature
'thumb': np.ndarray, # JPEG byte stream, decoded on demand
'labels': ['subsetA', ...], # free-form tags, filterable
'time': datetime,
},
...
}Project and Train files use the same layout, so any project pickle can be imported as a train set and vice versa.
Under the Settings menu:
- histogram bit depth — bin count for the
adaptinput feature. Default 8-bit (256). - histogram handling —
none,unit,std(default),log,cdf. - Rehistogram Project — recomputes every project histogram at the current settings.
Needed after a bit depth change, since
adaptrefuses to mix bin counts. - adapt neighbors — k for the KNN. Default 16.
Preview resolution is fixed at one sixth of the screen width, set by previewDiv in
dBadaCGapp.__init__. It is not exposed in the menu because changing it forces a full
re-read of the project; the menu entry is left commented out next to the Settings build.
@inproceedings{acg,
title={Adaptive Color Grading},
author={Canham, Trevor and Punnappurath, Abhijith and Brown, Michael},
booktitle={Color and Imaging Conference},
year={2026}
}