Runtime44 Color Match
Make one image wear another image's color grade
- source
- target
- IMAGE
Runtime44 Color Match does one thing and does it cleanly: it takes the color distribution of one image and stamps it onto another. You render a scene and the lighting comes out blue and clinical; you have a reference photo with a warm golden grade; this node makes your render adopt that grade. It's histogram matching - the classic computer-vision trick, no AI involved, no model weights, deterministic.
This is the node to use when your pipeline keeps producing images that are technically fine and aesthetically wrong. Generative restorers and img2img will happily rewrite your image to fix color; histogram matching won't touch the structure at all. It only redistributes color. That makes it the boring, reliable choice for unifying a batch of renders to one look, or for pulling a generated image toward the palette of a real photograph.
How it works
The mechanism is match_histograms from scikit-image: it takes each color channel of the target image and reshapes its histogram to match the source's. If the source is warm, your render gets warm; if the source has crushed blacks, yours do too. On a CUDA machine it runs through cucim (the CuPy GPU build of scikit-image); on CPU it falls back to plain numpy + scikit-image, so it works everywhere, just slower on big images.
The one thing that trips everyone up
The input order. This node has two inputs, source and target, and getting them backwards is the whole failure mode:
- source - the image whose colors you want. The reference, the grade, the vibe.
- target - the image that gets recolored. The thing you're fixing.
The output is a single IMAGE - your target's structure, your source's color distribution. Flip them and you'll "fix" the reference photo instead of your render, which is confusing for a solid ten minutes.
Using it
Wire it anywhere you have two IMAGE inputs already: after a VAE Decode, before a save, or mid-pipeline to re-grade an intermediate result. It's a pixel-space operation, so it slots in as a post-processing step and doesn't care about latents or samplers.
A couple of realistic notes. It's a global match - it can't transfer lighting direction or shadow placement, only color statistics. If your source and target have wildly different brightness ranges, expect a moodier or flatter result than you hoped. And because it matches per channel, it has no sense of "skin tones should stay skin tones"; for human subjects you may prefer a more conservative grade (maybe feed it a slightly desaturated source) so faces don't pick up a weird cast.
Installing
It ships in the Runtime44 ComfyUI Nodes pack:
cd ComfyUI/custom_nodes
git clone https://github.com/runtime44/comfyui_r44_nodes
cd comfyui_r44_nodes
python -m pip install -r requirements.txt # or: uv pip install -r requirements.txt
Restart ComfyUI, and the node appears under the "image" category. Or search "Runtime44" in ComfyUI Manager and install it from there - same result.
One thing to know: the pack's requirements file pulls the heavy CUDA wheels (cupy-cuda12x, cucim) even though this node degrades gracefully to CPU. On a CPU-only box the install is still heavy, but the node itself works fine. The pack has been dormant since mid-2024, which is fine here - histogram matching is a settled algorithm, and there's not much to fix.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| source | IMAGE | — | |
| target | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |