PIH Harmonize
Make Your Cutouts Stop Looking Pasted On
- Background Image
- Foreground Image
- PIH Processor
- mask
- IMAGE
You cut out the dog, dropped it on a beach, and everyone can tell. The subject is lit for one room, the background for another, and no amount of honest masking fixes it. That gap between "cut out" and "looks like it was shot there" is exactly what PIH Harmonize exists to close.
This is a ComfyUI port of Semi-supervised Parametric Real-world Image Harmonization, a CVPR 2023 paper from Adobe Research. Feed it a background, a foreground cutout, and it adjusts the foreground's color, tone, and shading so the composite reads as one photo instead of two images glued together. It's a classic research model wearing a small custom-node skin, and for a narrow job it's still quietly the right tool.
Why not just relight it with diffusion?
Most people reach for IC-Light or an instruction editor (Qwen, Flux Klein) to solve this, and those are great - right up until they're not. Diffusion re-emits the whole frame, so texture gets smeared and the subject's details come back "close but not identical." That's a real complaint in the wild: people chasing photorealistic compositing keep hitting the over-smoothed, plastic look. PIH takes the opposite approach. It doesn't regenerate anything. It only re-colors the pixels you already have, so the dog stays the dog - same geometry, same fur detail, just lit like it's standing on that beach. That's why a product-catalog workflow that needs consistent, conservative output is the case where PIH wins.
How it works
The model runs a quick prediction pass at 512×512 - the node downscales your composite and mask for it - and learns a set of parametric adjustments: brightness, contrast, and saturation curves plus a 3D LUT, computed from the background's appearance. Then it re-applies those adjustments at full resolution through a per-pixel gain map, masked so only the foreground region changes. Nothing generative, nothing hallucinated, just an informed color grade. It's fast enough to feel interactive on a GPU.
The inputs that matter
The required set is small and honest:
- Background Image - the scene your subject is going into.
- Foreground Image - the cutout, as RGB or RGBA. If it carries alpha, that alpha is used automatically.
- Strength (0–1, default 1) - blends between your raw composite and the fully harmonized result. Dialing this down is your safety valve when the model gets overzealous with the tone match.
- PIH Processor - the model object from PIH Model Loader; wire it in or the node won't run.
- mask (optional) - a manual MASK to limit harmonization to a region. If you don't provide a mask and your foreground has no alpha, the whole image gets harmonized, which is rarely what you want.
Output is a single IMAGE - wire it to a Preview or Save node. Note the node will silently resize the background to the foreground's resolution if they don't match, so bring them to the same size yourself and skip the surprise.
The one gotcha that bites everyone
The mask convention here is mask = 1 where the foreground is. ComfyUI's built-in LoadImage outputs an inverted mask (1 minus alpha) because it's built for inpainting. Feed that straight in and you'll harmonize the background and leave the subject untouched - it's the classic "why is nothing happening to my dog" moment. Insert an InvertMask between LoadImage and this node and it just works.
Install
Grab it from ComfyUI Manager by searching ComfyUI PIH, or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/chrismyau/ComfyUI-PIH
cd ComfyUI-PIH
pip install -r requirements.txt
Then restart ComfyUI. Dependencies are just Pillow and gdown - the real install step is the model, which the loader handles (see that node's page, because Google Drive downloads have a habit of failing).
The honest caveat: this is an obscure pack with essentially no community footprint, so you're relying on the paper's code rather than a crowd of users. For a deterministic, texture-preserving harmonization pass it's the one I'd reach for - just don't expect a big support community behind it.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| Background Image | IMAGE | — | |
| Foreground Image | IMAGE | — | |
| Strength | FLOAT | 1.000–1 | — |
| PIH Processor | PIH_PROCESSOR | — | |
| maskopt | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |