Face Parsing Skin Mask
The Segformer trick that finally excludes lips, eyes, and hair from your skin mask
- image
- skin_mask
Every skin-color workflow dies on the same rock: eyes, lips, eyebrows, and hair aren't skin-colored, but they sit right inside the face, and any color-based mask happily includes them. Face Parsing Skin Mask (Eric_) dodges the whole problem by not detecting color at all. It runs a real face-parsing segmentation model that knows - per pixel - whether it's looking at skin, nose, eye, lip, brow, or hair, and it simply keeps the skin labels and drops the rest. For headshots, this is the mask node I'd start with, full stop.
How it works. It loads a Segformer model (jonathandinu/face-parsing, ~339MB) from Hugging Face on first use and predicts a class for every pixel. The node keeps the skin and nose labels, and conditionally adds neck (via include_neck, default on) and ears (via include_ears, default on). Everything else - lips, eyes, brows, hair, hats, glasses, background - is discarded before the mask is even built. The output is a hard binary mask with feathering (0–32, default 5) applied as a Gaussian blur so the boundary doesn't band against the corrected image.
That "knows what a lip is" bit is the whole value. An HSV skin detector sees a lip as vaguely reddish and includes it; this model sees label 11 (u_lip) and excludes it by definition. Your skin-tone correction then can't smear lip color across the face, which is exactly the artifact that makes AI portraits look waxy.
The inputs. Just three toggles plus feathering, and you mostly leave them alone. include_neck and include_ears are self-explanatory (the neck one matters for jaw-to-collar corrections; turn it off if you're only grading the face itself). feathering is the only one you'll realistically touch - raise it when the boundary looks harsh, drop it toward 0 if the mask bleeds over the jawline. Output is a single skin_mask MASK, wired straight into the skin_mask input of ColorCorrectionAnalyzer, SkinToneCorrector, or ColorCastRemover.
Gotchas. First run downloads the ~339MB model and loads it - the node can genuinely sit there looking frozen for a while. That's normal, and it's cached afterward. It runs on CUDA when available. And there's a licensing note worth repeating with this pack: dual-licensed, non-commercial CC BY-NC-style unless you buy the separate commercial license - check it before client work.
Installing it. It's part of the Eric Color Correction pack:
cd ComfyUI/custom_nodes
git clone https://github.com/EricRollei/Eric_Color_Correction_ComfyUI
cd Eric_Color_Correction_ComfyUI
pip install -r requirements.txt
Restart ComfyUI, or install through ComfyUI Manager ("Eric Color Correction"). The transformers dependency is what makes this node possible - if imports fail after install, that's the package to check.
Which mask node? The pack gives you a spectrum: this one for faces (fine-grained, feature-aware), HumanParsingSkinMask for whole bodies (face + arms + legs), and MediaPipeSkinMask for a fast, no-transformers path. If your subject is a portrait, reach for this one first. If they're standing in a field, the human-parsing sibling. The analyzer will tell you when you picked wrong.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| include_neck | BOOLEAN | true | — |
| include_ears | BOOLEAN | true | — |
| feathering | INT | 50–32 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| skin_mask | MASK | — |