Invert Mask (SEGS)
SEGS Masks, But Backwards (and Still Soft)
- segs
- segs
In the SEGS world, the mask inside each segment entry is not decoration - it is the instruction. A detailer reads cropped_mask to decide which pixels inside its crop it is allowed to touch, and a paste node reads it to decide what to composite back. So there is a small family of workflows where what you actually want is the opposite of what the detector found: "re-render everything that is not this face", "blend the surroundings, keep the subject untouched", "give me the negative space of this region". That is what this node produces.
How it works
It validates the SEGS structure - a two-tuple of canvas size and entries, each entry with a crop region inside that canvas - then, for each entry, pulls out the cropped mask, subtracts it from 1.0, and writes the result back into the segment with everything else preserved: crop region, bbox, confidence, label and the cropped image are all passed through unchanged.
The word that matters in the description is continuously. This is 1.0 - mask, not a boolean flip. A soft 0.3 edge becomes a soft 0.7 edge; a ramp stays a ramp, undimmed, just mirrored. If you have spent time feathering a mask, inverting it this way keeps that work.
Core's Invert Mask does not do that. It thresholds at 0.5 and flips, so a feathered edge becomes a hard step, and everything between 0.5 and 1.0 becomes a flat zero. For a binary detection mask the two are equivalent; for a blurred or refined mask they are very different tools, and this is the one that preserves the softness.
Inputs and outputs
One input, segs. One output, segs. No parameters, nothing to configure, no model, no widget - it is one arithmetic operation applied per entry, which is why it costs nothing to leave in a graph.
Reach for it at the end of a detection pipeline, when you want a pass that treats everything around a detected region. A typical shape: detect faces, invert the masks, run a low-denoise sampling pass so the surrounding skin and hair gets cleaned up while the faces are held fixed at their original detail. Or, in a compositing workflow, invert so that the paste operation treats the background as the region of interest and the subject as the area to preserve.
If what you want is the complement at the collection level rather than inside each crop, you probably want the core mask invert after a SEGSPaste-style mask export instead - this node keeps each segment's rectangle exactly as it was and only flips the values inside it.
Install
Part of ComfyUI-Utility-Suite. ComfyUI Manager → search ComfyUI-Utility-Suite → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/tom-m-2020/ComfyUI-Utility-Suite
Restart ComfyUI. The SEGS have to come from somewhere - Impact Pack's detectors, or any node that emits the structure - but nothing from Impact is bundled, so install it separately if you do not have it. No model downloads; the declared dependency is opencv-python-headless, unused here. The pack needs a recent ComfyUI since it targets the V3 node API.
Traps
The geometry no longer agrees with the mask. After inversion, crop_region and bbox still describe the original detection, while the mask describes everything except it. Anything downstream that trusts the box and the mask together - a paste that composites the crop using the mask - will paste a rectangle that is now almost entirely "uncovered". Inverted SEGS are for mask consumers that only read cropped_mask, not for the paste step.
An empty mask inverts to a solid one. A segment whose detection mask is all zeros becomes an all-ones mask: "work on this entire crop". That is arithmetically correct, and it is a real thing to watch for when a detector returns a region with a mask you did not expect to be empty.
Entries must be structurally replaceable. The node rebuilds each entry with its cropped_mask field replaced, so entries have to be the namedtuple-style objects Impact produces. Hand-built SEGS from a third party that use a plain dict or a custom class will be rejected with an error naming the entry index.
Inverting twice is free but pointless - 1 - (1 - m) is m, and the node will happily do it.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| segs | SEGS | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| segs | SEGS | — |