Nodes/DOGMA Nodes/DOGMA v52.1 Mask De-overlap / Empty-Mask Safe
ComfyUI Node

DOGMA v52.1 Mask De-overlap / Empty-Mask Safe

Your SAM 'road' mask ate the cars — this node gives them back

By axior·Created 4 months ago·Updated 3 days ago· 1
DOGMA v52.1 Mask De-overlap / Empty-Mask Safe
  • image
  • mask_1
  • mask_2
  • mask_3
  • mask_4
  • mask_5
  • mask_6
  • mask_1
  • mask_2
  • mask_3
  • mask_4
  • mask_5
  • mask_6
  • info
kind_1
kind_2
kind_3
kind_4
kind_5
kind_6
protect_px6

Ask a text-prompted segmenter for "road, street, asphalt, pavement, sidewalk" and it will hand you the road - plus the parked cars sitting on it, because they're on the street too. Ask for "buildings, facades, architecture" and you get the balconies, the awnings and a slice of the sky. Run a per-category inpaint on masks that overlap like that and the last pass wins, chewing up details the earlier pass just fixed.

This node is the tie-breaker. It's dead simple in principle - objects occlude surfaces, never the other way around, so let the objects win and carve them out of everything else - and it's the difference between a category-restoration pipeline that works and one that smears every car park into grey asphalt.

What you wire in

image (used only to get the height, width and device, so masks land on the right shape and the right GPU - it doesn't touch a single pixel), mask_1 through mask_6 from your segmenter, kind_1 through kind_6 from the plan node, and protect_px.

protect_px is the only real dial: an integer from 0 to 32, default 6. It's a dilation radius, in pixels, applied around the object union before the carve. The kinds are compared as case-insensitive strings, so they have to arrive as OBJECT, STRUCTURE or SURFACE - which is exactly what DOGMAV52ScenePlan's kind_i outputs give you.

Out you get mask_1mask_6 and an info string. Wire info into a Show Text node; it's your only diagnostic.

How the cleanup works

Three passes, in order.

Shape safety. Masks come back from segmenters in whatever shape the node felt like: [H,W], [B,H,W] for a batch of instances, occasionally [B,C,H,W]. All of them get normalized - instances unioned with a max, channels collapsed, bilinear-resized to the image's dimensions, clamped to 0–1. And here's the part that earns the "Empty-Mask Safe" in the name: if a mask is None, has zero elements, or comes back as a legally empty batch - which SAM does when it matches nothing - you get an all-black mask of the right size instead of an exception. On a hundred-frame batch, that's the difference between finishing and dying on frame 40.

Object union. Every mask whose kind is OBJECT gets maxed together into one union, then dilated with a max-pool of 2 × protect_px + 1, which spreads it protect_px pixels in every direction.

Carve. Every mask whose kind is STRUCTURE or SURFACE is multiplied by 1 − object_union. Object masks pass through untouched. So do masks carrying any other kind string - an unrecognized label is treated as protected and never carved, which is a nice failure direction.

The info line reports how many of the six inputs arrived empty, the protect_px you used, and mean_removed per slot. When a road pass comes back looking oddly bald, that number tells you whether the carve did it.

Picking protect_px

6 is a sane default and worth leaving alone until you see a problem. It exists because masks are tight: it's the same lesson the VLM-grounding workflows learned, where boxes wrap the cup and not the saucer and the padding is not optional. Here it's padding between categories rather than between mask and object.

Go too high and the dilation eats narrow surfaces outright. A road visible only in the gaps between parked cars disappears. A thin sidewalk goes with it. Go to 0 and the category passes meet at a hard border, which is fine until the vehicle pass and the road pass disagree about a few pixels and you get a visible seam.

And yes, a road mask full of car-shaped holes is the intended result, not a bug. If the holes bother you at low denoise, they're probably harmless; if they show as artifacts, raise the feathering on the mask after this node rather than lowering protect_px back to 0.

Two limits worth knowing: the carve is a straight multiplication, so this node does no feathering, blurring or morphological smoothing of its own - a hard edge in stays hard. And it's fixed-width at six categories. Extra slots you don't need should be fed a black mask, though the empty-safe path will cover you if your segmenter returns nothing.

Install

Manager → search DOGMA Nodes. Manual:

cd ComfyUI/custom_nodes
git clone https://github.com/axior/ComfyUI-DOGMA-Nodes

Restart. No third-party dependencies - the pack ships a requirements.txt containing one comment confirming it. In the node menu, search "de-overlap"; it's under category DOGMA/v52, display name "DOGMA v52.1 Mask De-overlap / Empty-Mask Safe".

Why you've never heard of it

Worth saying plainly: this pack has essentially no community footprint. There's no thread, no tutorial, no video - the README documents only its WAN VACE nodes and its samplers, and the semantic-detailer family is undocumented. If you're here because a workflow you downloaded shows a red "missing node" box, you now know what the node does; the source file dogma_semantic_v5641.py is the only reference there is.

CategoryDOGMA/v52

Inputs (14)

NameTypeDefaultDescription
imageIMAGE
mask_1MASK
mask_2MASK
mask_3MASK
mask_4MASK
mask_5MASK
mask_6MASK
kind_1STRING
kind_2STRING
kind_3STRING
kind_4STRING
kind_5STRING
kind_6STRING
protect_pxINT60–32

Outputs (7)

NameTypeDescription
mask_1MASK
mask_2MASK
mask_3MASK
mask_4MASK
mask_5MASK
mask_6MASK
infoSTRING