UR Regions To Mask Batch
Keyframe scribbles become the mask for every frame
- images
- mask
- selected_frame
- preview
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_keyframefor 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.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| regions_json | STRING | [{"type":"rect","frame_index":0,"x":160,"y":120,"w":260,"h":140}] | — |
| default_frame_index | INT | 00–1000000 | — |
| broadcast_mode | COMBO | 4 options: repeat_to_batch, single_frame_only, hold_after_frame, hold_until_next_keyframe | |
| normalized | BOOLEAN | false | — |
| preview_frame | INT | 00–1000000 | — |
| preview_color | STRING | #FF3B30 | — |
| preview_opacity | FLOAT | 0.350–1 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |
| selected_frame | IMAGE | — |
| preview | IMAGE | — |