Smart Color Match (Fixed)
Make your batch match the reference color — without re-sampling
- image_ref
- image_gen
- ignore_mask
- IMAGE
You've nailed the composition, the model, the prompt - and the render comes back with a green skin cast or a washed-out grade. Re-sampling is a lottery, and fiddling with the prompt won't fix a color shift that isn't your prompt's fault. Smart Color Match is the deterministic fix: it takes your generated image and reshapes its color distribution to match a reference image. No sampler, no denoise step, no dice-roll. It's a post-processing node that sits at the tail of your graph - after the VAE decode, before the save - and it runs in seconds instead of a sampling pass.
What it actually does
Under the hood this is a thin wrapper around hahnec's color-matcher, a well-known library for color transfer between images. The idea is simple: compute the color statistics of the reference, then remap the target so its statistics match. The method dropdown is literally that library's six algorithms, and it's the one input you'll actually think about:
mkl(default) - Monge-Kantorovich linearization, a full affine remap of the whole color distribution. The most thorough transfer, and the most likely to overcorrect on a very different reference.reinhard- the classic Reinhard et al. transfer: mean and standard deviation in LAB space. The gentle "white balance plus a nudge" option, and a good starting point for the same reason.hm- per-channel histogram matching. Tends to punch contrast and saturation toward the reference's histogram.mvgd- an analytical multivariate-Gaussian transfer.hm-mvgd-hm/hm-mkl-hm- histogram matching both before and after the Gaussian/linear step. These are the library's flagship compounds, the ones its own README claims outperform the rest.
The feature that makes it interesting
reference_end. If you feed a batch of target images - frames of a video, a sequence of renders - and also provide a second reference via reference_end, the node interpolates the reference gradually from reference to reference_end across the sequence. Frame one gets graded to the start look, the last frame to the end look, and everything in between eases through. Leave reference_end disconnected and it's just standard per-image matching. That's the difference between "a color match node" and "the thing that keeps a scene's tone consistent as it drifts across a video."
Inputs and outputs
The ones you actually set:
- target - the image (or batch) you want corrected.
- reference - the look you're matching toward.
- method - the algorithm above.
- reference_end (optional) - the endpoint for progressive blending across a batch.
- strength - a float, default 1, range 0–10. How much of the correction to apply versus the original. Dial it back when
mklpushes saturation too far; 0.5–0.7 is a common sweet spot. - multithread (default on) - parallelizes across the batch. Leave it on unless you're CPU-starved.
Output is a single image with the same batch size and resolution as the target. Wire it straight into a Save Image node, or into an upscaler if you grade first and scale second.
Installing it
ComfyUI Manager → search ComfyuiSmartColorMatch → Install, then restart. Or clone it by hand:
cd ComfyUI/custom_nodes/
git clone https://github.com/kayorlian/ComfyuiSmartColorMatch
Then restart ComfyUI. No model files to download. The pack's requirements.txt pulls in numpy and opencv-python, but here's the thing to know: SmartColorMatch is built on hahnec's color-matcher, and that library isn't listed in the pack's requirements file. If the node refuses to load with a missing-module error, the fix is one line:
pip install color-matcher
Where people get burned
- The README is stale. It lists methods (
mkl_neutral,reinhard_lab) that don't match the node's actual enum, and its install URL is literally aYOUR_USERNAMEplaceholder. Trust the node, not the README. - The repo moved on. The
developbranch has since been refactored into a different node,SmartColorMatchAdvanced("Smart Color Match (Ultimate VTON)"), with frequency-separation and bounce-light controls. If you clone fresh you may see that instead of this one. The version on this page is the one with the batch-blending feature. - It's global, not local. Statistical color transfer matches overall tone, full stop. If only the background is wrong and the subject is fine, this won't isolate it - that's what a masked variant is for.
Also worth knowing: it's a tiny pack with basically no community footprint. Not a red flag for something this simple - just a niche utility. But it does mean you're on your own with the algorithm math, so test on a single frame before running it across a whole sequence.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image_ref | IMAGE | — | |
| image_gen | IMAGE | — | |
| method | COMBO | 2 options: mkl_neutral, reinhard_lab | |
| blend_factor | FLOAT | 1.000–1 | — |
| ignore_maskopt | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |