Nodes/Zura Nodes/Zura Mask
ComfyUI Node

Zura Mask

Zura Mask takes any video, not just Wan's — and that's the useful part

By ZURAVFX·Created a day ago·Updated about 13 hours ago· 0
Zura Mask
  • video
  • mask_preview
  • masked_footage
  • mask
replacement_areaWhole character
mask_expansion12
blockify_masktrue
block_size32

Wan 2.2 Animate is a replacement model. It wants a driving clip, a reference identity, a mask saying which pixels get replaced, and pose/face conditioning so it knows how the performer moves. In a stock graph that's a small pile of nodes from Kijai's WanAnimatePreprocess pack wired by hand.

Zura Mask collapses that pile into one node with a dropdown. And unlike most of the pipeline it sits in, its input is a plain VIDEO - so if all you want is a person mask plus a red-tinted debug video, you can use it on any decoded clip from any pack.

Inputs worth knowing

  • video - any VIDEO wire. Zura Load Video, someone else's decoder, whatever.
  • replacement_area - Whole character, Whole head, or Face only. This is the one that changes your result most. Whole character replaces head and body; Whole head expands the face landmarks out to hair, forehead and ears, and crucially cuts at the neck so your subject's torso can't wander into the mask; Face only keeps the tight landmark ellipse.
  • mask_expansion - grows the mask by N pixels (default 12). A little slack stops the seam landing on the original silhouette.
  • blockify_mask + block_size - on by default, 32px.

Outputs, and which one goes where

Three outputs, and they are genuinely three different things:

  • mask_preview - a VIDEO with the mask tinted red over the footage. Preview it, SaveVideo it, it's a normal video wire. This is your "did the detector actually find the person" check, and you should look at it before spending GPU time.
  • masked_footage - type ZURA_FOOTAGE. This is the payload the sampler consumes, and it's the one non-standard wire in the whole pack. A VIDEO wire can't carry pose, face and mask tensors, so it doesn't try.
  • mask - a native MASK. Wire it to ComfyUI's own Preview Mask to see it in isolation, or feed any inpainting node; it isn't Wan-specific.

How it works

Per frame, a YOLOv8-m segmentation model runs on CPU. Deliberate: the diffusion model owns the GPU, and a small segmentation pass must not evict a 14B model's weights. Segmentation (a polygon) rather than bbox detection matters here for the same reason it does in image detailing - a polygon hugs the silhouette, a rectangle leaves edges - and this is the person_yolov8m-seg.pt weight the community has reused for years.

Then the mask is dilated by mask_expansion, blockified, and the pose/face pass runs through the installed WanAnimatePreprocess nodes (OnnxDetectionModelLoader, PoseAndFaceDetection, DrawViTPose) to build the pose video and 512×512 face crops. Face landmark bboxes get a NaN-safe fallback: WanAnimatePreprocess converts landmarks to integers, so an occluded face would otherwise crash there. You get a sane centred crop instead of a traceback.

Blockify is worth a sentence. Wan expects a blocky mask, and the author wanted KJNodes' BlockifyMask behaviour without forcing a KJNodes install: if that node is present the pack calls it, otherwise an internal bounding-box block-grid implementation reproduces the same algorithm. Same output either way - it's a GPL-3.0-derived port, which is why the pack ships AGPL-3.0 with a third-party notice.

One behaviour to respect rather than fight: if detection fails on any frame, the node raises instead of quietly producing a partial mask. "Refusing to continue without a character mask" is the right default - a missing mask halfway through gives you a chunk where the model replaces the background instead of the person.

Install

Manager → Zura Nodes, or:

cd ComfyUI/custom_nodes
git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
git clone https://github.com/kijai/ComfyUI-WanAnimatePreprocess
pip install -r ComfyUI_zura_nodes/requirements.txt   # into ComfyUI's own python env

Restart ComfyUI afterwards - ultralytics in that requirements file exists for this node.

This node also requires ComfyUI-WanAnimatePreprocess - it supplies the three preprocessing classes above, and without it the node raises with their names in the message.

Model files, in standard ComfyUI model dirs:

  • ComfyUI/models/ultralytics/segm/person_yolov8m-seg.pt - the segmenter. ComfyUI Impact Subpack's model installer can fetch this one for you.
  • ComfyUI/models/detection/vitpose-l-wholebody.onnx - ViTPose whole-body.
  • ComfyUI/models/detection/yolov10m.onnx - the WanAnimate detector.

The last two are the filenames the preprocessing call asks for by name, loaded from the detection directory that WanAnimatePreprocess registers.

Where people get burned

  • Everything is installed and it still says the preprocessing nodes are unavailable. The clone went into a different custom_nodes folder, or the pack needs a restart after installing WanAnimatePreprocess.
  • person_yolov8m-seg.pt in the wrong place. It goes under models/ultralytics/segm/, not next to the other detection ONNX files. Wrong folder, wrong error.
  • Occlusion and crowds. The detector is per-frame person segmentation; someone walking through the frame or a face turned away is exactly where it fails, and it fails loudly.
  • Cranking block_size or mask_expansion "for safety". Big blocks plus big expansion swallows clothing and background, and the model then replaces things you didn't ask it to replace. Defaults (32 / 12) are a sane starting point - change replacement_area first, it's the bigger lever.
CategoryZura

Inputs (5)

NameTypeDefaultDescription
videoVIDEOAny video wire: Zura Load Video, or a decoded clip from another pack.
replacement_areaCOMBOWhole characterWhole character: replace head and body. Whole head: replace the entire head including hair and ears. Face only: replace just the face.
mask_expansionINT120–128Grow the replacement mask by this many pixels before blockifying.
blockify_maskBOOLEANtrueQuantise the mask to square blocks, as Wan expects.
block_sizeINT328–512Size of blocks in pixels (smaller = smaller blocks) — full control, matching KJNodes BlockifyMask.

Outputs (3)

NameTypeDescription
mask_previewVIDEO
masked_footageZURA_FOOTAGE
maskMASK