Color Match
Match one image's color grade to another
- image_ref
- image_target
- image
You upscaled a frame and it came back slightly warmer than the original. You ran img2img and the palette drifted blue. You stitched two Wan clips together and the color doesn't quite match at the seam. Color Match fixes all of those in one step: hand it a reference image and a target image, and it re-grades the target so its colors match the reference. No manual curves, no eyeballing.
Under the hood it wraps hahnec's color-matcher library, which does statistical color transfer - it reads the color distribution of the reference and warps the target's distribution to match. That's a real technique from the color-grading world, used for film sequences, stop-motion correction, and matching photographs. It's not "make it look nice," it's "make image B's colors look like image A's." That video-seam case is the most common one in the wild, and because it runs inside the graph at generation time, it's part of the pipeline rather than a separate chaiNNer step afterward.
How it works
Every image has a distribution of colors - how much red, how the shadows lean, where the midtones sit. Color Match computes the reference's distribution and remaps the target's pixels so the two line up, using one of several published algorithms. Simple ones like Reinhard shift the mean and variance per channel; MKL (Monge-Kantorovich Linearization) does a smarter linear transfer; the histogram-matching compounds go the whole way. No AI, no model - classical color science, which is why it's fast and repeatable.
The inputs and outputs that matter
Only three required inputs, and getting the first two straight is the whole game:
image_ref- the image whose look you want. The source of the color.image_target- the image that gets changed to match. This is the one that comes out re-graded.
Flip those two and you'll re-color the wrong image. The reference stays untouched; the target is what transforms.
method(defaultmkl) - which algorithm:mkl,hm,reinhard,mvgd,hm-mvgd-hm, orhm-mkl-hm.mklis a solid default. Thehm-compounds (the library's own benchmark favorshm-mvgd-hm) match hardest, at the cost of being more aggressive. If one method overcooks it, try a gentler one - they fail differently and swapping is free.
Two optional knobs: strength (default 1, up to 10) blends between the original and the matched result - drop it below 1 for a partial correction, which is often what you actually want - and multithread (default on) speeds up batch processing.
The single output is image - the re-graded target, ready to save or feed onward.
How to install it
ComfyUI Manager: search KJNodes for ComfyUI, install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/kijai/ComfyUI-KJNodes
pip install -r ComfyUI-KJNodes/requirements.txt
then restart. This node is the one in the pack with a real Python dependency - the color-matcher package, pulled in by that requirements.txt. If you cloned manually, don't skip the pip step or the node won't import.
Common issues & troubleshooting
The node didn't show up. Almost always the color-matcher dependency didn't install. Check your startup terminal for an import error and run the requirements install with ComfyUI's Python (on portable, python_embeded\python.exe -m pip install color-matcher).
The result looks overcorrected. Drop strength below 1 to blend the effect back toward the original, or switch method - the hm- compounds match hardest and can push too far on images with very different content, so try mkl or reinhard for a subtler transfer.
Reference and target are wildly different scenes. Color matching works best when the two share a subject or lighting. Matching a sunset to a snow scene does exactly what you asked and looks strange doing it - that's the math, not a bug. It also can't rescue a shot whose lighting genuinely changed mid-scene; it gets you most of the way, the rest is a manual grade.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image_ref | IMAGE | — | |
| image_target | IMAGE | — | |
| method | COMBO | mkl | 6 options: mkl, hm, reinhard, mvgd, hm-mvgd-hm, hm-mkl-hm |
| strengthopt | FLOAT | 1.000–10 | — |
| multithreadopt | BOOLEAN | true | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |