Clothing Color Correction
Your Face Swap Fixed the Face and Broke the Jacket — Fix It Here
- original_image
- clothing_mask
- output_image
- output_mask
- IMAGE
If you've run Reactor, ACE++, or any pixel-level face swap on someone in a colored shirt, you've seen this: the face lands perfectly, and the jacket is suddenly a slightly different shade. Too warm, too desaturated, off by just enough that you can't unsee it. This node exists for exactly that one problem.
Face swap nodes are post-process pastes, not re-renders. The swapped face brings its own skin tone and lighting with it, and that bleeds into everything around it - most visibly the clothing. The fix most people reach for is re-sampling the whole image and hoping, which is slow and can drift other details. Clothing Color Correction is the surgical option: it re-applies the original clothing color onto the swapped output, only inside the clothes.
How it works
The node takes two image/mask pairs: your original_image with a mask of its clothing, and your face-swapped output_image with a mask of its clothing. Then three things happen:
- It computes the mean and standard deviation of each channel inside the masked clothing region of both images.
- It scores the difference - roughly 70% mean distance, 30% standard-deviation distance, normalized to 0–1.
- If that score beats your color_threshold, it runs a color transfer and composites the result back in. Below the threshold, it does nothing and hands the output back untouched. That's a feature, not a bug: no pointless churn when the swap already preserved the colors.
Three methods are available, and they're the classic color transfer trio:
- lab_transfer (the default) - matches statistics in LAB space, which tracks human perception better than RGB.
- statistical - the classic per-channel mean/std transfer.
- histogram - histogram matching in HSV, with special handling for hue being a circular channel.
strength (default 0.8) blends between your original output and the fully-corrected version; 0 is no change, 1 is a full transfer. preserve_luminosity (on by default) keeps brightness exactly where it was and only fixes hue/saturation - leave it on. The only output is a single corrected IMAGE, which you wire straight into your Save Image or the next compositing step.
The inputs that actually matter
You'll set all four image/mask inputs, but two deserve real attention:
- clothing_mask / output_mask - these decide what gets corrected, and they're where people burn the most time. You need a clothing mask for the original and a separate one for the swapped output; the node binarizes masks at 0.5, so soft edge masks get hard edges. Pose changed between images? Then the masks have to differ too. SAM, BIRefNet, or manual masking all work.
- color_threshold (default 0.15) - the trip wire. Crank it and nothing ever fires; that's the most common "is this node broken?" report, and the answer is usually "your threshold is too high."
Installing it
ComfyUI Manager (search "Clothing Color Correction" or "ColorCorrection") will handle it, or the manual way:
cd ComfyUI/custom_nodes
git clone https://github.com/zaheenrahman/ComfyUI-ColorCorrection
# restart ComfyUI
The requirements are numpy, opencv-python, torch, pillow - you already have torch and numpy, and OpenCV is installed by half the ecosystem. No model downloads, no heavyweight deps. One small trap: the README's own clone command uses a placeholder URL (yourusername) and a different folder name, so copy the command above rather than the one in the repo if the README trips you up.
Troubleshooting
- Nothing changes → check threshold, then check that both masks actually cover the clothing and aren't empty. If the swap already matched colors, the node legitimately does nothing.
- Splotchy, oversaturated result → strength at 1.0 with a hard-edged mask gets waxy. Back off to 0.6–0.8.
- Flattened shading/texture → that's
preserve_luminositybeing off. Turn it back on.
It's a niche node, but it's the right tool for a genuinely common failure - and it costs you nothing but a clone and two masks.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| original_image | IMAGE | — | |
| clothing_mask | MASK | — | |
| output_image | IMAGE | — | |
| output_mask | MASK | — | |
| color_threshold | FLOAT | 0.150.01–1 | — |
| strength | FLOAT | 0.800–1 | — |
| preserve_luminosity | BOOLEAN | true | — |
| method | COMBO | lab_transfer | 3 options: statistical, histogram, lab_transfer |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |