Nodes/ComfyUI-WanAnimatePreprocessV2/Wan-Animate Face Quality Check (V2)
ComfyUI Node

Wan-Animate Face Quality Check (V2)

Your face crops are feeding the encoder garbage — this node catches it before it does

By Code2Collapse·Created 8 months ago·Updated 8 days ago· 17
Wan-Animate Face Quality Check (V2)
  • face_images
  • face_images_repaired
  • good_frame_ratio
  • report_json
blur_threshold50
min_eye_brightness0.10
auto_repair_bad_framestrue
repair_strategycopy_previous_good

Wan Animate's face encoder has a known failure mode: feed it a blurry or too-dark face crop and it produces drifting, wrong-direction gaze - the character's eyes slide off into space like the actor forgot what they were looking at. WanAnimateFaceQualityCheckV2 sits in front of that encoder and scores every face crop on two objective signals: sharpness and eye-region brightness. Bad frames get repaired before they ever reach the model. It's the kind of node you didn't know you needed until the first time a character's pupils pointed at the ceiling.

The pack's paper-notes call it out directly (spec Sec 4.3): bad face conditioning frames cause the face encoder to produce drifting / wrong-direction gaze. This node is the cheap insurance against exactly that.

How it works

Two checks per frame, both pure OpenCV math, zero models:

  1. Sharpness - Laplacian variance. A crisp 512×512 face crop typically scores 100–1000; anything below blur_threshold (default 50) is flagged as motion blur or out-of-focus.
  2. Eye brightness - the mean luma of the eye-region strip (rows 30–55% of the crop). Below min_eye_brightness (default 0.1), the eyes are likely closed or the frame is too dark for the encoder to read gaze at all.

A frame fails if it trips either check. Then, depending on auto_repair_bad_frames and repair_strategy, it's fixed in one of three ways:

  • copy_previous_good (default) - replace the bad frame with the last frame that passed. Simple, effective, and for a short blink-blur or one bad exposure it's invisible.
  • unsharp_mask - sharpen it instead of replacing it. Better when the frame is soft but the information is there.
  • skip - leave it untouched and just report.

The inputs and outputs that matter

  • face_images - the per-frame 512×512 crops from PoseAndFaceDetectionV2. This is the required input, and it's the whole point of the node's existence.
  • blur_threshold (50) - the sharpness floor. If you're getting false repairs on legitimately soft footage (shallow depth of field close-ups), lower it.
  • min_eye_brightness (0.1) - the eye-brightness floor.
  • repair_strategy - as above; defaults are fine for 95% of footage.

Outputs: face_images_repaired (same shape as input, wire this downstream in place of face_images), good_frame_ratio (the fraction that passed - a 0.98 means you're fine, a 0.7 means your source is in trouble), and report_json with per-frame blur score, eye brightness, verdict and repair action.

Where you put it

The README and tooltips are explicit about placement: between PoseAndFaceDetectionV2's face-crop output and your downstream face encoder - typically face_images → this node → the sampler's face input. Since the face branch in Wan Animate is 100% pixel-driven, cleaning the pixels before the encoder is the only real lever.

One honest note: copy_previous_good can freeze a frame during a sustained blink - the repaired crop holds the last open-eye frame, which for a 2–4 frame blink is exactly what you want (the encoder sees open eyes), but for a long closed-eyes moment it's a deliberate lie. If you're driving a clip where the subject keeps their eyes shut for dramatic effect, skip is the honest setting. This is also the node to pair with the pack's force_eyes_open feature on the detection side: quality-check upstream, fix the framing upstream, and this node only catches the genuinely broken frames.

Install is the shared pack path - Manager search "WanAnimatePreprocessV2", or clone + pip install -r requirements.txt + restart. No model downloads of its own.

CategoryWanAnimatePreprocess_V2

Inputs (5)

NameTypeDefaultDescription
face_imagesIMAGEPer-frame 512x512 face crops (output of Pose and Face Detection V2).
blur_thresholdFLOAT500–5000Laplacian-variance threshold below which a frame is flagged as blurry. Typical sharp 512x512 frames score 100-1000; <50 indicates motion blur or out-of-focus.
min_eye_brightnessFLOAT0.100–1Minimum mean luma of the eye-region strip (rows 30%-55%). Below this, eyes are likely closed or the frame is too dark for the encoder to read gaze.
auto_repair_bad_framesBOOLEANtrueIf true, repair frames flagged as bad. If false, just report stats.
repair_strategyCOMBOcopy_previous_goodcopy_previous_good: replace with last good frame. unsharp_mask: deconvolve-style sharpening. skip: leave untouched but report.

Outputs (3)

NameTypeDescription
face_images_repairedIMAGERepaired face IMAGE batch (same shape as input).
good_frame_ratioFLOATFraction of frames that passed BOTH thresholds (0..1).
report_jsonSTRINGJSON report: per-frame blur score, eye brightness, verdict, repair action.