Nodes/ComfyUI-UniversalToolkit/Separate Masks (UTK)
ComfyUI Node

Separate Masks (UTK)

Split one mask into its objects and process them one at a time

By whmc76·Created about a year ago·Updated 2 months ago· 72
Separate Masks (UTK)
  • mask
  • masks
size_threshold_width256
size_threshold_height256
modearea
max_poly_points8

Run a segmentation pass with SAM, BiRefNet or rembg and you often end up with one mask full of disconnected blobs - three people in a shot, a product next to its reflection, a handful of stray specks. Core ComfyUI has no "split this into its objects" node, so you're stuck hand-cropping. This node labels the connected components of a mask and emits one mask per object, filtered by size and sorted left to right. If you've ever wanted to inpaint or upscale each subject individually instead of all at once, this is the bridge.

How it works

It's the classic connected-components trick. scipy.ndimage.label finds each continuous region (8-connectivity, so diagonally-touching pixels count as one blob). Every component is measured against your width and height thresholds, and the survivors come out as individual masks stacked into a single batch, ordered by their horizontal centroid. The three modes change what each output mask looks like:

  • area (default) - keeps the exact shape of each component, warts and all.
  • box - a rectangular bounding box around each component. Perfect when you're going to feed a region to a crop-then-refine loop.
  • convex_polygons - a simplified convex hull approximation, controlled by max_poly_points. Great for feeding a polygon into a detailer or a mask-to-anything node.

The implementation is ported from kjnodes' mask logic, which is a decent pedigree for this kind of thing.

The inputs that matter

  • mask - the MASK input you want split.
  • size_threshold_width / size_threshold_height (both default 256) - minimum dimensions a component needs to survive. This is your noise filter: tiny specks vanish automatically. Note it's an AND condition - a component must clear both.
  • mode - area, box, or convex_polygons.
  • max_poly_points (3–32, default 8) - only used by convex_polygons, caps how many points the polygon approximation can have.

One output, masks, which is a batch. If you need each object on its own wire, pair it with a batch-split node.

Installing it

Same shared install as everything in this pack - ComfyUI Manager, search "ComfyUI-UniversalToolkit", install and restart, or:

cd ComfyUI/custom_nodes
git clone https://github.com/whmc76/ComfyUI-UniversalToolkit
pip install -r requirements.txt

Where people get burned

  • Vanishing regions. Components below either threshold are dropped silently. If your mask "lost" an object, that's why - lower the thresholds.
  • Missing deps. This node needs scipy (for labeling) and opencv-python (for the box/polygon modes). Both are in the pack's requirements.txt, but if you skipped pip install -r requirements.txt you'll get an explicit error telling you to install scipy. OpenCV only errors when you actually pick box or convex_polygons.
  • The empty case isn't an error. If nothing survives the thresholds, you get a single all-zero mask back, not a zero-length batch. Know that before you wire it into a loop that assumes output.

For multi-subject workflows it turns "one giant mask" into "n individual problems," and it's the cheapest way to do per-object cleanup you'll find.

CategoryUniversalToolkit/Mask

Inputs (5)

NameTypeDefaultDescription
maskMASKInput mask to separate into components
size_threshold_widthINT2560–4096Minimum width for components to be included
size_threshold_heightINT2560–4096Minimum height for components to be included
modeCOMBOareaMethod for creating separated masks
max_poly_pointsINT83–32Maximum points for polygon approximation (convex_polygons mode)

Outputs (1)

NameTypeDescription
masksMASK