toobusy Face Mask
Erase a face or keep only the face — the swap-prep node
- image
- image
- mask
Face-swap workflows have an annoying chicken-and-egg problem: to swap a face cleanly you often want a body shot with no face at all, and a face-only reference with no body. Doing that by hand in an editor for every card you feed a reference board is soul-destroying. toobusy Face Mask is the preprocessing node that does it for you - two modes, one socket each for the result image and the mask, and it's the exact tool the pack's own Reference Board flow expects you to reach for.
How it works
It detects the face, builds an oval mask around it, and then either erases the face (filling the area with gray/black/white) or keeps only the face (blanking everything else). expand grows the mask outward in pixels so you're not leaving a halo of original face at the edges, and feather softens the boundary so downstream inpainting or compositing doesn't show a hard seam. The detector chain matters, and it's auto-detected best-first:
- YOLO face model - if you already have
ultralyticsplus a face model (the same.ptfiles Face Detailer / Impact Pack use, inmodels/ultralytics), it's used automatically and it's the most accurate. - mediapipe - a precise face-oval mask when it imports cleanly.
- opencv Haar - the always-available fallback, since opencv ships its own cascade.
That chain means the node degrades gracefully: no YOLO model, no mediapipe, still works. If no face is found at all, the image passes through with an empty mask rather than crashing.
The inputs that matter
mode-erase_face(for a body card you'll paste a new face into) orkeep_face(for the face-source card). This is the whole point of the node.fill- the color behind an erased face: gray, black, white. Gray is the neutral default that plays nicest with inpainting.expand(8) andfeather(6) - the two quality knobs. If the erased area leaves ghosting, raise expand; if the mask edge is crunchy, raise feather.
Outputs and where they go
image- the processed frame (face filled in, or everything-but-face blanked).mask- the face mask itself, so you can reuse it for inpaint or composite elsewhere.
In the toobusy flow this feeds the Reference Board's card modules - Erase Face on a body card, Keep Face Only on a face source card - before the bundle goes through the Prompt Director into Flux2 Klein. But it's perfectly usable standalone: erase a face before running any inpaint model, or keep only a face to build a reference.
Install and gotchas
Optional dependency file, like the background node:
python -m pip install -r custom_nodes/toobusy/requirements_facemask.txt
Only opencv-python is strictly required; mediapipe is optional and its import is genuinely brittle across Python versions - the node auto-skips it if it's broken, so don't treat a mediapipe error as fatal. Pack install is otherwise the standard Manager-search-"toobusy" or git clone + restart.
One real-world caveat: this is a preprocessing mask, not a face-identity model. It finds a face and masks it; it doesn't guarantee the downstream swap holds identity - that's the job of the generation model and its LoRAs. Use the expand knob generously if you're erasing for an inpaint, because a hairline sliver of original face left behind is exactly the artifact that ruins an otherwise clean swap.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mode | COMBO | erase_face | 2 options: erase_face, keep_face |
| fill | COMBO | gray | 3 options: gray, black, white |
| expandopt | INT | 80–256 | Grow the face mask outward (px). |
| featheropt | INT | 60–128 | Soften the mask edges (px). |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |