SDPose Keypoint Extractor
Whole-body pose from an SD checkpoint, no external preprocessor
- model
- vae
- image
- bboxes
- keypoints
Pose ControlNet has always had an ugly dependency: you needed a separate preprocessing pack - ControlNet Aux, DWPose, OpenPose - just to turn a photo into the stick figure that pose conditioning runs on. This node is ComfyUI core's answer. It runs SDPose, a whole-body pose model that happens to be a diffusion checkpoint, and it ships natively with ComfyUI (since February 2026). No extra pack, no Python environment roulette.
The twist is the model. SDPose is built on the idea that an image-generation model's internal knowledge makes a great computer-vision backbone - the same "prior knowledge" trick as Marigold for depth. ComfyUI loads it like any checkpoint, then this node reaches into the diffusion model, captures mid-network features, and reads pose keypoints off a dedicated heatmap head. It outputs the classic OpenPose format: body joints, feet, face landmarks, and both hands, in pixel coordinates with confidence scores.
How it works
For each image (or each crop, if you give it boxes), the image gets encoded to latent space through a VAE, then run through the model for a single denoising step with zero noise - a "just look at it" pass. The node intercepts the 640-channel feature maps via a patch, feeds them to the model's heatmap head, and gets keypoints plus scores back. Those are remapped from the model's working resolution back to your image's coordinates, the neck joint is synthesized from the shoulders, and everything is reordered from the model's internal MMPose layout into OpenPose order. That last bit is why the output looks right in every downstream tool.
The inputs and outputs that matter
- model - the SDPose checkpoint. Drop
sdpose_wholebody_fp16.safetensorsinmodels/checkpoints/and load it with a checkpoint loader. If the model isn't an SDPose model, the node refuses with a "no heatmap_head" error - it can't extract pose from a regular SD checkpoint. - vae - from the same checkpoint. It needs a VAE to encode crops into the model's latent space.
- image - the input, or a batch.
- batch_size - images per forward pass in full-image mode (default 16). Raise it for faster batch processing, lower it if you're memory-constrained.
- bboxes - the one that matters most: required for multi-person detection. Without boxes, the model does one full-image pass and returns one person. Feed it per-person boxes (from
SDPoseFaceBBoxesfor faces, or any detector) and it runs each crop separately, which is both more accurate and multi-person-capable.
The keypoints output is a POSE_KEYPOINT in OpenPose frame format - canvas_width, canvas_height, people, each with flat [x, y, score] lists for body, feet, face, and hands.
Wiring it up
Keypoints aren't an image, and they aren't conditioning. To actually use them you route through the rest of the family: SDPoseDrawKeypoints turns them into the stick-figure IMAGE that a pose ControlNet conditions on, and SDPoseFaceBBoxes turns them into face crops for a second, more accurate extraction pass. It's a three-node pipeline that replaces an entire preprocessor pack - and it's a strong argument for dropping DWPose from your setup if you're already on modern ComfyUI.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| vae | VAE | — | |
| image | IMAGE | — | |
| batch_size | INT | 161–10000 | — |
| bboxesopt | BOUNDING_BOX | [object Object] | Optional bounding boxes for more accurate detections. Required for multi-person detection. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| keypoints | POSE_KEYPOINT | Keypoints in OpenPose frame format (canvas_width, canvas_height, people) |