Image Harmonization (Multi-Model)
Eight harmonization models in one node — and the one you'll actually use
- composite_image
- mask
- harmonized_image
You cut the subject out, dropped it on a new background, and it's wrong. Not the mask - the cutout itself is clean. It's the light. Your foreground was shot under one sun and the background under another, and every pixel is telling on you. That's the "paste seam" problem, and it's the gap between "cutout" and "composite" in the whole detect → cut → paste workflow.
This node is the fix. Image Harmonization (Multi-Model) re-tints and re-lights only the masked foreground region so it matches its surroundings - no diffusion, no sampler, no seed, fully deterministic. Run it twice and you get the identical image back. It's the classical harmonization lane: a trained CNN transfers color and illumination from background to foreground inside the mask. The diffusion alternative (IC-Light and friends) re-emits the whole frame and can quietly change detail; here only the masked region moves, so the subject's structure stays put. That's the trade you're buying.
How it works
Feed it a composite_image and a mask (white = the foreground region you want harmonized), pick a model_variant, and out comes harmonized_image. Internally it converts to the model's format, downsizes to max_resolution (default 1024) if your image is bigger, runs inference, and upscales back. CDTNet models do a LUT color transform plus an optional refinement pass; the _sim_ variant drops refinement for speed.
The two PCT-Net controls - pctnet_strength (0–2, default 1.0) and pctnet_blend_mode (upstream / mask / attention) - are always visible but ignored unless you pick a PCT-Net model. PCT-Net runs a low-res parameter network at 256px, then applies the color transform at full resolution, which is why it's fast and memory-light. Strength scales those parameters (0.8–1.1 is the useful band), and the blend mode decides how the transform gets fused. CNN attention can come out soft at edges - switch pctnet_blend_mode to mask for sharper edges.
The dropdown, decoded
Eight models is choice paralysis until you read the registry:
- CDTNet_iHarmony4_256 - the balanced default, good quality/speed.
- CDTNet_HAdobe5k_2048 - best quality, but slow and memory-hungry. Save it for the money shot.
- CDTNet_sim_base256 and iSSAM_256 - the fast lane. iSSAM is a lightweight CDTNet.
- Harmonizer / Enhancer - filter-based, EfficientNet backbone, subtle adjustments.
- PCTNet_CNN / PCTNet_ViT - full-res application; tune strength and blend per the above.
My default: CDTNet_iHarmony4_256 for everything under ~1500px, CDTNet_HAdobe5k_2048 when it's a hero image, and the sim model if I'm iterating fast.
Install
ComfyUI Manager (search "comfyui-libcom-image-composition") or the manual route:
cd ComfyUI/custom_nodes/
git clone https://github.com/fuselayer/comfyui-libcom-image-composition
# restart ComfyUI
Nice part: there's no model download. All eight checkpoints are committed in the repo under checkpoints/ - each under 20MB, about 100MB total. Clone, restart, done. The real dependencies (from requirements.txt) are torch, torchvision, numpy, einops, and timm (for the EfficientNet Harmonizer). The README's portable-Python install also lists kornia, albumentations and easydict - kornia and albumentations are what the vendored PCT-Net code actually imports, so install those if you plan on the PCT-Net variants.
Gotchas
- CUDA OOM → lower
max_resolutionor switch to a fast variant. - "Checkpoint not found" → the
.pthfile isn't incheckpoints/; check the filename matches the variant. - PCT-Net looks metallic/dark or checkerboardy → read the console. You want
PCTNet weights loaded perfectly.; aMissing=… Unexpected=…line means the model config and weights disagree. - Soft edges on CNN → use
pctnet_blend_mode="mask".
One honest warning: this pack is young. Single commit, the __init__.py author field is literally "Your Name", and it had zero impressions on comfy.icu when I checked. It works - I ran it - but you're an early adopter, not a customer. Wire the harmonized_image into the pack's HarmonyScore node afterward and let a number confirm the improvement instead of eyeballing it.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| composite_image | IMAGE | — | |
| mask | MASK | — | |
| model_variant | COMBO | 8 options: CDTNet_iHarmony4_256, CDTNet_HAdobe5k_2048, CDTNet_sim_base256, iSSAM_256, Harmonizer, Enhancer, +2 | |
| pctnet_strengthopt | FLOAT | 1.000–2 | — |
| pctnet_blend_modeopt | COMBO | upstream | 3 options: upstream, mask, attention |
| max_resolutionopt | INT | 1024256–4096 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| harmonized_image | IMAGE | — |