Nodes/ComfyUI_zura_nodes/Zura · Crop Approved Speech Portrait
ComfyUI Node

Zura · Crop Approved Speech Portrait

Not a face-crop node — a bouncer that checks your performer's ID first

By ZURAVFX·Created about a month ago·Updated a day ago· 2
Zura · Crop Approved Speech Portrait
  • opening
  • source_images
  • approved_mask
  • source_pose
  • source_boxes
  • opening_pose
  • opening_boxes
  • speech_portrait
  • crop_provenance
◄guide_key►

ZuraWanSpeechReferenceCrop (display name Zura · Crop Approved Speech Portrait) sounds trivial - find a face in one image, cut a portrait around it - and then spends most of its code refusing to do it. That's the point. This is the reference portrait that drives Wan's native speech guide, and a portrait of the wrong face is how you get a lipsync pass that animates someone else's mouth. So it checks that the face it found sits inside your approved performer mask, roughly where the performer was in the source shot.

The crop itself

The framing is mechanical: a strict 3:4 portrait sized off the detected face, centred horizontally on it and shifted slightly down so chin and neck stay in frame, clamped to the edges. If the face can't fit without being cut it raises rather than cropping a partial face - and that 3:4 shape matches the 480 × 640 reference the guide expects.

Inputs

This is a native-graph node, so the wiring is the work:

  • opening (IMAGE) - the approved character look, one RGB frame. It has to be a single frame; a batch is rejected.
  • source_images (IMAGE) - one frame from the source shot's opening; the name is misleading, and it's used only as a position reference, not as content.
  • approved_mask (MASK) - the approved performer mask for that source opening frame, and it has to match its size.
  • source_pose / source_boxes, opening_pose / opening_boxes - POSEDATA and the detector's bbox lists from WanAnimatePreprocess's PoseAndFaceDetection for each image. Both must describe exactly one detected person: one pose entry, one box.
  • guide_key (STRING) - the 64-hex identity of the guide being prepared, stamped into the crop record so the crop can be verified against it later.

What it checks, and why

The face evidence has to be real. It wants the 68-point landmark set - a 69-keypoint layout gets trimmed to fit - averages the confidence of the lower-face points only, and requires at least 0.3. It also rejects "collapsed" landmarks even when the detector reported a high score. Those checks are what stop a black frame or a smeared background face from becoming your speech reference.

Then the two identity checks, which is the part I'd call clever:

  1. The detected source face box must be at least half inside the approved performer mask, or you've approved a mask that doesn't cover the person's face.
  2. The face in the approved opening, projected back into source coordinates, must also be ≥50 % inside that mask with its centre within 1.5 face-widths of the source face. That's the multi-person guard: in a two-hander shot, the "new" face can be legitimate and still be the wrong performer, and a confidence check alone would wave it through.

It then writes all of it down. The crop_provenance output is canonical JSON containing the recipe name (approved-face-portrait-v1), the guide key, both image sizes, both face boxes, the crop as x, y, w, h, both mask-overlap fractions and both confidences. That string goes into the crop_metadata input of ZuraWanSpeechSaveGuide, which re-validates all of it: recipe intact, crop inside the opening frame, aspect exactly 4:3, overlaps ≥0.5, confidences ≥0.3. So the crop record isn't a log - it's what the guide gets verified against. The speech_portrait output is the image you actually use.

Install

Nothing beyond the pack and its preprocessing dependency:

cd ComfyUI/custom_nodes
git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
python -m pip install -r ComfyUI_zura_nodes/requirements.txt

You need ComfyUI-WanAnimatePreprocess for PoseAndFaceDetection, plus detection/vitpose-l-wholebody.onnx and detection/yolov10m.onnx installed where that pack looks for them. This crop feeds the InfiniteTalk guide, so the speech route also wants Setup_Wan_Speech_Windows.cmd run once. Studio builds the node for you when you open More controls > Open in graph view > Wan speech performance; hand-wiring it is only worth it if you're deliberately replacing the guide.

Where people get burned

  • Loose framing is the number one cause of failure: two people in frame, a profile, a hand over the mouth or a face mostly off-camera all end in a variant of Detect one visible character face in the approved opening frame. The fix is upstream - pick a cleaner opening frame in the review flow rather than tweaking settings here.
  • The face cannot fit a portrait crop without cutting it. Choose a wider opening frame. - the face is too large for a 3:4 crop that contains it. Again, upstream framing.
  • Wiring source_images from the approved output instead of the source opening frame is an easy mistake; the position check will then compare a face against itself.
  • And once more for the pack itself: there's effectively no community coverage of these nodes, so a weird error means reading the message closely - fortunately these are specific enough to act on.
CategoryZura/Artist Studio

Inputs (8)

NameTypeDefaultDescription
openingIMAGE—
source_imagesIMAGE—
approved_maskMASK—
source_posePOSEDATA—
source_boxesBBOX,—
opening_posePOSEDATA—
opening_boxesBBOX,—
guide_keySTRING—

Outputs (2)

NameTypeDescription
speech_portraitIMAGE—
crop_provenanceSTRING—