Kepri Mask Merge (Multi-Object → 1 BBox)
Turn N detection masks into the one bounding box they all share
- masks
- merged_mask
Detection models don't think the way your downstream nodes do. Point a GroundingDINO-style detector at a pair of shoes and you get two masks - one per shoe. A three-piece outfit gets three. That's correct behavior for a detector, and a headache for the rest of your graph, because bounding-box and background-removal nodes like MaskBoundingBox+ want a single unified mask. KepriMaskMerge is the bridge: N masks in, one [1, H, W] mask out.
It's the first node in the Kepri pack's own reference pipeline, and the pattern tells you where it belongs:
LoadImage → Resize → GroundingDetector ("shoe")
→ KepriMaskMerge → GrowMask → MaskBoundingBox+
→ RMBG-2.0 → KepriImageFinalize
How it merges
The union is a logical OR - the node takes the max across the batch dimension, so a pixel is foreground if any detected mask covers it. That choice matters: for disconnected parts like two side-by-side shoes, an intersection would be empty. The union keeps every part and the resulting bounding box englobes the whole item.
Two safety behaviors make it production-grade:
- Noise filtering -
min_mask_area_percent(default 1.0) drops any mask covering less than that % of the image, so detector background artifacts don't pollute the union. Set it to 0 to keep everything. - Graceful fallback - if no mask was detected, or every mask fell below the noise threshold, the node returns a full-image white mask instead of crashing. In an automated backend, that means the batch keeps running and the bad frame gets flagged for review rather than silently killing the run.
Inputs and outputs
One input pair, one output:
masks- the detector's[N, H, W]batch (or[H, W]when detection found nothing - ComfyUI passes an empty detection that way, and the node handles both shapes).min_mask_area_percent- the noise cutoff.- Output
merged_mask- a single[1, H, W]mask, ready for bbox and cutout nodes.
Two things worth knowing
First, that full-white fallback cuts both ways. It keeps your pipeline alive when detection finds nothing, which is exactly what you want at 3 a.m. - but it also means a failed detection quietly becomes "the whole image is the object." If you're shipping this in a batch, pair it with KepriMaskAnalysis downstream to gate the quality of what comes out of the merge.
Second, the empty-detection shape quirk is worth remembering when you're debugging. Seeing a [H, W] tensor where you expected a batch isn't a bug in your workflow - it's ComfyUI's way of saying "nothing found," and KepriMaskMerge is built to handle it.
Install
It's part of comfyui-kepri-nodes-pack - ComfyUI Manager → search "comfyui-kepri-nodes-pack", or:
cd ComfyUI/custom_nodes
git clone https://github.com/wearekhepri/comfyui-kepri-nodes-pack
Restart and refresh; it lands under Kepri/Background. Zero dependencies beyond the torch ComfyUI already ships, no model files to fetch. The detector, SAM, and background-removal weights all come from your existing nodes. Minor trap: the README's clone snippet still references comfyui-kepri.git, but the real repository is comfyui-kepri-nodes-pack - use the command above.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| masks | MASK | — | |
| min_mask_area_percent | FLOAT | 1.00–100 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| merged_mask | MASK | — |