Nodes/ComfyUI 1hewNodes/Image Color Match
ComfyUI Node

Image Color Match

Stop re-rolling generations because the colors are off

By 1hew·Created about a year ago·Updated 2 days ago· 33
Image Color Match
  • source_image
  • reference_image
  • image
methodmkl

What it's for

Color match is the most underrated node in the whole post-processing layer, and this is the pack's take on it: give it a source image and a reference, and it moves the source's palette toward the reference's statistics.

The KB puts the case for it better than any node page can - it's the honest alternative to re-rolling a generation because the colors are off, and it's the correct fix for three jobs people keep doing by hand: making an outpainted or inpainted region agree with the original, making an upscaled tile or a stitched frame match its neighbours, and making a composited subject sit in a new background's light. That last one is why every video workflow with a color-shift problem ends up with a color-match node bolted on the end - in the corpus, that's the standard answer to "why does my video drift in color after frame 81". A statistics transfer is deterministic and instant; a re-gen is neither.

It's also worth having for the Flux 2-era annoyance the KB's troubleshooting doc flags: edits that come back warmer/yellow. Color-match against the source and it's gone.

How it works

source_image gets recolored to reference_image. Three things are true of the implementation.

Eight methods, two families. wavelet and adain run natively in the node (PyTorch, ported from Easy-Use's colorfix.py). Everything else - mkl, hm, reinhard, mvgd, and the hybrids hm-mvgd-hm / hm-mkl-hm - is delegated to the third-party color-matcher package, exactly the way Easy-Use's easy imageColorMatch always did it.

What the methods actually do. wavelet decomposes both images into five levels of frequency, keeps the source's high-frequency detail and transplants the reference's low-frequency color - that's the one to use when you want the content untouched and only the grade to move, which is the outpaint case. adain is adaptive instance normalization: normalize the content by its own mean/std, rescale by the style's. Of the package methods, reinhard is the 2001 classic (Lab statistics, gentle, hard to make ugly), mkl is Monge-Kantorovich linear transfer and is the node's default, hm is histogram matching, mvgd is a multivariate Gaussian transplant, and the hyphenated ones chain them (hm first, then the middle method, then hm again). Start at mkl; if it's too aggressive on faces, drop to reinhard or wavelet.

Batching cycles. For each source frame i it uses reference[i % ref_count] - so one reference recolors a whole batch, an equal-sized reference batch matches frame for frame, a smaller one repeats, a bigger one gets truncated. Alpha is split off before any of this and re-attached untouched, so RGBA survives. The transfer itself happens on CPU, so long video batches are serial work.

Inputs and outputs

Two IMAGE inputs with tooltips that say exactly what you'd hope - source_image "Image that will be recolored", reference_image "Reference image whose colors are transferred" - plus the method combo. One output: image.

Wiring that matters: the reference should be the thing whose light you want, not just something pretty. Matching an outpaint to the pre-outpaint image, a tile to its neighbour, a subject to its new backdrop's plate. If you feed a reference from a completely different scene, you get a full palette swap and it will look like a filter, because it is one.

Install

ComfyUI Manager → search 1hewNodes, or clone it:

cd ComfyUI/custom_nodes
git clone https://github.com/1hew/ComfyUI-1hewNodes

Restart. color-matcher>=0.6.0 is in the pack's requirements.txt, so a normal install has it. If you installed the pack earlier and only just noticed this node, that one package is the whole story:

python -m pip install color-matcher

Common issues

"Image Color Match methods 'mkl', 'hm', 'reinhard', 'mvgd', 'hm-mvgd-hm' and 'hm-mkl-hm' require the 'color-matcher' package." That's the node's own error, and it means exactly what it says. Note that wavelet and adain still work without the package - they're native - so if pip is broken in your environment you can keep working with those two.

The colors move but the mood doesn't. You matched to a reference whose statistics are dominated by something you didn't intend - a dark corner, a sky. Crop the reference, or pick a frame from the same scene.

It looks plasticky or posterized after hm. Histogram matching is the most literal of the methods: it forces your histogram onto the reference's, which can crush gradients. wavelet is the more conservative option for anything with smooth tonal transitions, like skin or a sky.

Video batches get slow. It's CPU per frame by design (the node moves the tensors off the GPU before transfer). If you're matching hundreds of frames, do a range-sample first, or accept the wall-clock cost.

Category1hewNodes/color

Inputs (3)

NameTypeDefaultDescription
source_imageIMAGEImage that will be recolored
reference_imageIMAGEReference image whose colors are transferred
methodCOMBOmkl8 options: wavelet, adain, mkl, hm, reinhard, mvgd, +2

Outputs (1)

NameTypeDescription
imageIMAGE