SEGs to Mask
Turn SAM3's SEGS output into masks you can actually filter and use
- segs
- combined_mask
- individual_masks
- labels_info
- seg_count
SEGs to Mask is the node that makes SAM3 segmentation actually useful instead of a preview you stare at. SAM3 and Impact Pack's detector nodes output a thing called SEGS - a bundle that carries the segmentation image size, per-segment cropped masks, where each crop sits in the full image, a label, and a confidence score. That's a rich format, but ComfyUI's image-processing nodes want plain masks. This node converts SEGS to masks - and it's the conversion with opinions, letting you filter, sort, and merge along the way.
The killer feature is that it doesn't just dump all segments into one mask. It lets you say "only the people," or "only segments I'm at least 70% sure about," or "drop the tiny specks," and get back a combined mask plus a per-label list.
The inputs that matter
segs(SEGS) - from a SAM3 segmentation node or Impact-style SEGS detector.label_filter(STRING, default*) - wildcard on the segment label.person_*grabs all persons,*_0grabs the first instance of every class,dogmatches exactly.min_confidence(FLOAT, 0–1) - drop segments below this score.min_area_percent(FLOAT, 0–100) - drop masks smaller than this % of the whole image. 5.0 means "must cover 5% of the frame."sort_order(default/x_then_y/y_then_x/confidence_high_to_low) - deterministic ordering of the output masks.union_same_labels(BOOLEAN, default true) - merge every segment with the same label into one mask.invert(BOOLEAN) - flip the result.
Outputs: combined_mask (MASK, the union), individual_masks (list of MASK), labels_info (list of strings like "person_0: 0.95"), and seg_count (INT).
How it works
Each SEG carries a cropped_mask and a crop_region - the box in the full image where that mask belongs. The node builds a full-size zero tensor and splices each cropped mask into place, clamping coordinates to the image bounds. With union_same_labels on (the default), all segments sharing a label get OR'd into one mask, and the label's reported confidence is the max of the group. That's the behavior the README highlights: three person_0 segments become one person_0 mask.
It's defensive about input - None masks, wrong-shaped tensors, and numpy-vs-tensor confidence values (Impact Pack gives you numpy arrays, TBG SAM3 gives floats) are all handled rather than crashed on.
Where it fits
The flagship workflow is SAM3 → SEGs to Mask → mask-based processing:
TBG SAM3 Segmentation
→ SEGs to Mask (label_filter: "person_*", min_confidence: 0.7)
→ combined_mask → inpaint/composite/conditioning
→ individual_masks → per-person processing
You can also chain the masks into Mask to BBox to get boxes back out - the pack explicitly supports round-tripping.
Installing it
Part of ComfyUI-JK-TextTools: Manager search "JK-TextTools", or
cd ComfyUI/custom_nodes
git clone https://github.com/Nakamura2828/ComfyUI-JK-TextTools.git
Restart ComfyUI. The pack itself downloads no models and adds no heavy deps - but remember the segs input comes from a segmentation node that does need a SAM3 model and a HuggingFace access approval if you're using SAM3 specifically.
Gotchas
The min_area_percent is a percentage of the whole image, not of the segment's own box - easy to misjudge at first. And union_same_labels defaults to on, which is right for "all people in one mask" but wrong when you wanted per-instance masks; flip it off to get one mask per segment instead of one per label.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| segs | SEGS | — | |
| label_filteropt | STRING | * | — |
| min_confidenceopt | FLOAT | 0.000–1 | — |
| min_area_percentopt | FLOAT | 0.00–100 | — |
| sort_orderopt | COMBO | default | 4 options: default, x_then_y, y_then_x, confidence_high_to_low |
| union_same_labelsopt | BOOLEAN | true | — |
| invertopt | BOOLEAN | false | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| combined_mask | MASK | — |
| individual_masks | MASK | — |
| labels_info | STRING | — |
| seg_count | INT | — |