Consolidate Masks
Packing a pile of small masks into fewer tiles
- masks
- MASK
If you've used a detailer workflow - the detect-crop-refine-paste-back loop that Impact Pack's FaceDetailer made standard practice - you've seen what happens when a detector hands back a dozen small masks instead of one big one: a crowd scene, say, where every face gets its own tiny detection mask. Running a separate crop-and-refine pass on each one individually works, but it's slow, and often unnecessary when several of those masks sit close together. Consolidate Masks exists for exactly that situation: it groups nearby masks into fewer, larger tiles before you do the expensive part.
How it works
The node's own description lays out the mechanism directly: it finds the largest group of masks that all fit inside a tile of the given width and height (including padding), merges them, and repeats until nothing more can be combined. It's a greedy bin-packing pass over your mask batch - not smarter than that, but that's exactly what makes it fast and predictable.
The inputs that matter
masks(MASK, required) - the batch of separate masks going in, typically a pile of small detection masks from an upstream detector.width/height(default512each, in steps of64) - the tile size budget. Masks only get merged if the resulting group fits inside one tile of this size.padding(default0) - extra slack around each mask when checking whether it fits inside a tile. A mask technically just outside your tile bounds but within padding distance still gets pulled into the group.
Output: MASK - the consolidated batch, now fewer and larger masks, each one covering whatever original masks fit together in a shared tile.
How to install it
Via ComfyUI Manager: search KJNodes for ComfyUI, install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/kijai/ComfyUI-KJNodes
pip install -r ComfyUI-KJNodes/requirements.txt
Then restart. Pure mask-batch logic, no models to download.
Common issues & troubleshooting
Little to no consolidation is happening. If your original masks are spread out relative to width/height, the node simply can't fit multiple of them inside one tile of that size - bump width/height up (in 64-pixel steps, matching typical latent-friendly resolutions) if you expected more merging than you're seeing.
You want the node to be more aggressive about grouping nearby-but-not-quite-overlapping masks. Raise padding before touching tile size - it directly controls how close two masks need to be to count as mergeable, independent of whether they physically fit inside the same tile.
The next node in your chain wants boxes, not a mask. This node's output stays a MASK - it doesn't produce BBOX data. If you're feeding the result into something expecting bounding boxes (this pack's BatchUncrop, for instance), you'll need a mask-to-bbox conversion step in between.
Consolidation groups regions you didn't want combined. A large padding or generous tile size can merge masks you'd rather keep processed separately - for instance, two faces that are visually near each other but belong to subjects you want detailed independently. Pull padding back down, or shrink the tile size, if the groupings are too aggressive for your use case.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| masks | MASK | — | |
| width | INT | 5120–4096 | — |
| height | INT | 5120–4096 | — |
| padding | INT | 00–4096 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | — |