# DWPose
[](https://badge.fury.io/py/controlnet-dwpose)
[](https://github.com/kapong/controlnet_dwpose/actions)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/Apache-2.0)
[](https://colab.research.google.com/gist/kapong/588227d8209143975bfc09da90c08f12/dwpose.ipynb)
A standalone Python library for whole-body pose estimation extracted from the [ControlNeXt](https://github.com/dvlab-research/ControlNeXt) project.
> **Note**: This is a modified version of the DWPose implementation from the original ControlNeXt repository. The code has been restructured for standalone use and includes API improvements for better usability.
## ⚠️ AI Generation Disclaimer
This repository's packaging, documentation, and API improvements were generated with assistance from Claude AI. While the core DWPose algorithms remain unchanged from the original research implementations, the following components were created using AI assistance:
- Repository structure and packaging (setup.py, requirements.txt)
- Documentation (README.md, CLAUDE.md)
- API improvements and code organization
- Installation and usage examples
The original DWPose research and implementation credit belongs to the respective authors (Yang et al. and Peng et al.). This packaging is provided for educational and research purposes.
## Overview
DWPose provides dense keypoint detection for body, hands, and face using ONNX Runtime. It supports both CPU and GPU inference and is designed for efficient pose estimation in images and videos.
## Features
- **Whole-body pose estimation**: Detects body (18 keypoints), hands (21 keypoints each), and face (68 keypoints)
- **ONNX Runtime support**: Efficient inference with CPU and CUDA providers
- **Video processing**: Temporal consistency with pose rescaling across frames
- **Memory efficient**: Lazy loading and explicit memory management
- **Easy to use**: Simple API with minimal setup
## Installation
### From PyPI (when available)
```bash
pip install controlnet_dwpose
```
### From source
```bash
git clone https://github.com/kapong/controlnet_dwpose.git
cd controlnet_dwpose
pip install -e .
```
### Dependencies
Install required dependencies:
```bash
pip install -r requirement.txt
```
## Quick Start
### Basic Usage
```python
import cv2
import numpy as np
from controlnet_dwpose import DWposeDetector
# Initialize detector
detector = DWposeDetector(
model_det="yolox_l.onnx",
model_pose="dw-ll_ucoco_384.onnx",
device='cpu' # or 'cuda'
)
# Load image
image = cv2.imread('example/02.jpeg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# Detect poses
pose_result = detector(image)
# Access results
bodies = pose_result['bodies']
hands = pose_result['hands']
faces = pose_result['faces']
# Clean up memory when done
detector.release_memory()
```
### Processing Images with Customizable Thickness
```python
from controlnet_dwpose.preprocess import get_image_pose
from controlnet_dwpose import set_thickness_multiplier, get_thickness_multiplier
# Method 1: Using the new API functions (recommended)
current_thickness = get_thickness_multiplier() # Get current value (default: 3)
set_thickness_multiplier(2) # Set thinner lines
# set_thickness_multiplier(5) # Or set thicker lines
# Method 2: Direct access (legacy)
import controlnet_dwpose.util as util
util.thickness_mul = 2 # Thinner lines
# Get pose visualization
pose_image = get_image_pose(detector, image)
# Convert from CHW to HWC format for display
pose_image = pose_image.transpose(1, 2, 0)
# Display or save
import matplotlib.pyplot as plt
plt.imshow(pose_image)
plt.axis('off')
plt.show()
```
### Processing Videos
```python
from controlnet_dwpose.preprocess import get_video_pose
from controlnet_dwpose import set_thickness_multiplier
# Configure thickness for video processing
set_thickness_multiplier(2)
# Process video with pose rescaling
pose_sequence = get_video_pose(
dwprocessor=detector,
video_path="path/to/video.mp4",
ref_image=reference_image,
sample_stride=1
)
```
### Advanced Usage with Custom Visualization
```python
from controlnet_dwpose.util import draw_pose
from controlnet_dwpose import set_thickness_multiplier
# Set custom thickness
set_thickness_multiplier(4)
# Get pose data
pose_result = detector(image)
height, width = image.shape[:2]
# Create custom visualization
pose_canvas = draw_pose(pose_result, height, width)
# Convert to displayable format
pose_image = pose_canvas.transpose(1, 2, 0) # CHW to HWC
```
## Thickness Configuration
The library provides configurable thickness for pose visualization through dedicated API functions:
### API Functions
```python
from controlnet_dwpose import set_thickness_multiplier, get_thickness_multiplier
# Get current thickness multiplier (default: 3)
current_thickness = get_thickness_multiplier()
print(f"Current thickness: {current_thickness}")
# Set new thickness multiplier
set_thickness_multiplier(2) # Thinner lines
set_thickness_multiplier(5) # Thicker lines
set_thickness_multiplier(1.5) # Fine control with float values
# Verify the change
new_thickness = get_thickness_multiplier()
print(f"New thickness: {new_thickness}")
```
### Effects on Visualization
The thickness multiplier affects:
- **Body pose lines**: Line width = 4 × thickness_multiplier
- **Body keypoints**: Circle radius = 4 × thickness_multiplier
- **Hand pose lines**: Line width = 2 × thickness_multiplier
- **Hand keypoints**: Circle radius = 4 × thickness_multiplier
- **Face keypoints**: Circle radius = 3 × thickness_multiplier
### Legacy Access
For backward compatibility, direct access is still supported:
```python
import controlnet_dwpose.util as util
util.thickness_mul = 2 # Direct assignment
```
## Model Requirements
You need to download the ONNX models:
1. **Detection model**: `yolox_l.onnx` - YOLOX-L for human detection
2. **Pose model**: `dw-ll_ucoco_384.onnx` - DWPose for keypoint estimation
### Download Models
Install gdown for downloading from Google Drive:
```bash
pip install gdown
```
Download the required models:
```python
import gdown
# Download pose estimation model
gdown.download('https://drive.google.com/uc?id=12L8E2oAgZy4VACGSK9RaZBZrfgx7VTA2', 'dw-ll_ucoco_384.onnx', quiet=False)
# Download detection model
gdown.download('https://drive.google.com/uc?id=1w9pXC8tT0p9ndMN-CArp1__b2GbzewWI', 'yolox_l.onnx', quiet=False)
```
Or from command line:
```bash
gdown 'https://drive.google.com/uc?id=12L8E2oAgZy4VACGSK9RaZBZrfgx7VTA2' -O dw-ll_ucoco_384.onnx
gdown 'https://drive.google.com/uc?id=1w9pXC8tT0p9ndMN-CArp1__b2GbzewWI' -O yolox_l.onnx
```
## Output Format
The pose detection returns a dictionary with:
- `bodies`: Body keypoints with shape `(N, 18, 2)` for N detected persons
- `hands`: Hand keypoints with shape `(N, 42, 2)` (both hands combined)
- `faces`: Face keypoints with shape `(N, 68, 2)`
- `*_score`: Confidence scores for each keypoint type
Coordinates are normalized (0-1) relative to image dimensions.
## Requirements
- Python >= 3.7
- numpy
- opencv-python
- onnxruntime-gpu (or onnxruntime for CPU-only)
- torch
- matplotlib
- decord
- tqdm
## Attribution
This code is extracted and packaged from the ControlNeXt project:
- **ControlNeXt Repository**: [dvlab-research/ControlNeXt](https://github.com/dvlab-research/ControlNeXt)
- **Source Directory**: [ControlNeXt-SVD-v2/dwpose](https://github.com/dvlab-research/ControlNeXt/tree/main/ControlNeXt-SVD-v2/dwpose)
- **ControlNeXt Authors**: Bohao Peng, Jian Wang, Yuechen Zhang, Wenbo Li, Ming-Chang Yang, Jiaya Jia
### Original DWPose
The DWPose implementation used by Peng et al. in ControlNeXt is based on the original DWPose research:
- **Original DWPose Repository**: [IDEA-Research/DWPose](https://github.com/IDEA-Research/DWPose)
- **Original DWPose Authors**: Zhendong Yang, Ailing Zeng, Chun Yuan, Yu Li
- **Paper**: "Effective Whole-body Pose Estimation with Two-stages Distillation" (ICCV 2023)
### Modifications
This repository contains the following modifications from the original ControlNeXt implementation:
- **Standalone packaging**: Restructured as an independent Python package with proper setup.py
- **API improvements**: Enhanced function signatures for better usability
- **Documentation**: Added comprehensive README, examples, and installation instructions
- **Dependency management**: Proper requirements.txt and package dependencies
- **Model download**: Integrated Google Drive download links for pre-trained models
- **Memory management**: Improved memory cleanup and resource handling
### Citation
If you use this code, please cite both the ControlNeXt paper and the original DWPose paper:
```bibtex
@article{peng2024controlnext,
title={ControlNeXt: Powerful and Efficient Control for Image and Video Generation},
author={Peng, Bohao and Wang, Jian and Zhang, Yuechen and Li, Wenbo and Yang, Ming-Chang and Jia, Jiaya},
journal={arXiv preprint arXiv:2408.06070},
year={2024}
}
@inproceedings{yang2023effective,
title={Effective Whole-body Pose Estimation with Two-stages Distillation},
author={Yang, Zhendong and Zeng, Ailing and Yuan, Chun and Li, Yu},
booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},
pages={4210--4219},
year={2023}
}
```
## License
This project is licensed under the Apache License 2.0 - see the original [ControlNeXt repository](https://github.com/dvlab-research/ControlNeXt) for details.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Issues
If you encounter any problems, please open an issue on the [GitHub repository](https://github.com/your-username/dwpose/issues).
Raw data
{
"_id": null,
"home_page": "https://github.com/kapong/controlnet_dwpose",
"name": "controlnet-dwpose",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "pose-estimation controlnext controllable-generation onnx",
"author": "P.Phienphanich",
"author_email": "garpong@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/ad/e1/1041bc7e49b89976ad59a50bb13f9588bf59c7d67f41421d9e50b0cfa572/controlnet_dwpose-0.1.4.tar.gz",
"platform": null,
"description": "# DWPose\n\n[](https://badge.fury.io/py/controlnet-dwpose)\n[](https://github.com/kapong/controlnet_dwpose/actions)\n[](https://www.python.org/downloads/)\n[](https://opensource.org/licenses/Apache-2.0)\n[](https://colab.research.google.com/gist/kapong/588227d8209143975bfc09da90c08f12/dwpose.ipynb)\n\nA standalone Python library for whole-body pose estimation extracted from the [ControlNeXt](https://github.com/dvlab-research/ControlNeXt) project.\n\n> **Note**: This is a modified version of the DWPose implementation from the original ControlNeXt repository. The code has been restructured for standalone use and includes API improvements for better usability.\n\n## \u26a0\ufe0f AI Generation Disclaimer\n\nThis repository's packaging, documentation, and API improvements were generated with assistance from Claude AI. While the core DWPose algorithms remain unchanged from the original research implementations, the following components were created using AI assistance:\n\n- Repository structure and packaging (setup.py, requirements.txt)\n- Documentation (README.md, CLAUDE.md)\n- API improvements and code organization\n- Installation and usage examples\n\nThe original DWPose research and implementation credit belongs to the respective authors (Yang et al. and Peng et al.). This packaging is provided for educational and research purposes.\n\n## Overview\n\nDWPose provides dense keypoint detection for body, hands, and face using ONNX Runtime. It supports both CPU and GPU inference and is designed for efficient pose estimation in images and videos.\n\n## Features\n\n- **Whole-body pose estimation**: Detects body (18 keypoints), hands (21 keypoints each), and face (68 keypoints)\n- **ONNX Runtime support**: Efficient inference with CPU and CUDA providers\n- **Video processing**: Temporal consistency with pose rescaling across frames\n- **Memory efficient**: Lazy loading and explicit memory management\n- **Easy to use**: Simple API with minimal setup\n\n## Installation\n\n### From PyPI (when available)\n```bash\npip install controlnet_dwpose\n```\n\n### From source\n```bash\ngit clone https://github.com/kapong/controlnet_dwpose.git\ncd controlnet_dwpose\npip install -e .\n```\n\n### Dependencies\nInstall required dependencies:\n```bash\npip install -r requirement.txt\n```\n\n## Quick Start\n\n### Basic Usage\n\n```python\nimport cv2\nimport numpy as np\nfrom controlnet_dwpose import DWposeDetector\n\n# Initialize detector\ndetector = DWposeDetector(\n model_det=\"yolox_l.onnx\",\n model_pose=\"dw-ll_ucoco_384.onnx\",\n device='cpu' # or 'cuda'\n)\n\n# Load image\nimage = cv2.imread('example/02.jpeg')\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n# Detect poses\npose_result = detector(image)\n\n# Access results\nbodies = pose_result['bodies']\nhands = pose_result['hands']\nfaces = pose_result['faces']\n\n# Clean up memory when done\ndetector.release_memory()\n```\n\n### Processing Images with Customizable Thickness\n\n```python\nfrom controlnet_dwpose.preprocess import get_image_pose\nfrom controlnet_dwpose import set_thickness_multiplier, get_thickness_multiplier\n\n# Method 1: Using the new API functions (recommended)\ncurrent_thickness = get_thickness_multiplier() # Get current value (default: 3)\nset_thickness_multiplier(2) # Set thinner lines\n# set_thickness_multiplier(5) # Or set thicker lines\n\n# Method 2: Direct access (legacy)\nimport controlnet_dwpose.util as util\nutil.thickness_mul = 2 # Thinner lines\n\n# Get pose visualization\npose_image = get_image_pose(detector, image)\n\n# Convert from CHW to HWC format for display\npose_image = pose_image.transpose(1, 2, 0)\n\n# Display or save\nimport matplotlib.pyplot as plt\nplt.imshow(pose_image)\nplt.axis('off')\nplt.show()\n```\n\n### Processing Videos\n\n```python\nfrom controlnet_dwpose.preprocess import get_video_pose\nfrom controlnet_dwpose import set_thickness_multiplier\n\n# Configure thickness for video processing\nset_thickness_multiplier(2)\n\n# Process video with pose rescaling\npose_sequence = get_video_pose(\n dwprocessor=detector,\n video_path=\"path/to/video.mp4\",\n ref_image=reference_image,\n sample_stride=1\n)\n```\n\n### Advanced Usage with Custom Visualization\n\n```python\nfrom controlnet_dwpose.util import draw_pose\nfrom controlnet_dwpose import set_thickness_multiplier\n\n# Set custom thickness\nset_thickness_multiplier(4)\n\n# Get pose data\npose_result = detector(image)\nheight, width = image.shape[:2]\n\n# Create custom visualization\npose_canvas = draw_pose(pose_result, height, width)\n\n# Convert to displayable format\npose_image = pose_canvas.transpose(1, 2, 0) # CHW to HWC\n```\n\n## Thickness Configuration\n\nThe library provides configurable thickness for pose visualization through dedicated API functions:\n\n### API Functions\n\n```python\nfrom controlnet_dwpose import set_thickness_multiplier, get_thickness_multiplier\n\n# Get current thickness multiplier (default: 3)\ncurrent_thickness = get_thickness_multiplier()\nprint(f\"Current thickness: {current_thickness}\")\n\n# Set new thickness multiplier\nset_thickness_multiplier(2) # Thinner lines\nset_thickness_multiplier(5) # Thicker lines\nset_thickness_multiplier(1.5) # Fine control with float values\n\n# Verify the change\nnew_thickness = get_thickness_multiplier()\nprint(f\"New thickness: {new_thickness}\")\n```\n\n### Effects on Visualization\n\nThe thickness multiplier affects:\n- **Body pose lines**: Line width = 4 \u00d7 thickness_multiplier\n- **Body keypoints**: Circle radius = 4 \u00d7 thickness_multiplier \n- **Hand pose lines**: Line width = 2 \u00d7 thickness_multiplier\n- **Hand keypoints**: Circle radius = 4 \u00d7 thickness_multiplier\n- **Face keypoints**: Circle radius = 3 \u00d7 thickness_multiplier\n\n### Legacy Access\n\nFor backward compatibility, direct access is still supported:\n\n```python\nimport controlnet_dwpose.util as util\nutil.thickness_mul = 2 # Direct assignment\n```\n\n## Model Requirements\n\nYou need to download the ONNX models:\n\n1. **Detection model**: `yolox_l.onnx` - YOLOX-L for human detection\n2. **Pose model**: `dw-ll_ucoco_384.onnx` - DWPose for keypoint estimation\n\n### Download Models\n\nInstall gdown for downloading from Google Drive:\n```bash\npip install gdown\n```\n\nDownload the required models:\n```python\nimport gdown\n\n# Download pose estimation model\ngdown.download('https://drive.google.com/uc?id=12L8E2oAgZy4VACGSK9RaZBZrfgx7VTA2', 'dw-ll_ucoco_384.onnx', quiet=False)\n\n# Download detection model \ngdown.download('https://drive.google.com/uc?id=1w9pXC8tT0p9ndMN-CArp1__b2GbzewWI', 'yolox_l.onnx', quiet=False)\n```\n\nOr from command line:\n```bash\ngdown 'https://drive.google.com/uc?id=12L8E2oAgZy4VACGSK9RaZBZrfgx7VTA2' -O dw-ll_ucoco_384.onnx\ngdown 'https://drive.google.com/uc?id=1w9pXC8tT0p9ndMN-CArp1__b2GbzewWI' -O yolox_l.onnx\n```\n\n## Output Format\n\nThe pose detection returns a dictionary with:\n\n- `bodies`: Body keypoints with shape `(N, 18, 2)` for N detected persons\n- `hands`: Hand keypoints with shape `(N, 42, 2)` (both hands combined)\n- `faces`: Face keypoints with shape `(N, 68, 2)`\n- `*_score`: Confidence scores for each keypoint type\n\nCoordinates are normalized (0-1) relative to image dimensions.\n\n## Requirements\n\n- Python >= 3.7\n- numpy\n- opencv-python\n- onnxruntime-gpu (or onnxruntime for CPU-only)\n- torch\n- matplotlib\n- decord\n- tqdm\n\n## Attribution\n\nThis code is extracted and packaged from the ControlNeXt project:\n\n- **ControlNeXt Repository**: [dvlab-research/ControlNeXt](https://github.com/dvlab-research/ControlNeXt)\n- **Source Directory**: [ControlNeXt-SVD-v2/dwpose](https://github.com/dvlab-research/ControlNeXt/tree/main/ControlNeXt-SVD-v2/dwpose)\n- **ControlNeXt Authors**: Bohao Peng, Jian Wang, Yuechen Zhang, Wenbo Li, Ming-Chang Yang, Jiaya Jia\n\n### Original DWPose\n\nThe DWPose implementation used by Peng et al. in ControlNeXt is based on the original DWPose research:\n\n- **Original DWPose Repository**: [IDEA-Research/DWPose](https://github.com/IDEA-Research/DWPose)\n- **Original DWPose Authors**: Zhendong Yang, Ailing Zeng, Chun Yuan, Yu Li\n- **Paper**: \"Effective Whole-body Pose Estimation with Two-stages Distillation\" (ICCV 2023)\n\n### Modifications\n\nThis repository contains the following modifications from the original ControlNeXt implementation:\n\n- **Standalone packaging**: Restructured as an independent Python package with proper setup.py\n- **API improvements**: Enhanced function signatures for better usability\n- **Documentation**: Added comprehensive README, examples, and installation instructions\n- **Dependency management**: Proper requirements.txt and package dependencies\n- **Model download**: Integrated Google Drive download links for pre-trained models\n- **Memory management**: Improved memory cleanup and resource handling\n\n### Citation\n\nIf you use this code, please cite both the ControlNeXt paper and the original DWPose paper:\n\n```bibtex\n@article{peng2024controlnext,\n title={ControlNeXt: Powerful and Efficient Control for Image and Video Generation},\n author={Peng, Bohao and Wang, Jian and Zhang, Yuechen and Li, Wenbo and Yang, Ming-Chang and Jia, Jiaya},\n journal={arXiv preprint arXiv:2408.06070},\n year={2024}\n}\n\n@inproceedings{yang2023effective,\n title={Effective Whole-body Pose Estimation with Two-stages Distillation},\n author={Yang, Zhendong and Zeng, Ailing and Yuan, Chun and Li, Yu},\n booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n pages={4210--4219},\n year={2023}\n}\n```\n\n## License\n\nThis project is licensed under the Apache License 2.0 - see the original [ControlNeXt repository](https://github.com/dvlab-research/ControlNeXt) for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Issues\n\nIf you encounter any problems, please open an issue on the [GitHub repository](https://github.com/your-username/dwpose/issues).\n",
"bugtrack_url": null,
"license": null,
"summary": "DWPose component from ControlNeXt for whole-body pose estimation",
"version": "0.1.4",
"project_urls": {
"Bug Reports": "https://github.com/kapong/controlnet_dwpose/issues",
"Homepage": "https://github.com/kapong/controlnet_dwpose",
"Original ControlNeXt": "https://github.com/dvlab-research/ControlNeXt",
"Original DWPose": "https://github.com/IDEA-Research/DWPose",
"Source": "https://github.com/kapong/controlnet_dwpose"
},
"split_keywords": [
"pose-estimation",
"controlnext",
"controllable-generation",
"onnx"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5da4bb5145ecd6ac1a72368f8d2df360d393c8c2556c76d4caad89babdeab4de",
"md5": "7ddc3258fb1848cc33e6bc45888262fe",
"sha256": "bd74aba421183d3c987503056c2c51d8067e8fd7a26208b16a0c65bb3ac02d9d"
},
"downloads": -1,
"filename": "controlnet_dwpose-0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7ddc3258fb1848cc33e6bc45888262fe",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 19934,
"upload_time": "2025-07-18T09:21:16",
"upload_time_iso_8601": "2025-07-18T09:21:16.118698Z",
"url": "https://files.pythonhosted.org/packages/5d/a4/bb5145ecd6ac1a72368f8d2df360d393c8c2556c76d4caad89babdeab4de/controlnet_dwpose-0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ade11041bc7e49b89976ad59a50bb13f9588bf59c7d67f41421d9e50b0cfa572",
"md5": "aeadc3d20d27c5387cc2e878df5891e9",
"sha256": "c9d522d6f6448c04f61714dfcbcb549fe3a9519f58b2a0c5ea74d1b792042ce0"
},
"downloads": -1,
"filename": "controlnet_dwpose-0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "aeadc3d20d27c5387cc2e878df5891e9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 23266,
"upload_time": "2025-07-18T09:21:17",
"upload_time_iso_8601": "2025-07-18T09:21:17.159329Z",
"url": "https://files.pythonhosted.org/packages/ad/e1/1041bc7e49b89976ad59a50bb13f9588bf59c7d67f41421d9e50b0cfa572/controlnet_dwpose-0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-18 09:21:17",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "kapong",
"github_project": "controlnet_dwpose",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "controlnet-dwpose"
}