Nodes/Character Face Swap/Exclude Facial Feature
ComfyUI Node Runs on cloud

Exclude Facial Feature

The node whose name lies (it keeps the hair)

By ArtBot2023·Created 3 years ago·Updated 2 years ago· 102
Exclude Facial Feature
  • face
  • model
  • image
  • IMAGE
expand

Let's get the elephant in the room out of the way: despite the name, the active code path of this node keeps the hair and blanks out everything else - it doesn't exclude a facial feature at all. Read the source and you'll find two mask functions: a commented-out one that masks the actual facial features (brows, eyes, nose, mouth, lips - classes 2–13), and the live one, get_mask_hair, which builds a mask of just the hair class and multiplies your image by it. The name describes the unused code. Classic small-pack archaeology.

So what does it actually do for you? It takes an image, runs BiSeNet face parsing on a reference face, and returns the image with every pixel outside the hair region set to black. Think of it as "hair extraction" - if you want the character's hairstyle to survive a swap, this is the node that separates the hair from the face so you can composite the hair back over the new face.

How it works

  • face (IMAGE) - the reference image whose hair you want to detect. It's parsed by BiSeNet to find the hair pixels.
  • model (BISENET) - from Load BiseNet.
  • image (IMAGE) - the image you actually want masked down to that hair region. (In the pack's workflow these are usually the same image, but the socket exists separately.)
  • expand (INT, ≥0) - dilation on the hair mask, in pixels, to pad the hair region.

The output is a single IMAGE: your input image with everything that isn't hair zeroed out. The mask itself isn't exposed - you get the masked image only.

One more honesty note: since it's the hair path that's active, and include_hair style toggles don't exist here, this node is hair-only by construction. The original "exclude facial feature" idea - mask out eyes/nose/mouth from a face - is dead code. If that's what you need, you'll get further with a face-parsing node from a maintained pack.

Installing the pack

It ships with Character Face Swap - ComfyUI Manager (search Character Face Swap), or:

cd ComfyUI/custom_nodes/
git clone https://github.com/ArtBot2023/CharacterFaceSwap.git
cd CharacterFaceSwap
python install.py          # on the bundled Windows build: ../../../python_embeded/python install.py

Requires the bundled facexlib (that's the install.py step) and CUDA - BiSeNet inference here is hardcoded to .cuda(), same as Segment Face.

Common problems

  • Output is mostly black: that's the node doing its thing - only hair pixels survive. If your character has short hair or hair that blends into the background, there may be almost nothing left.
  • Hair mask includes background: dark hair on dark background gets labeled as background by BiSeNet. A higher expand helps pad it back, but won't recover what the parser never saw.
  • You expected a face-mask with features removed: the name misleads, as covered. You're looking for a maintained face-parsing mask node instead.

Niche, oddly-named, and dead-code-adjacent - but if you specifically need a hair region to composite back over a swapped face, this is the one that does it.

CategoryCFaceSwap

Inputs (4)

NameTypeDefaultDescription
faceIMAGE
modelBISENET
imageIMAGE
expandINT

Outputs (1)

NameTypeDescription
IMAGEIMAGE