MediaPipe Face Mesh
Control faces and expressions with ControlNet
- image
- IMAGE
This node runs Google's MediaPipe face landmarker over an image and draws the detected faces as a dense mesh of landmark lines - the tessellated "wireframe face" you've seen in AR filters. Feed that mesh into the matching face ControlNet (the LAION face model) and you get precise control over facial structure, expression, and head angle: copy an expression from a reference, pin a head orientation, or keep a face consistent while you change everything around it. It's the face-specific counterpart to OpenPose - where OpenPose handles the whole body loosely, Face Mesh handles the face in fine detail.
How it works
MediaPipe is Google's on-device ML library, and the part this ecosystem cares about is its face landmarker - it locates faces and returns a dense set of facial landmarks (hundreds of points across the face). This node renders those landmarks as a mesh and hands it to a face ControlNet. Because the mesh captures the geometry of the face - the position of eyes, mouth, brows, the tilt of the head - the model can reconstruct a face matching that structure while changing identity, style, and lighting. That's what makes it useful for expression transfer and face-angle control specifically.
One nice side note from the knowledge base: MediaPipe is Apache 2.0, which is why projects that want to be commercially clean lean on it instead of the non-commercially-licensed InsightFace. Here it's doing detection and landmarking, not identity - worth knowing it's not a face-swap or identity-embedding tool. It captures where a face is and how it's shaped, not who it is.
The inputs that matter
max_faces(default 10) - how many faces to detect and mesh. Bump it up for a crowd, drop it to 1 if you only care about a single subject and want to avoid meshing background faces.min_confidence(default 0.5) - the detection threshold. Lower it if it's missing a face (an odd angle, poor lighting); raise it if it's meshing things that aren't faces.resolution(default 512) - working size; match your render.
The single output is an IMAGE - the face mesh - feeding a ControlNet Apply node with a face-mesh ControlNet (controlnet_sd21_laion_face_v2). The node makes the mesh; the ControlNet model is separate.
Installing it
ComfyUI Manager: search ComfyUI's ControlNet Auxiliary Preprocessors, install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/Fannovel16/comfyui_controlnet_aux
pip install -r requirements.txt
Restart ComfyUI. MediaPipe pulls its face model on first use. If this particular node fails to appear after install, it's usually a MediaPipe dependency that didn't install cleanly - this pack skips nodes it can't import rather than crashing, so check the ComfyUI startup console for the import error and reinstall requirements.
Where people get burned
First, mind the license/model match: the face mesh pairs specifically with the LAION face ControlNet, which is an SD2.1-lineage model - using it with the wrong ControlNet gives you nothing useful. Second, this is detection-and-landmarking, not identity - don't expect it to preserve a specific person's likeness the way InstantID or an IP-Adapter FaceID would; for that you want an actual identity tool, not a mesh. Face Mesh controls the shape and expression, and the model fills in the identity from your prompt. Third, MediaPipe is occasionally the finicky install in this pack; if the node's missing, the fix is almost always reinstalling the pack's requirements so MediaPipe imports. And the eternal reminder: the mesh does nothing without a face ControlNet loaded to consume it.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| max_facesopt | INT | 101–50 | — |
| min_confidenceopt | FLOAT | 0.500.1–1 | — |
| resolutionopt | INT | 51264–16384 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |