Nodes/ComfyUI-UniversalRemove/UR Regions To Mask Batch
ComfyUI Node

UR Regions To Mask Batch

Keyframe scribbles become the mask for every frame

By fengwk·Created 2 months ago·Updated 2 months ago· 0
UR Regions To Mask Batch
  • images
  • mask
  • selected_frame
  • preview
regions_json[{"type":"rect","frame_index":0,"x":160,"y":120,"w":260,"h":140}]
default_frame_index0
broadcast_mode
normalizedfalse
preview_frame0
preview_color#FF3B30
preview_opacity0.35

This is the heart of the UniversalRemove pack. Everything else is build-up: UR Region Editor gives you the scribbles, UR Mask Processor polishes the result, UR Keyframe Prep feeds the model. This is the node that takes your keyframe regions and turns them into a MASK for the entire image batch - every frame of your video, not just the ones you drew on.

That "keyframe" bit is the whole trick. You don't draw 300 masks for a 300-frame clip; you draw three or four, and this node decides how the in-between frames get covered.

How it works

You feed it your frame batch plus a regions_json array - the output of UR Region Editor, or hand-written JSON. Each region is a shape (rect, circle, or polygon) tagged with a frame_index:

[
  {"type": "rect", "frame_index": 0, "x": 160, "y": 120, "w": 260, "h": 140},
  {"type": "polygon", "frame_index": 48, "points": [[120,160],[240,150],[280,260],[150,290]]}
]

The node rasterizes each shape onto a mask at its keyframe, then broadcast_mode spreads those keyframe masks across the batch:

  • repeat_to_batch - union of everything, repeated on every frame. For a static watermark.
  • single_frame_only - masks only the frames you explicitly drew.
  • hold_after_frame - each keyframe mask holds from its frame to the end of the clip (later keyframes overwrite earlier ones).
  • hold_until_next_keyframe - the one that makes video removal sane: each keyframe mask covers the span up to the next keyframe, and the last one runs to the end. This is the mode that follows a moving object across a shot.

Shape type names are forgiving - rectangle, box, bbox, ellipse, poly are all accepted as aliases. A region without a frame_index falls back to default_frame_index, and any frame index outside the batch gets clamped rather than crashing.

Inputs and outputs that matter

  • images - your frame batch. Its dimensions define the mask resolution.
  • regions_json - the payload.
  • broadcast_mode - the behavior knob. Start with hold_until_next_keyframe for anything moving.
  • normalized - treat all coordinates as 0–1 fractions of the frame.
  • preview_frame / preview_color / preview_opacity - which frame to preview on, and how to style the overlay.

Outputs: mask (the full batch of masks - this is the one that matters), selected_frame (the preview frame), and preview (overlay image).

Wire the mask into UR Mask Processor → UR Keyframe Prep → your inpaint model, and the whole remove core is assembled. The README's recommended workflow is exactly that chain, with UR Soft Composite catching the other end.

Common issues

The classic mistake is forgetting the frame_index and getting a mask on the wrong frame - always check which keyframe a region is tagged with when a removal appears a few frames late. If you hand-write JSON, malformed entries raise a clear error rather than silently passing, but an empty array produces an all-black mask with no complaint, so a missing mask is usually "the JSON didn't load" rather than a crash. And remember the bbox-vs-polygon lesson from the detailing literature: if you're removing organic shapes, polygons feather far better than rectangles - the seams disappear because the mask hugs the subject.

CategoryUniversal Remove

Inputs (8)

NameTypeDefaultDescription
imagesIMAGE
regions_jsonSTRING[{"type":"rect","frame_index":0,"x":160,"y":120,"w":260,"h":140}]
default_frame_indexINT00–1000000
broadcast_modeCOMBO4 options: repeat_to_batch, single_frame_only, hold_after_frame, hold_until_next_keyframe
normalizedBOOLEANfalse
preview_frameINT00–1000000
preview_colorSTRING#FF3B30
preview_opacityFLOAT0.350–1

Outputs (3)

NameTypeDescription
maskMASK
selected_frameIMAGE
previewIMAGE