Colorize Facial Parts from PoseKPS
Turn face keypoints into a colored region map
- pose_kps
- IMAGE
This is a niche one, and it's for a specific kind of face conditioning. Instead of drawing face landmarks as dots and lines (the way OpenPose face output looks), this node takes facial keypoints and fills in the actual regions - skin, each eye, nose, the lips, the inside of the mouth - each painted a distinct flat color. The result is a face-parsing-style map: a color-coded stencil of where every facial feature sits. That's the input format some face ControlNets and animation pipelines (think MediaPipe face mesh conditioning) expect, where colored areas, not skeletal points, define the face.
How it works
Face-aware pose preprocessors (OpenPose with face, DWPose, MediaPipe face mesh) output facial keypoints inside their POSE_KEYPOINT data. This node reads those keypoints and, instead of connecting them as a wireframe, uses them as boundaries to flood-fill each facial part with a solid color. Skin gets one color, the left eye another, right eye another, nose, upper lip, inner mouth, lower lip - each its own shade. The output is a segmented face map you feed to a compatible face ControlNet, which then generates a face laid out according to those regions.
It's a small, specialized converter - it doesn't detect anything itself, it just re-renders existing face keypoints in a region-colored style.
The inputs that matter
The node takes pose_kps (POSE_KEYPOINT, wired from a face-capable pose preprocessor) and outputs an IMAGE - the colored face map. The rest of the inputs are styling controls:
mode(defaultpolygon; alsopoint) - how the parts get drawn.polygonfills each facial region as a solid area (the segmented look);pointmarks keypoints instead.polygonis what you want for region-based conditioning.- The per-part color strings (
skin,left_eye,right_eye,nose,upper_lip,inner_mouth,lower_lip) - each is anrgb(...)value defaulting to a distinct color. Change these only if your target ControlNet expects a specific color-to-part mapping; otherwise the defaults give you a clean, well-separated map.
Installing it
ComfyUI Manager: search ComfyUI's ControlNet Auxiliary Preprocessors, install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/Fannovel16/comfyui_controlnet_aux
pip install -r requirements.txt
Restart ComfyUI. No model download - this is a rendering step. You do need a face-capable pose preprocessor upstream to produce the keypoints.
Where people get burned
The biggest one: this needs facial keypoints as input, so your upstream preprocessor has to be detecting the face - plain body OpenPose won't cut it. Use OpenPose with face enabled, DWPose, or MediaPipe face mesh. Second, the colored map only means something to a ControlNet that was trained to read face-part colors; if you feed it to a generic ControlNet it won't know what the colors mean. Match the map to the model - and if that model expects a particular color scheme, set the per-part colors to match rather than trusting the defaults. This is an advanced, purpose-built node; if you just want a face pose, the standard OpenPose face skeleton is the simpler path.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| pose_kps | POSE_KEYPOINT | — | |
| mode | COMBO | polygon | 2 options: point, polygon |
| skin | STRING | rgb(0, 153, 255) | — |
| left_eye | STRING | rgb(0, 204, 153) | — |
| right_eye | STRING | rgb(255, 153, 0) | — |
| nose | STRING | rgb(255, 102, 255) | — |
| upper_lip | STRING | rgb(102, 0, 51) | — |
| inner_mouth | STRING | rgb(255, 204, 255) | — |
| lower_lip | STRING | rgb(255, 0, 102) | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |