Mask Filter
Keep only the mask blobs worth keeping
- masks
- MASK
Every automatic segmentation run - SAM, a detector, a background remover - returns noise along with the signal: a mask batch full of tiny specks and stray blobs that you absolutely do not want sent to the sampler. MaskFilter is the bouncer. It takes a batch of masks, looks at the pixel area of each connected component inside, and keeps only the ones that pass your size threshold. One MASK comes out the other side with the junk removed.
The mechanism is clean: it labels connected regions with scipy.ndimage.label, sums the pixels in each blob, and drops blobs that fail the size test. That's the important bit - it filters per blob, not per whole mask, so a single mask with one big region and a field of dust loses the dust and keeps the region.
Three inputs do the deciding:
area_x(default 3000) - the primary area threshold.area_y(default 5000) - the upper bound, only used in "between" mode.keep- the mode dropdown:above_x(keep blobs ≥ area_x),bellow_x(keep blobs ≤ area_x), orbetween_x_y(keep blobs between the two).
Heads-up on the dropdown: it's spelled bellow_x, with two L's. That's the actual value in the code, not a typo in your workflow - don't go hunting for a correctly-spelled option.
Pair it with the pack's MaskProcessor for the classic cleanup chain: filter out the specks, then dilate and feather what's left so it composites cleanly. If you're running regional prompting or inpainting, this is the step that stops "why is there a weird tiny region over there" - because that weird tiny region is a sub-threshold blob you never meant to keep. It also works on a single mask, where it'll happily strip lone stray pixels from an otherwise clean selection.
Install via ComfyUI Manager (search "WtlNodes") or:
cd ComfyUI/custom_nodes
git clone https://github.com/Scorpiosis0/ComfyUI-WtlNodes.git
then restart ComfyUI. Dependencies: numpy, scipy, pillow - scipy is the real engine here, and it's already in the pack's requirements. No models to download.
Same apply_type warning as the rest of the pack: none and apply_all pause the workflow and wait for an Apply/Skip click in the browser, so if you run headless, stick to auto_apply. The live preview is RAM-only and shows you exactly which blobs survived before you commit - which is the whole reason to use this over writing a filter loop yourself.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| masks | MASK | — | |
| area_x | INT | 30000–10000000 | — |
| area_y | INT | 50000–10000000 | — |
| keep | COMBO | 3 options: above_x, bellow_x, between_x_y | |
| apply_type | COMBO | 3 options: none, auto_apply, apply_all |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | — |