MaskDilateErode PM
The Mask Border Machine — Where Dilate Minus Erode Makes a Seam Feather
- mask
- MASK
If you've ever pasted an AI-generated face onto a photo and stared at the hard edge where the face meets the neck, PM_MaskDilateErode is the node you were missing. It takes a mask and returns the border band of it - the ring of pixels between the mask's shrunken inner edge and its grown outer edge. That band is exactly what you use to feather a composite seam so a face swap doesn't look like a sticker slapped on a picture.
The mechanism, which is refreshingly honest
This is plain image morphology, no AI involved. The source does two OpenCV operations on your mask and subtracts them:
- dilate with a 96×96 kernel - grows the mask outward, one iteration.
- erode with a 48×48 kernel - shrinks the mask inward, one iteration.
Subtracting the eroded mask from the dilated one leaves the band of pixels in between: the outer boundary region of your original mask. In EasyPhoto's pipeline (which this pack ports), that's precisely how the face region's edge is softened before the face is merged back onto the background. In your own workflows, it's the same trick - grow the swap region outward, then blur this band and use it to blend.
The one thing you need to know going in: there are no parameters. The schema is a single mask input, one MASK output. You can't widen or narrow the band, can't change the kernel. The 96/48 sizes are baked in and they're sized for a full-resolution face mask - feed it a tiny 64×64 thumbnail mask and the erosion can swallow the whole thing. If you need a thinner or thicker band, you're better off with ComfyUI's built-in Mask Dilate / Mask Erode nodes and subtracting, or just accepting this node's fixed geometry.
The inputs and outputs that matter
Honestly? All of them, because there's only one of each:
- mask (MASK, required) - the face/region mask you want the border of.
- Output: MASK - the border band, ready to feed a blur, a composite, or a
PM_MaskMerge2Image.
Typical wiring: PM_FaceSkin or PM_RetinaFace produces a face mask → this node extracts the edge band → a blur node softens it → PM_MaskMerge2Image composites the enhanced face over the original using the softened band as the transition. That chain is the heart of why this pack's face results don't have visible seams.
Install
It's part of ComfyUI-Portrait-Maker. ComfyUI Manager (search "Portrait-Maker") or:
cd ComfyUI/custom_nodes
git clone https://github.com/THtianhao/ComfyUI-Portrait-Maker.git
then restart ComfyUI. This specific node only needs opencv-python and numpy (both already in ComfyUI's world), but the pack itself pulls heavy deps - tensorflow, insightface, modelscope - and downloads a stack of models on first launch with no hash verification. Don't interrupt that download; half-written files need manual deletion to retry. And don't panic when the node shows up under the protrait/ category - typo in the pack, everyone lives with it.
One final note: since the output is a binary band, feed it through a Gaussian blur before using it as a blend mask, or your "feathered" seam will be as hard-edged as the one you were trying to fix.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | — |