Mask Refine (Morph)
The mask grower that knows where edges are
- image
- mask
- refined_mask
Mask Refine (Morph) is the edge-aware cousin of the pack's Mask Refine (K-Means). Same goal - grow an under-segmented mask outward to cover the subject's clipped edges - but instead of clustering colors, it grows up to the image's edges and no further. Give it a mask and the image it was made from, and it dilates the mask pixel by pixel, stopping wherever it hits a strong gradient in the image. That's the difference between "grow the mask 50 pixels" and "grow the mask until the subject ends."
That distinction matters in exactly the case that breaks naive dilation. Your segmentation mask clips the subject, so you dilate it 50 pixels to recover the edge - but the background right next to the subject is visually similar, so the growth swallows it. Edge-aware growth hits the actual boundary line between subject and background and stops. For inpainting masks, detailer masks, or any mask that feeds a sampling pass, this is the difference between an invisible fix and a visible artifact.
How it works
The growth is genuinely iterative - one pixel at a time, up to grow_pixels total - and it has three modes selected by your settings:
- Edge detection (default, on) - computes a Sobel gradient of the image, normalizes it, and refuses to grow across any pixel whose edge strength exceeds
edge_threshold. Lower threshold = more sensitive = the mask stops sooner. This is the "stop at the subject's outline" mode - Color-aware - if
color_thresholdis above 0, it instead compares each candidate pixel's color against the mask's average color and stops growing when the difference exceeds the threshold. That's the mode for subjects that blend into similar-colored backgrounds where edge detection is useless or over-aggressive - Pure dilation - both off (edge detection disabled,
color_threshold0) and it's just a plain morphological growth
After growth, it applies a closing pass and a Gaussian blur (smooth_pixels, which the tooltip correctly calls "sigma") to soften the boundary. The output is a binary mask, thresholded at 0.5.
Inputs and outputs
- image and mask - the picture and the mask to refine
- grow_pixels - 0 to 200, default 50. The growth budget
- smooth_pixels - 0 to 20, default 3. Edge smoothing (sigma)
- edge_threshold - 0 to 1, default 0.3. Lower = more sensitive edge detection
- use_edge_detection - on/off, default on. Flip off for similar-color subjects
- color_threshold - 0 to 1, default 0. When above 0, switches to color-aware mode
Output: refined_mask, a MASK.
Installing it
With the rest of the XJNodes pack. ComfyUI Manager → search "ComfyUI-XJNodes" → install → restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/alexjx/ComfyUI-XJNodes
# restart ComfyUI
Needs scipy for the morphological ops (present in most ComfyUI installs; pip install scipy if not). Category: XJNodes/segs.
Choosing between the two refine nodes
K-Means and Morph solve the same problem with different eyes, and the pick comes down to your subject. K-Means is better when the subject has distinctive color - it'll follow a bright jacket across subtle background texture. Morph's edge detection is better when the subject is defined by boundaries - a person against a busy, similar-tone background - and its tooltips themselves point you at the swap: "disable for similar colors or when edge detection is too aggressive," and use color_threshold instead. Also worth noting: the color-aware path in Morph uses a normalized color distance, and both nodes print progress info to the console, which is annoying until it saves you. If you're feeding this into a detailer or inpaint pipeline, keep the mask grow modest and check the result visually - these tools over-grow fast, and a mask that's 200 pixels past the subject is a mask that's painting over the background.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| grow_pixels | INT | 500–200 | Number of pixels to dilate/grow. Use with edge_threshold and color_threshold to control growth. |
| smooth_pixels | INT | 30–20 | Sigma for Gaussian smoothing. Higher values create smoother but less detailed edges. |
| edge_threshold | FLOAT | 0.300–1 | Threshold for edge-based refinement (0-1). Lower values are more sensitive to edges. Use with use_edge_detection to control growth at edges. |
| use_edge_detection | BOOLEAN | true | Whether to use edge detection to limit growth. Disable for similar colors or when edge detection is too aggressive. |
| color_threshold | FLOAT | 0.000–1 | If > 0, stop growth when pixel color differs from mask average by more than this threshold (0-1). Use instead of edge detection for similar colors. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| refined_mask | MASK | — |