Mpi Inpaint Heal
Your inpaint fill looks off? Heal the colour drift after the fact
- image
- mask
- IMAGE
You know the tell. You regenerate an object out of a photo - a person, a lamp, a car - and the seam where the AI's fill meets the real image just won't hide. The fill's colours wander away from the surrounding pixels, and its texture lands noticeably smoother than the real thing. On foliage nobody notices; on skin it's a billboard. Mpi Inpaint Heal exists to fix exactly that, after the fact, by matching the filled region back to the untouched pixels that hug it.
The mechanism is the interesting part, because it's deliberately not what most people try first. It takes your stitched image and the mask of the region that was regenerated, then builds a ring around that mask - a band of untouched pixels (ring_px, default 31 pixels wide) sampled as the reference. Then it does two corrections. color_strength shifts the fill's average colour toward the ring's average colour, killing the drift. grain_strength is cleverer: instead of pasting texture in, it looks at the fill's own high-frequency detail, measures how much quieter it is than the ring's, and amplifies it up to match. No donor patches, no invented texture - it just turns the fill's existing grain up to the right volume. Finally feather_px (default 15) softens the correction's own edge so you don't trade one seam for a sharper one. Everything clamps to 0–1, and it's safe to run on batches.
That "ring, not a rectangle" choice is the core design bet, and the author is explicit about it: a colour-match done on a rectangular crop still contains the removed object, so it pulls the fill toward the thing you just deleted. A ring hugging the mask never does. It also means the input ordering matters - run it after stitching, with the mask of the region that was regenerated. Heal before you stitch and you're polishing a fill that's about to be composited over anyway.
Inputs and outputs are small enough to list: image and mask in, one IMAGE out. The four knobs all have sane defaults, so the 80% case is "wire it up, leave the sliders alone." Where people get burned:
- The ring needs real pixels to reference. A mask that runs right to the image edge has a thin or empty ring, so the correction has nothing to average - keep
ring_pxsmaller than the distance from your fill to the border, or extend the canvas first. - Don't crank
color_strengthto fix a grain problem. The two sliders are independent; set whichever to 0 to disable it. Crank both to 1 and you may over-correct a fill that was already close. - If a seam still shows, bump
feather_px, notring_px- the feather is what decides whether the correction blends or reads as a new line.
Installing: ComfyUI Manager, search "ComfyUi-MpiNodes", install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/MadPonyInteractive/ComfyUi-MpiNodes
No model downloads, no pip dependencies - this is pure tensor math from the Mad Pony Interactive pack (the same crew behind Cubric Vision). It won't rescue a genuinely bad regen, but for the classic "good fill, wrong colour, too-smooth texture" case it's usually the last node you add before the image looks native.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| color_strength | FLOAT | 1.000–1 | Shift the filled region's colour toward the surrounding ring. 0 disables. |
| grain_strength | FLOAT | 1.000–1 | Lift the filled region's fine grain toward the surrounding ring. 0 disables. |
| ring_px | INT | 311–512 | Width of the untouched band sampled as the reference. Wide enough for a stable average, narrow enough to stay locally lit. |
| feather_px | INT | 150–256 | Softens the correction's edge so it does not become a visible seam of its own. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |