ComfyUI Node

Bridge Masks

Glue Two Detected Blobs Into One Region

By tom-m-2020·Created about a month ago·Updated 7 days ago· 1
Bridge Masks
  • mask_a
  • mask_b
  • mask
◄mode▾►

The problem it solves

Detectors are greedy for boxes and stingy with continuity. You ask a face or segment detector for a subject and get back two blobs where you wanted one - head and torso split by an occluding arm, a hand attached to nothing, a SAM fragment broken in half because the shading changed. Hand that to a detail pass and the loop treats them as two jobs, or you crop one and lose the other.

Padding solves a single region. It does nothing for the space between two regions. That's the slot Bridge Masks fills: hand it two masks and it produces one mask covering both plus the corridor between them, as straight-sided convex geometry. It saves you from hand-painting the connective tissue every time.

No pixels get generated here - this is plumbing, the graph just gets a better-shaped region. And nobody on r/comfyui is talking about this pack; zero threads name it. So what follows is read off the source and its test suite, not off other people's workflows.

How it works

For each input it computes the exact-nonzero bounding box - every pixel that isn't zero counts, no threshold. Then it takes the four corners of box A and the four corners of box B (eight points total), runs cv2.convexHull on them, and fills the resulting polygon. That's it. The output is the hull, or the union, depending on mode.

Two things follow from that, and both matter.

First, the geometry is bounding-box geometry, not contour geometry. It never looks at the shape of your mask. Two ragged, comma-shaped detections become a clean polygon with straight edges (more than four vertices once the boxes are offset diagonally). If you expected a mask that hugs the subject, you'll be disappointed - this is coarse by design.

Second, a zero-valued pixel is the only thing that doesn't count. One faint antialiased pixel of value 0.02 in the far corner of your canvas is enough to drag the bounding box across the whole frame, and the hull with it. Feed it hard masks: don't feather or blur beforehand, and don't hand it anything that leaves soft residue at the edges.

The inputs and the one that matters

Three inputs, one output.

  • mask_a - MASK, required.
  • mask_b - MASK, required.
  • mode - COMBO, required. Options are exactly convex_hull and gap.
  • Output: mask (MASK), one per node.

mode is the whole decision.

convex_hull throws your original mask values away and returns only the filled hull at 1.0. Use it when you want a single blunt region - a crop box, a broad area to rediffuse, a coarse "this character" zone for regional work.

gap is the conservative mode. It keeps both masks pixel-for-pixel, including soft values, and only adds pixels in the corridor between them - and only when the two bounding boxes genuinely don't touch. If the boxes overlap, are nested, or share an edge, gap returns plain union and adds nothing, because there's no gap to bridge. The bridge pixels it adds are hard 1.0, so a bridged mask ends up part soft, part hard; feather it afterward if the seam matters.

Both inputs must share a canvas size, and they need equal batch counts - or one may be a single mask that gets broadcast across the other.

Installing it

The pack's README is empty - literally zero bytes - so there's no author writeup to crib from. Manager or a clone are your options.

cd ComfyUI/custom_nodes
git clone https://github.com/tom-m-2020/ComfyUI-Utility-Suite
# restart ComfyUI

Or search ComfyUI-Utility-Suite in ComfyUI Manager and install from there. It lands under the Utility Suite/Mask category, so look for Utility Suite → Mask → Bridge Masks.

No model downloads. The only declared dependency is opencv-python-headless (the hull math is cv2), which a normal ComfyUI install already has, so the install is usually a no-op. The real requirement is your ComfyUI version: the whole pack is written against the newer comfy_api.latest node schema, so on an older build it won't register at all - an import failure in the startup log and no nodes in the menu. Update ComfyUI first.

Where people get burned

An empty mask kills the run. If a detector found nothing on one input you get Bridge Masks mask_a batch item 0 has no nonzero bounding box, and the whole execution dies - a hard error, not a warning. Across a batch of video frames, one missed detection takes down the job, so guard in front of it or only use it on frames you know detected.

Mismatched canvases and batches. Both masks must be the same H×W (requires matching canvas dimensions) - this bites when one mask came out of a crop and lost its resolution, so resize back to full canvas. Two batched masks with different counts fail with requires equal batch sizes or a singleton side; run 8 against 8, or 8 against 1.

The hull overreaches. Because it bridges by bounding box, two masks in diagonal corners produce a polygon covering most of the image. That's correct behavior and almost never what you want. Preview the mask before wiring it into an inpaint - a hull that swallows the background is the fastest way to discover you rediffused half your picture.

CategoryUtility Suite/Mask

Inputs (3)

NameTypeDefaultDescription
mask_aMASK—
mask_bMASK—
modeCOMBO2 options: convex_hull, gap

Outputs (1)

NameTypeDescription
maskMASK—