CoLIE LowLight Enhance
Brighten a dark photo without a diffusion pass — CoLIE optimizes per image
- src_img
- res_img
Low-light photos are the classic "fix it in post" problem that post can't fix: push the exposure slider and the noise and color cast come along for the ride. CoLIE takes a completely different approach - it fits a tiny neural network to your specific image and estimates how light is distributed in the scene, then re-brightens accordingly. It's slow, it has no model to download, and for a genuinely dark image it's the difference between a usable photo and a crushed black rectangle.
How it works (the "trains per image" part is not a joke)
CoLIE stands for Fast Context-Based Low-Light Image Enhancement via Neural Implicit Representations (Chobola et al., 2024). Instead of a big pre-trained model, it optimizes a small SIREN - a neural implicit representation, a coordinate network that maps pixel positions to values - from scratch for each image. It takes the V (brightness) channel of your image, downsamples it, and trains the SIREN to reconstruct an illumination map over epochs of Adam optimization. Then it divides the image by that estimated illumination (a Retinex-style trick) to pull out the hidden detail. Because it optimizes per image, it needs no training data and no downloaded weights - the node is fully self-contained.
That's the trade: per-image optimization means every frame you run through it is a mini training run. On a single 256px estimate it's seconds-to-a-minute per frame; run it on a whole video and you'd better have a coffee ready. It does have a proper ComfyUI progress bar, at least.
The inputs that matter
There are nine, but you realistically touch three:
src_img- the dark IMAGE to brighten. Same resolution in, same resolution out, though the optimization runs atdown_res.loss_mean- the target brightness the exposure loss optimizes toward. The author's own note: lower values produce brighter images, and the included workflow uses0.1against a default of0.3. Start at0.1–0.2.down_res- the resolution the illumination estimate is computed at (default256). This is where the speed lives:256is the sweet spot, smaller is faster but chunkier.epochs- training iterations for the SIREN (default100). More epochs = cleaner estimate, but it's linear cost.100is a good default; drop to50when testing on video.
The rest - cxt_window, alpha, beta, gamma, delta - are loss-weighting and context parameters from the paper. Leave them alone unless you enjoy experimentation; alpha/beta/gamma/delta weigh the spatial, smoothness, and exposure losses respectively.
The res_img output is the enhanced IMAGE, same resolution as the input.
Installing it
FM_nodes via ComfyUI Manager (search FM_nodes) or:
cd ComfyUI/custom_nodes
git clone https://github.com/FuouM/FM_nodes
then restart. Requirements are just torch and einops. And that's the whole install - unlike every other node in this pack, there is no model file to download. That alone makes it the easiest node here to get working.
Where people get burned
The dominant failure mode is impatience, not setup. If the result looks flat or the dark areas stay dark, loss_mean is too high and epochs too low - drop loss_mean toward 0.1 and give it more epochs. Also mind the resolution: it processes at down_res and upscales the illumination back to full size, so on a 4K image the per-frame time adds up fast. It's the right tool when you have a handful of precious dark shots, not when you need a batch of a thousand. For those few photos, though, it's quietly excellent - no model, no keys, no diffusion rewrite of your subject.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| src_img | IMAGE | — | |
| down_res | INT | 256 | — |
| epochs | INT | 100 | — |
| cxt_window | INT | 1 | — |
| loss_mean | FLOAT | 0.30 | — |
| alpha | FLOAT | 1.00 | — |
| beta | FLOAT | 20.00 | — |
| gamma | FLOAT | 8.00 | — |
| delta | FLOAT | 5.00 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| res_img | IMAGE | — |