ComfyUI Node

Openpose Render Node

The 'ultimate' OpenPose renderer that detects nothing — and why that's the point

By westNeighbor·Created 2 years ago·Updated 2 years ago· 16
Openpose Render Node
  • POSE_KEYPOINT
  • IMAGE
show_bodytrue
show_facetrue
show_handstrue
resolution_x-1
pose_marker_size4
face_marker_size3
hand_marker_size2
POSE_JSON

If you've ever run a DWPose or OpenPose preprocessor and wished you could do something with the stick figure besides take it as-is - draw only the body, drop the hands, make it bigger - this is the node for you. Openpose Render Node takes pose keypoints or classic OpenPose JSON and redraws them onto a clean black canvas, outputting an IMAGE ready to feed a ControlNet.

The name is doing some lifting. "Ultimate" suggests a detector, but it's a pure renderer: no pose models, no weights, no API, nothing to download. You hand it pose data, it draws the skeleton you already have. Detection happens upstream, in the ControlNet Auxiliary Preprocessors' DWPose/OpenPose nodes.

Honest take: if your whole pipeline is image → DWPose preprocessor → ControlNet, you don't strictly need this - the preprocessor already outputs a rendered pose map. This node earns its place when you want control over that render: body-only conditioning (hand keypoints are notorious for steering a model toward weird fingers), a specific output width to match your latent size, or pose data that never existed as an image - pasted OpenPose JSON, exported pose files, or output from the author's sibling project, the interactive ComfyUI-ultimate-openpose-editor. And because it loops over every frame in the pose data, a pose sequence becomes a batch of skeletons for per-frame ControlNet work in animation.

How it works

Two pose inputs, and only one matters at a time. POSE_KEYPOINT takes the wire type straight off a ControlNet Aux preprocessor (its second output); POSE_JSON is the same data as multiline text. Priority is explicit: POSE_KEYPOINT wins if both are connected - the README calls it out, and the code backs it up.

Both inputs end up parsed as the classic OpenPose JSON schema: a list of frames, each with people, canvas_width, and canvas_height, where each person carries pose_keypoints_2d, face_keypoints_2d, hand_left_keypoints_2d, and hand_right_keypoints_2d as x/y/confidence triplets. That's exactly what ControlNet Aux's modern DWPose emits - its UI even prints an openpose_json blob you can copy straight into POSE_JSON.

The drawing is the OpenPose look you already know: rainbow-colored limb sticks and joint dots for the body (18 keypoints), HSV-tinted lines with red joints for hands, white dots for the face, all on a black canvas via OpenCV. Coordinates auto-normalize - if keypoints peak above 2.0 they're treated as pixel coords and divided by width/height, otherwise assumed 0–1. A single dict gets auto-wrapped into a list.

The inputs that matter

  • POSE_KEYPOINT - the wire from a ControlNet Aux DWPose/OpenPose preprocessor, or from a pose editor.
  • POSE_JSON - same data as text, when you don't have the wire.
  • show_body / show_face / show_hands - toggle what gets rendered, all true by default.
  • resolution_x - output width; height follows the source aspect ratio. Default -1 (anything under 64) means "keep the original canvas width."
  • pose_marker_size / face_marker_size / hand_marker_size - stick and dot thickness, defaults 4/3/2.

Output: a single IMAGE tensor (floats 0–1). Wire it into a ControlNet node with an openpose-family model (match dw_openpose to a DWPose source, openpose to an OpenPose source), then on to your KSampler. Or just drop a PreviewImage on it and look at what the ControlNet is actually being fed - usually the most instructive thing you can do.

Install

Easiest via ComfyUI Manager (search "ultimate-openpose"), or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/westNeighbor/ComfyUI-ultimate-openpose-render
cd ComfyUI-ultimate-openpose-render
pip install -r requirements.txt

Portable installs use the embedded interpreter, e.g. E:/ComfyUI_windows_portable/python_embeded/python.exe -m pip install -r requirements.txt. Then restart ComfyUI and find it under Right-click → ultimate-openpose → Openpose Render Node. No model downloads. One quirk: requirements.txt lists polygraphy, an NVIDIA tool the node never imports - harmless bloat, ignore it.

Common issues

  • Feed it a photo and it errors. It renders, it doesn't detect. Detection is the preprocessor's job upstream. If neither input has usable data - no keypoint wire, empty JSON - you get ValueError: Invalid input type. Expected an input to give an output. That's the node's actual error, and it's telling you the truth.
  • You edited POSE_JSON but nothing changed. Check whether a POSE_KEYPOINT wire is still connected - it silently overrides the text field.
  • Empty or malformed JSON renders nothing. It must be the OpenPose people schema with canvas_width/canvas_height; arbitrary detector dumps without a people key come back empty.
  • Hands/face toggles do nothing. The node can only render keypoints the preprocessor actually detected - DWPose's detect_hand/detect_face options gate what's in the data in the first place.

Small, dependency-light, one job done well. Not the flashiest node in the graph - just the one that turns pose data into exactly the control signal you meant to send.

Categoryultimate-openpose

Inputs (9)

NameTypeDefaultDescription
show_bodyoptBOOLEANtrue
show_faceoptBOOLEANtrue
show_handsoptBOOLEANtrue
resolution_xoptINT-1-1–12800
pose_marker_sizeoptINT40–100
face_marker_sizeoptINT30–100
hand_marker_sizeoptINT20–100
POSE_JSONoptSTRING
POSE_KEYPOINToptPOSE_KEYPOINT

Outputs (1)

NameTypeDescription
IMAGEIMAGE