Unblend Pose Engine
Anime pose detection that actually sees anime
- image
- pose_image
- bodies_json
Here's a niche annoyance that eats a whole evening: you want to ControlNet-pose an anime character, you run the standard DWPose preprocessor, and the skeleton comes out scattered - the head box lands at the neck, the limbs read as a 2D pinboard. DWPose was trained on COCO, i.e. real people, and anime proportions (big head, long legs) break its assumptions. UnblendPoseEngine exists to give you a second engine that was also trained on drawn characters, and it's one of the quietly useful nodes in this pack.
The two engines
dwpose- the imgutils DWPose backend. It's the standard everywhere, and it's the one that misreads anime. The pack keeps it as an option, not because it's wrong, but because it's already installed viadghs-imgutilsand works fine on photo-real input.rtmlib_humanart- RTMPose-m (halpe26 keypoints) paired with YOLOX-m-HumanArt, a detector trained on seven datasets including HumanArt, which is actual drawn/cartoon characters. This is the recommended engine for anime, and it's the whole reason the node exists: one switch and the "scattered skeleton" problem mostly disappears.
Both produce the same output: an OpenPose RGB image for ControlNet and a JSON of detected bodies. Wire pose_image into a ControlNet Apply node with an OpenPose model, and you've got pose conditioning that respects the way anime bodies actually are.
The inputs that matter
pose_engine-rtmlib_humanartfor anime,dwposefor photos. This is the headline choice.box_source-heads+silhouette(default) detects heads first, then derives a body box per head from the foreground silhouette, because head boxes don't merge the way full-body boxes do on overlapping characters.detectorjust runs the internal YOLOX. For duo art, keep the default.det_conf- only affects rtmlib. The default is 0.3 (the original rtmlib used 0.7), and for two+ characters the README says to drop it to 0.25–0.4 so the detector doesn't collapse the second body into the first.device- defaults tocpuand that's deliberate, see below.
The best trick is the optional out_bboxes_json input: feed it the box JSON from a character detector like DeepghsCharSeg or AnimeCharDetectSeg, and the node skips detection entirely, computing one clean skeleton strictly per character box. For trio art, that's the difference between a mess and something usable.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/LatentDesireAI/ComfyUI-Unblend
pip install -r ComfyUI-Unblend/requirements.txt
The rtmlib and onnxruntime deps install from requirements.txt; rtmlib's weights download automatically from HuggingFace on the first run. Manager users get all of this for free by searching "Unblend". DWPose needs nothing extra - it rides along with dghs-imgutils.
Troubleshooting
The device default of cpu isn't paranoia: on CUDA 13 dev / RTX 50xx, onnxruntime's GPU path dies with a missing cublasLt64_12.dll, and mixing onnxruntime-GPU into the same process as a CUDA 13 torch can actually break your UNet (the pack's own __init__.py calls out the Windows DLL-name collision explicitly). The node catches that and falls back to CPU automatically, printing a one-time warning. CPU is slow but fine for a pose pass.
If a character comes back missing entirely, that's detection, not pose - lower det_conf or hand the node explicit boxes via out_bboxes_json. If a skeleton is there but half its joints are absent, lower point_conf: joints scoring at or below the cutoff are dropped from the render, so a cutoff set too high leaves you with a skeleton missing its hands. And if pose_engine fails to load at all (missing rtmlib), it falls back to DWPose rather than crashing - you'll see it in the console.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| pose_engine | COMBO | 2 options: rtmlib_humanart, dwpose | |
| box_source | COMBO | 2 options: heads+silhouette, detector | |
| device | COMBO | cpu | 2 options: cpu, cuda |
| det_conf | FLOAT | 0.300.05–0.9 | — |
| point_conf | FLOAT | 0.300.05–0.95 | — |
| pose_canvas_size | INT | 512128–2048 | — |
| out_bboxes_jsonopt | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| pose_image | IMAGE | — |
| bodies_json | STRING | — |