Face Composite
The Wan Animate glue
- original_images
- face_images
- face_bboxes
- composited_images
Face Composite does one job and does it well: it takes face crops you've refined and pastes them back onto the video frames they were cut from, in exactly the right place. It's the "stitch" in the crop-refine-stitch loop, purpose-built for the Wan Animate 2.2 preprocessing pipeline. If you've detailed a face with Impact Pack's FaceDetailer, this is the same idea - only the refiner is up to you, and it runs per-frame on video instead of a single image.
Why it exists
Wan 2.2 Animate (Animate-14B, Apache 2.0 and ungated) does motion transfer from a driving video, and the quality of that video decides the whole output. A small face in a frame is precisely what generative models mangle - the latent has no pixel budget to spend there, so it comes out a smear. The community fix has always been the same: crop the region, give it its own pass, stitch it back. Face Composite is that loop, applied per-frame to a character-animation input.
Kijai's ComfyUI-WanAnimatePreprocess does the detection half: YOLO finds the body, ViTPose extracts pose and face keypoints, and the WanAnimatePreprocess node hands you 512×512 face crops plus a list of bounding boxes. The crop then goes through whatever refiner you want - a detailer, an inpainting pass, or an image-edit model like Qwen-Image-Edit. (The author, London studio SYSTMS, also publishes the INFL8 LoRA used in the "Qwen Image Edit + Wan2.2 Animate" showcase workflow - this node is the glue from their own pipeline.) Face Composite is the return trip: refined crop in, glued onto the original frame, ready to feed Wan Animate.
How it works
For each frame it converts to numpy, resizes the refined crop to the bbox size with Lanczos interpolation, then blends it in. That's it - no model, no VRAM cost. The frame-level logic handles the boring but critical case: when a frame has no face, the bbox arrives as a full-frame box (0, 0, W, H) and the node passes the frame through untouched instead of pasting a face that isn't there.
Three blend modes decide how visible the seam is. feather is the default and the one to keep: it builds a mask that fades out feather_amount pixels from the patch edges, so the refinement melts into the surrounding pixels instead of sitting on top like a sticker. replace is a hard paste - clean when the refined face blends naturally, merciless when it doesn't. alpha_blend is a fixed 50/50 mix of old and new, which softens the seam by letting the original face show through - which also means you never fully get the refined face. Feather wins in almost every case; that's why it's the default.
The inputs that matter
- original_images (IMAGE) - the source frames, before face extraction.
- face_images (IMAGE) - your refined face crops.
- face_bboxes (BBOX) - the face bounding boxes straight off Kijai's Pose and Face Detection node, one
(x1, y1, x2, y2)per frame. - blend_mode and feather_amount - the only two knobs.
The single output, composited_images (IMAGE), is the same resolution as the originals with the refined faces baked in - feed it into the rest of the Wan Animate preprocessing and carry on.
Installing it
The pack is on the Comfy registry, so the easy path is ComfyUI Manager → Custom Nodes Manager → search "Nodes-" (or "Systms Face Composite") → Install → Restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/systms-ai/Nodes-
then restart ComfyUI. Dependencies are light - opencv-python, numpy, tqdm, torch. One important catch: this pack does not define the BBOX type. That comes from Kijai's ComfyUI-WanAnimatePreprocess, which also produces the bboxes the node consumes. Install that too, or Face Composite sits red in your graph as a missing node - there's a June 2026 thread of someone hitting exactly that "failed to find" error on the WanAnimatePreprocess category; the fix was installing the dependency pack.
The traps
The obvious one: index correspondence. face_images[i] is pasted onto original_images[i] at face_bboxes[i]. Reorder anything upstream and you'll composite the wrong face onto the wrong frame. If the refined image list runs short, the node passes the frame through rather than crashing - graceful, but a sign your upstream is out of sync.
Set expectations: this is a one-commit node from a small studio, about as deep as a pasting node gets. feather_amount is in pixels, not percent - at 512×512 crops the default of 5 is thin, so nudge it up for large faces. And there's no magic here: a 50/50 alpha blend can't fix a bad refinement, and replace won't hide one. Give the crop a real edit pass and let feather do the rest, and this little node quietly turns "deformed face in the driving video" into a non-problem.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| original_images | IMAGE | Original video frames before face extraction | |
| face_images | IMAGE | Refined face images to composite back | |
| face_bboxes | BBOX | Face bounding boxes from Pose and Face Detection node | |
| blend_modeopt | COMBO | feather | How to blend refined faces back onto original |
| feather_amountopt | INT | 50–200 | Pixels to feather at edge (only for feather mode) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| composited_images | IMAGE | — |