mini_color_match
Mask-based color matching that only touches the pixels you point at
- target_image
- ref_image
- target_mask
- ref_mask
- IMAGE
You outpaint an image, and the newly grown sky is clearly a different blue from the original. Or you inpaint a face and the skin tone drifts - that classic "the rest of the image is right, the patch isn't" failure that makes you re-roll the whole generation. The honest fix is a color-match node: it reads the color statistics of one image and transfers them onto another. The problem is that most color-match nodes force the reference to resize and crop to the target's dimensions, and if you're matching a face, that silently repositions everything and the statistics come out wrong.
mini_color_match gets around that by decoupling the sampling. It doesn't stretch or crop either image - it samples pixels from each one in its own original coordinate space, using the masks you feed it. That's the whole trick, and it's why the author built it specifically for outpainting and character skin-tone consistency.
How it works
You give it a target image (the one that needs fixing), a reference image (the one whose colors you want), and optionally a mask for each. It collects the pixels under each mask, computes the color statistics of both sets, and applies a transform to the whole target image. If you connect no masks at all, it switches to full-frame mode and matches the global stats - a quick grade, but you lose the precision that makes this node worth having.
The method dropdown picks the math:
- Linear - scales R, G, B independently (per-channel mean/std transfer). Strongest match, and the one to reach for when you have masks. This is the classic Reinhard-style move the rest of the ecosystem calls "Color Match Image."
- Mean - only shifts the means, preserving the target's contrast. Smoother, less aggressive, great for style references where you don't want contrast overhauled.
- MKL - a full covariance transfer that maps the target's color distribution onto the reference's. Best for unmasked, whole-image matching; it's more forgiving when you don't want to draw masks.
- Wavelet - a blurred-difference correction tuned for identical compositions. If the shot is the same but the white balance is off, this is the one.
strength (0.0–1.0, default 1.0) lerps between the original and the fully corrected image, so you can dial a correction back to 40% instead of committing to the full transfer.
The inputs that matter
The two that make it different from every other match node are the optional target_mask and ref_mask. The workflow the author intends: draw a mask over the unchanged region of the original (that's your reference), and another over the outpainted/inpainted region (your target). The node compares only those pixels. The pixel extraction threshold is 0.1 rather than 0.5, so feathered mask edges are captured instead of dropped - that's what makes the transition delicate instead of showing a hard boundary.
You don't have to draw masks by hand either. Feed it a mask from a segmentation node - a skin-tone segment on both the target and a differently-styled reference is a legit way to do style grading, matching just the skin while leaving everything else alone.
Output is a single IMAGE, same dimensions as the target, ready to wire into a VAE decode, a save node, or back into an inpaint-stitch pipeline.
Install
ComfyUI Manager → search "comfyui-mini-nodes" → install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/catmaxzj/comfyui-mini-nodes
Restart ComfyUI. There are no extra dependencies - the pack only uses torch, numpy, and OpenCV, which ComfyUI ships with. No model downloads, nothing.
Common gotchas
- Empty mask → no correction. If the sampled pixels are empty the node just returns the target unchanged. A mask that's all black, or a segmentation mask at the wrong resolution, silently does nothing. (It does auto-resize masks that don't match the image size, so that specific footgun is covered.)
- Method selection is a real choice. Linear on an unmasked full frame over-corrects contrast badly; MKL is the default-for-everything unmasked pick. When it looks "washed," you grabbed the wrong method, not a bug.
- The ref should be the thing you want to match, not the whole world. A full image with wildly different content (new clothing, new pose) will drag the match toward those pixels - that's precisely why the mask inputs exist. Mask what didn't change.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| target_image | IMAGE | — | |
| ref_image | IMAGE | — | |
| method | COMBO | Linear | Linear: 适合遮罩校色,RGB独立缩放,色彩参考最直接 Mean: 适合遮罩校色,平移均值保留原图对比度,风格参考最稳定 MKL: 适合无遮罩,通用全局映射,快捷校色最方便 Wavelet: 适合相同构图矫正偏色,还原参考最自然 |
| strength | FLOAT | 1.000–1 | — |
| target_maskopt | MASK | — | |
| ref_maskopt | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |