Segs Compose (NH)
Build one mask out of labels, not brushes
- segs
- segs_2
- segs_3
- mask
Once a segmentation node has found things, the next thing you always want is a combination of them: the wall without the windows, the people without their hair, everything except the subject. You can write that formula straight into SAM3 Segment's concepts, but you get one mask back, from one run, from one model. Segs Compose works on instances you already have, from up to three nodes at once. One SAM 3 run, many masks.
Where it fits
NH_SEGS is a light description of instances - label, score, box, plus the mask cropped to that box - and ComfyUI's own nodes can't read it. Segs Compose is one of the few ways to turn it into something every node understands: a plain MASK.
It's also the mixer. segs, segs_2 and segs_3 take instances from up to three different vision nodes on the same photo, and the labels from all of them go into one namespace before your formula is read. Bag from SAM 3, dress from Garment Segment, lips from Body Segment, one expression. That's the trick that makes a mixed workflow of three parsers feel like one.
The language
expression defaults to all and takes the same small grammar as the rest of the pack:
| Expression | Result |
|---|---|
| person - hair | the people without their hair |
| ~person | everything except the people |
| background | everything outside every instance in the segs |
| (wall \| ceiling) - window | facade with the openings cut out |
| all - person | everything found except the people |
| face - eyes - eyebrows | Body Segment's face minus Portrait Segment's eyes and eyebrows |
Two traps in that table are worth the words. background is different from ~person - it leaves out every instance that was found, so windows and chairs disappear from the mask too. And all - person differs again: it leaves out the background that nothing found. Pick deliberately.
This node adds a few operators SAM3 Segment doesn't have. or, and and not are operators here (a or b is a | b), * and ? are wildcards on labels (*shirt), and words in a row are still one label - red car needs no quotes, "salt & pepper" does.
check_same_photo (default on) is a guard, not a law. Each batch of segs carries a small grey print of its photo, and the node refuses to mix prints that disagree. Brightness, contrast, colour and blur edits pass. A shifted or zoomed copy can fool it, and a new background behind the same person can trip it - that last case is what the off switch is for.
A node's own words
The genuinely clever bit, and the part that will confuse you the first time: a label first picks instances that literally have it, but when nothing does, the node re-reads the word as one of that node's own group terms. So on Body Segment's segs, skin means the face, torso, arms, hands, legs and feet parts together, mouth means lips plus teeth plus tongue, and clothes covers top, bottom, shoes, socks and accessories. On Portrait Segment's segs, face is skin, nose, glasses, eyes, eyebrows, mouth and lips.
With both of those wired in, face takes the face of both nodes and the eyes and eyebrows come out - the documented face - eyes - eyebrows recipe.
Two limits. The near synonyms Body Segment's regions accepts (dress, pants, neck) are not read here; write top and bottom, or mix in Garment Segment, which labels dresses and skirts for real. And a word that names only part of a part - left hand, upper arm, thigh - finds nothing here, because Body Segment's instances don't carry sides.
Installing it
ComfyUI Manager, search NH-Nodes, install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/NH-Nodes.git
cd NH-Nodes
python -m pip install -r requirements.txt
No models, no downloads - pure compute over instances you already made. The pack wants a recent ComfyUI (tested on 0.41) and Python 3.10+.
Common issues
A typo silently gives you the whole picture. A label no instance has produces an empty part, so ~persn is "everything except nothing" - the entire frame. The console names the label and lists what the segs actually hold; check it before you blame the model.
Spaces around the minus matter. person-hair is one label. If person and hair both exist, the node errors and shows you person - hair, which is the most useful error message in this article.
segs holds fewer instances than you expect. The people nodes return one instance per part for the whole photo - three people give you one hair, not three. Sides and individual people come from SAM3 Segment.
Empty masks from a label that exists. Singular and plural match (arm finds arms), _ counts as a space, case is ignored - but glass and glasses stay separate labels. That one catches everybody.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| segs | NH_SEGS | — | |
| expression | STRING | all | Labels combined with | or + (union), - (minus), & (overlap), ~ (everything except) and parentheses; commas or new lines list several. all = every instance, background = everything outside them, image = whole frame, none = nothing. Words in a row are one label (red car); t-shirt needs no quotes; Vietnamese works (tóc, nền). Put spaces around a minus to subtract. Examples: person - hair · background · (wall | ceiling) - window. |
| segs_2opt | NH_SEGS | More instances of the same pictures (from another SAM3 Segment, Garment, Portrait or Body Segment), mixed into the formula. | |
| segs_3opt | NH_SEGS | And more. | |
| check_same_photoopt | BOOLEAN | true | Refuse segs of different photos of the same size (each segs keeps a small print of its picture). Turn off to mix segs of edits of one photo, such as a new background or a relight. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |