ProPIH Harmonizer
Make your composite stop looking pasted — ProPIH harmonizes it in stages
- composite
- background
- foreground_mask
- foreground_MASK
- out_0
- out_1
- out_2
- out_3
You know the tell immediately: a foreground cut out of one photo and dropped onto another background, and it's close but the lighting doesn't match - the color temperature's off, the shadows are wrong, the whole thing reads as "pasted." That's a compositing/harmonization problem, and it's exactly what ProPIH is for. Give it your composite, the background it's supposed to live in, and a mask of the pasted region, and it re-grades the foreground so it looks like it was shot in that scene. It's the "make the inpaint result not look like an inpaint result" node.
How it works
ProPIH is Progressive Painterly Image Harmonization from Low-level Styles to High-level Styles (bcmi lab, 2023). "Progressive" is doing real work here: instead of one-shot recoloring, a generator runs four passes that harmonize the foreground at increasing levels of abstraction - starting with low-level style (color, tone, brightness) and moving up to high-level style (texture and structural detail). That's why the node has four image outputs instead of one. The generator is an HRNet-style network backed by a fixed VGG19 that provides the style features to match.
The inputs that matter
composite- the image with the pasted foreground, exactly as it currently looks.background- the scene the composite is being dropped into. ProPIH matches the foreground's style against this.foreground_mask(IMAGE) orforeground_MASK(MASK) - the region to harmonize. Both are optional in the schema, but you must provide one of them; the node raises an error if both are missing. If you pass the MASK variant, use a proper ComfyUI MASK tensor; if you pass the IMAGE variant, it gets converted to grayscale internally.
The four outputs - out_0 through out_3 - are the harmonization at progressive refinement stages, coarsest to finest. Try out_3 first; if the result overshoots (too aggressively re-styled, texture smeared), back off to an earlier output. The progressive design is genuinely useful here: you get a "how strong" dial for free.
Installing it
Same FM_nodes pack routine - ComfyUI Manager (search FM_nodes) or:
cd ComfyUI/custom_nodes
git clone https://github.com/FuouM/FM_nodes
then restart. Requirements are just torch and einops. Two model files are needed, both manual downloads: vgg_normalised.pth (from the ProPIH Installation section) and latest_net_G.pth (from the Train/Test section). Both go in custom_nodes/FM_nodes/models/propih/. Miss either and you'll get a load error on queue - the code loads the VGG weights first, so vgg_normalised.pth missing shows up before anything else.
Where people get burned
The classic stumble is forgetting the mask entirely - the node is explicit about needing one, but since both mask inputs are marked optional, beginners assume neither is required and then hit a hard error. The subtler issue is scale: the paper's generator is built around ~512px processing, so for the smoothest result feed it a reasonably sized composite rather than a giant 4K canvas. And remember what it harmonizes: it fixes lighting and color style, not perspective or geometry - a foreground shot from the wrong angle will still look wrong, just better lit. For the "why does this look photoshopped" problem, though, it's one of the more satisfying single-node fixes in the pack.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| composite | IMAGE | — | |
| background | IMAGE | — | |
| foreground_maskopt | IMAGE | — | |
| foreground_MASKopt | MASK | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| out_0 | IMAGE | — |
| out_1 | IMAGE | — |
| out_2 | IMAGE | — |
| out_3 | IMAGE | — |