Nodes/ComfyUI-BadmanNodes/Color Match (Badman)
ComfyUI Node

Color Match (Badman)

Learn a color-drift fix from one pair, apply it to everything

By MariusKM·Created 2 years ago·Updated 3 months ago· 4
Color Match (Badman)
  • image
  • source_ref
  • target_ref
  • source_mask
  • target_mask
  • image_mask
  • image
  • mask
  • preset_path
use_presetfalse
preset_name
methodreinhard
strength1.00
save_as
overwritefalse

The problem this solves is a familiar one if you've done any batch generation or img2img chains: color drifts. Run the same character through a few generations, an upscale, an inpaint pass, or a style transfer, and the palette creeps - skin goes a bit too orange, whites go a bit too warm, and by the tenth image in a batch it's visibly off from the first. Color Match's approach is to learn the correction once, from a single before/after pair, and then reuse it.

How it actually works

You give it a source_ref (the drifted version) and a target_ref (the clean version you want to match) as an optional reference pair. From that pair, the node learns a color transform and applies it to your main image input. Two methods are on offer: reinhard, which matches LAB mean and standard deviation - a gentle, statistically safe correction that tends to generalize well across images with different palettes; and hist, which does full LAB per-channel histogram matching - a much stronger, more literal correction, but one that's tuned to the specific reference pair's palette and can look wrong applied to an image with a genuinely different color range. reinhard is the safer default; reach for hist when drift is bad enough that the gentler option isn't cutting it.

The feature that separates this from a one-off color-match node: you can save the learned transform as a named preset (save_as) and reload it later via use_preset + preset_name, instead of re-supplying the reference pair every time. Build the correction once against your worst-drifted example, save it, and apply it across a whole batch or an entire project without wiring reference images into every single run. It also reportedly runs a live ~180ms preview when you drag strength or swap presets, without re-queueing the workflow - a genuinely nice bit of interactivity for a node this utilitarian.

The inputs that matter

  • image - what gets corrected.
  • use_preset (boolean) - flip on to apply a saved preset instead of a live reference pair.
  • preset_name - which saved preset to use, when use_preset is on.
  • method (reinhard default, or hist) - see above.
  • strength (0–1, default 1) - how much of the correction to apply; dial back if a full-strength match looks overcooked.
  • save_as / overwrite - name and save the transform you just learned as a reusable preset.

Optional: source_ref / target_ref (the reference pair, when not using a preset) and source_mask / target_mask / image_mask (MASK) to restrict where the learning and application happen.

Three outputs: the corrected image, a mask, and preset_path (STRING) - the location of the preset you just saved, if you saved one.

Installing it

ComfyUI Manager: search ComfyUI-BadmanNodes, install, restart. Manual: cd ComfyUI/custom_nodes && git clone https://github.com/MariusKM/ComfyUI-BadmanNodes. No extra dependencies noted - presets get written to disk somewhere under the node's own storage, but that's file I/O, not a model download.

Where people get burned

Method mismatch is the big one, and it matters beyond a single run: if you're building toward this pack's Color Match Combine Presets node to average several saved presets together, they all need to share the same method - mixing a reinhard-learned preset with a hist-learned one won't combine sensibly. Decide on a method before you build out a preset library, not after. Second, a preset learned from one reference pair is only as general as that pair was - a transform learned to fix orange-tinted skin on a portrait can do something bizarre to a landscape shot with no skin tones in it at all, so don't assume a preset generalizes further than the kind of image it was trained on. And if strength at 1 looks like it's overcorrecting, that's usually a sign the reference pair itself had more drift in it than your actual image does - turn strength down before reaching for a different method.

CategoryBadman/color

Inputs (12)

NameTypeDefaultDescription
imageIMAGE
use_presetBOOLEANfalse
preset_nameCOMBO1 options: anti-terracotta
methodCOMBOreinhard2 options: reinhard, hist
strengthFLOAT1.000–1
save_asSTRING
overwriteBOOLEANfalse
source_refoptIMAGE
target_refoptIMAGE
source_maskoptMASK
target_maskoptMASK
image_maskoptMASK

Outputs (3)

NameTypeDescription
imageIMAGE
maskMASK
preset_pathSTRING