DWPose Estimator
The pose detector for OpenPose ControlNet
- image
- IMAGE
- POSE_KEYPOINT
If you want a generated character in a specific pose - arms crossed, mid-jump, sitting cross-legged - you don't describe it in the prompt and pray. You hand the model a skeleton. DWPose Estimator (class name DWPreprocessor) looks at a reference image and draws that skeleton: colored bone lines, a constellation of face dots, the fingers. That skeleton feeds an OpenPose ControlNet, which forces your generation to match the pose. It's the good version of pose detection - the "improved pose detector, better hand detection" that replaced the original OpenPose estimator for most people, and the one to reach for by default.
It ships inside ComfyUI's ControlNet Auxiliary Preprocessors (Fannovel16's pack), the preprocessor toolbox for the whole ControlNet ecosystem - depth, canny, lineart, normals, pose, all of it. Without it, ControlNet is limited to conditions you prepare externally, which is why the pack is functionally required for any serious ControlNet workflow. DWPose is one of its headline nodes.
How it works
It's a two-stage pipeline, which is why it has two model dropdowns. A bbox detector (a YOLO-family object detector) finds where the people are and boxes them; a pose estimator then runs on each box and regresses the keypoints - joints, face landmarks, finger positions. DWPose is a whole-body model, so unlike the older OpenPose estimator it does body, hands, and face in one pass, and the hands notably better. The node renders all that into the standard OpenPose "stick figure" hint image that ControlNet models were trained to read.
The skeleton is model-agnostic in the useful sense: detect a pose once and you can drive it into an SD 1.5 openpose ControlNet, an SDXL union, or a modern Flux/Qwen/Z-Image union - they all still carry a pose condition. Only the ControlNet checkpoint changes.
The inputs and outputs that matter
The only required input is image - the reference photo to copy the pose from. Everything else is optional and mostly best left alone.
The three you'll actually touch:
detect_hand/detect_body/detect_face- toggles (enable/disable) for which keypoint groups get drawn. All default to enable. Turndetect_faceoff if the face dots pin your generated face too hard to the reference; keepdetect_handon - hands are the whole reason people switched to DWPose.resolution- the detection pass resolution (default 512, steps of 64). Bump to 768 or 1024 for a big or busy image where the skeleton comes out sloppy; costs a bit more time.
The two model dropdowns - bbox_detector and pose_estimator - matter for speed, not correctness (see troubleshooting). scale_stick_for_xinsr_cn is a niche toggle for one specific xinsir SDXL ControlNet; leave it disabled otherwise.
Two outputs: IMAGE is the rendered pose skeleton - wire it into your ControlNet Apply node. POSE_KEYPOINT is the structured data (OpenPose-format JSON) for editing the pose in a pose-editor node rather than just rendering it.
How to install it
Easiest path is 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/
cd comfyui_controlnet_aux
python -m pip install -r requirements.txt # use ComfyUI's python (python_embeded on portable)
then restart. The DWPose model files download automatically on first run from HuggingFace, so the first time you queue the node it'll pause to pull a few hundred MB. That's normal; let it finish.
Common issues & troubleshooting
"DWPose might run very slowly" / it's pegging your CPU. This is the DWPose gotcha, a genuine rite of passage. You'll see Onnxruntime not found ... switch to OpenCV with CPU device. DWPose might run very slowly. Detection fell back to CPU, where it's painful. Two fixes, per the pack's Q&A. Simple: use the TorchScript checkpoints (the .torchscript.pt endings, which are the defaults) - GPU, no extra libraries, a touch slower than ONNX but way faster than CPU. Fussier: install onnxruntime-gpu and pick the .onnx checkpoints to hand the work to CUDA - but the prebuilt package historically wanted CUDA 11.8, so on a CUDA 12 setup that's its own rabbit hole. For most people TorchScript is the right answer.
A node from the pack didn't show up. The pack deliberately skips any node that fails to import rather than crashing the whole set, so a missing node usually means a dependency didn't install. Check the startup terminal log for the import error.
The pose comes out empty or garbage. DWPose has to actually find a person. Tiny figures, heavy occlusion, or very stylized art can defeat the bbox detector; raise resolution or crop tighter so the subject dominates the frame.
The result feels rigid. DWPose draws all three groups by default, so the ControlNet has a lot to adhere to. Disable detect_face (and sometimes detect_hand), or lower the ControlNet's strength and end its influence partway through denoising so the later steps stay the model's own - the most useful ControlNet habit there is, pose work included.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| detect_handopt | COMBO | enable | 2 options: enable, disable |
| detect_bodyopt | COMBO | enable | 2 options: enable, disable |
| detect_faceopt | COMBO | enable | 2 options: enable, disable |
| resolutionopt | INT | 51264–16384 | — |
| bbox_detectoropt | COMBO | yolox_l.onnx | 6 options: None, yolox_l.torchscript.pt, yolox_l.onnx, yolo_nas_l_fp16.onnx, yolo_nas_m_fp16.onnx, yolo_nas_s_fp16.onnx |
| pose_estimatoropt | COMBO | dw-ll_ucoco_384_bs5.torchscript.pt | 3 options: dw-ll_ucoco_384_bs5.torchscript.pt, dw-ll_ucoco_384.onnx, dw-ll_ucoco.onnx |
| scale_stick_for_xinsr_cnopt | COMBO | disable | 2 options: disable, enable |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| POSE_KEYPOINT | POSE_KEYPOINT | — |