Sapiens2 Pose (308 KP)
308 human keypoints, down-mapped to OpenPose when you need it
- image
- sapiens2_model
- bboxes
- keypoints
Pose estimation is the ControlNet preprocessor that made reposing people actually controllable, and Sapiens2 does it with a 308-keypoint layout that includes both hands' full finger chains and dense facial landmarks - far beyond the 17-joint skeleton most detectors give you. This node runs the Sapiens2 pose head on your image and hands you those keypoints. The clever part is the output format: it can hand them to you as OpenPose-compatible data, so every downstream openpose tool and ControlNet model you already use understands it.
How it works
Wire in the image and a SAPIENS2_MODEL from the Loader that loaded a -pose checkpoint. Two decisions matter:
-
output_format -
openpose(default) remaps the 308 keypoints into the classic OpenPose shape: 17 body joints + 6 foot + 21+21 hand keypoints (plus 70 face landmarks if you tick include_face), stored aspose_keypoints_2d/foot_keypoints_2d/hand_*/face_keypoints_2d. This is what controlnet/openpose conditioning expects.raw_308gives you the full native Sapiens2 layout with no remapping - mostly for the DrawPose node, which can render the complete 308-point skeleton with per-part coloring. -
bboxes (optional, connection-only - you can't type it in) - person bounding boxes from a detector like RT-DETR, SDPoseFaceBBoxes, or SAM3. Give it boxes and the node does proper top-down inference: each person is cropped and warped individually to the model's 1024×768 input, matching how upstream Sapiens2 runs, then coordinates are remapped back to your image. Without boxes, the whole image gets resized and run as one person - fine for a tight single-person crop, wrong for a group shot.
-
frames_per_batch - frames per forward pass for video. The keypoint decode uses a DARK-style heatmap peak with blur, which is why the joints stay stable frame to frame instead of jittering like a naive argmax.
Output is keypoints (type POSE_KEYPOINT), a frame-per-image structure with per-person data. From here it goes one of two ways: into Sapiens2 Draw Pose to render an actual image (then into a ControlNet openpose conditioner or just saved as a visual), or straight into any node that consumes pose data.
The workflow you actually want
LoadImage → ImageResize → Sapiens2 Loader (pose-1b) → Sapiens2Pose → Sapiens2DrawPose → SaveImage
└→ ControlNet (openpose) → KSampler
include_face is off by default for a reason: it costs a little accuracy budget, and most reposing only needs the body. Turn it on when you're driving facial expression or lip shape. And the honest tip from running this pack: on a photo with one person, skip the detector and just pre-crop - the full-image path is simpler and nearly as good; on anything with multiple people, wire the bboxes or every person melts into one averaged skeleton.
Install: Manager search "ComfyUI-Sapiens2", or git clone https://github.com/kijai/ComfyUI-Sapiens2 into custom_nodes, restart. Pose checkpoints from facebook/sapiens2-pose-1b (0.4B is notably worse on hands and face) go into ComfyUI/models/sapiens2. No pip dependencies, but you need a recent ComfyUI - this pack targets the newer io.ComfyNode API.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| sapiens2_model | SAPIENS2_MODEL | — | |
| output_format | COMBO | openpose | 2 options: openpose, raw_308 |
| include_face | BOOLEAN | false | — |
| frames_per_batch | INT | 11–256 | Frames per forward pass. Lower if you OOM. |
| bboxesopt | BOUNDING_BOX | [object Object] | Person bboxes (RT-DETR / SDPoseFaceBBoxes / SAM3). When given, each person is cropped+warped individually (matches upstream Sapiens2 inference). Without bboxes, the whole image is resized — only correct when input is already a single-person crop. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| keypoints | POSE_KEYPOINT | — |