CMK Face Mask
A soft ellipse over the face, and a coverage number to prove it
- image
- selected_face
- image
- selected_face
- mask
- diagnostic
Inpainting a face is 90% mask quality. Too tight and you get a visible rectangle of different skin; too loose and the model rebuilds the hair, the earring and the background behind it. CMK Face Mask gives you a feathered shape derived from the face box, and - the part I actually like - tells you what percentage of the frame you just selected.
What it is
A toolbox node: image and a selected_face in, then image (passed through untouched), selected_face (passed through), mask, and a diagnostic. Category CMK/Toolbox/Face.
The pass-throughs are deliberate. It's a mask builder, not an image operation, so the image and the face payload come out the other side identical and you can chain it in the middle of a face pipeline without rewiring.
The controls
shape-Ellipse(default) orBox. Ellipse hugs a face far better than a rectangle; a box-shaped mask is what you use when the face is against the frame edge or you're deliberately being generous.padding- default 0.25, range 0–2, as a fraction of the face box. This is the main dial: it decides whether you're masking the face or the head.feather- default 24, range 0–256. Softens the mask edge so the composite seam fades. This is the difference between a blended result and a visible oval.invert- flip it and you mask everything except the face, which is the shape you want when the job is "re-generate the surroundings, leave the person alone."preview_mode-Off,Mask,Overlay,OutlineorCoverage, defaultOverlay. Andpreview_opacity(0.5) to taste.
The preview modes are the sell here. Coverage renders a coverage readout over the image; the diagnostic's summary and metrics carry that number (coverage_avg, as a percentage of the frame) plus the shape, padding, feather and invert state. So after one run you know your mask covers 4.2% of a 1024×1024 frame, and you know that because the node measured it, not because you eyeballed a black-and-white thumbnail.
How it works
For each frame it builds the mask from the face bounding box expanded by padding, as either an ellipse or a rectangle, applies the feather radius, optionally inverts, and stacks the result into a batch. padding, feather and preview_opacity are clamped at execution time - there's a comment in the source about stale widget values in older workflows, so a saved graph that predates a range change gets quietly brought back into range instead of producing something absurd. shape and preview_mode fall back to their defaults if a stored value isn't recognised. That's a small thing that saves a class of "my old workflow went weird" bug reports.
One behaviour to note: the outputs are a batch matched to the input image batch, so a 4-frame batch gives you 4 masks. If a downstream node takes a single mask, take the first frame.
Install
Ships with the pack. Manager: search CMK Flow, install the CMKFlow entry, restart. Manual, from the folder with main.py:
git clone https://github.com/CMKFlow/cmk_nodes.git custom_nodes/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py
CMK dependency check: OK is what you're waiting for, and it's the step people miss after a manual clone - git clone never runs pip on its own. The environment it installs into is a shared one, and this pack is not shy about it: ultralytics, onnxruntime, insightface, segment-anything, imageio-ffmpeg, opencv-python, nudenet==3.4.2. No Impact Pack needed for the SEGS side, though - CMK ships its own.
Detector weights (YOLO face models) belong under models/ultralytics/bbox; the resource checker audits the filenames the bundled workflows expect:
python3 custom_nodes/cmk_nodes/scripts/check_cmk_resources.py --models-root "/path/to/shared/models"
Issues worth knowing
Feather is in pixels, not a percentage, so it doesn't scale with resolution. A feather of 24 that looks perfect at 1024×1024 is a hard edge at 2048. Bump it when you upscale.
And the classic: if your inpainted face has a visible halo, the seam is the mask, not the model. Turn preview_mode to Coverage, look at where the mask actually ends, and increase padding before you touch denoise. More often than not the ellipse was cutting through the jawline.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| selected_face | CMK_SELECTED_FACE | — | |
| shape | COMBO | Ellipse | 2 options: Ellipse, Box |
| padding | FLOAT | 0.250–2 | — |
| feather | INT | 240–256 | — |
| invert | BOOLEAN | false | — |
| preview_mode | COMBO | Overlay | 5 options: Off, Mask, Overlay, Outline, Coverage |
| preview_opacity | FLOAT | 0.500–10 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| selected_face | CMK_SELECTED_FACE | — |
| mask | MASK | — |
| diagnostic | CMK_DIAGNOSTIC | — |