Nodes/ComfyUI-BodyRatioMapper/BodyRatioMapper SDPose Render
ComfyUI Node

BodyRatioMapper SDPose Render

Turn your pose keypoints into the skeleton image a ControlNet expects

By wuwukaka·Created 4 months ago·Updated about a month ago· 142
BodyRatioMapper SDPose Render
  • pose_keypoint
  • image
resolution_x-1
score_threshold0.30
scale_for_xinsirfalse
stick_width4
face_point_size3
draw_facetrue
draw_mouthtrue
draw_handstrue
draw_feettrue
draw_thightrue
draw_calftrue

Every node in this pack speaks POSE_KEYPOINT - a data structure, not an image. But the thing your ControlNet and your motion-transfer pipeline actually want to see is a picture of a skeleton. BodyRatioMapperSDPoseRender is the bridge: it takes SDPose keypoints and draws them as a stick-figure image you can preview, save, or feed straight into a pose ControlNet.

Why use this one instead of any of the dozen OpenPose renderers floating around? Two reasons. First, it's built to match the SDPose whole-body rendering style - 134 keypoints (18 body, 6 feet, 68 face, 21 per hand) in the exact order the SDPose detector emits them, including the foot and face landmarks most basic renderers drop. Second, it has the scale_for_xinsir toggle, which applies the adaptive stick-thickness scaling that Xinsir's ControlNet models were trained with. If you've ever rendered a pose and watched a ControlNet barely react, this is often why: your line weights didn't match what the model was trained on. Flip that toggle on and the rendering matches Xinsir's expectations.

The inputs that matter

Required input is pose_keypoint, SDPose format. Output is a single IMAGE tensor - frames batched, ready for a PreviewImage node or a ControlNet.

Four controls cover almost everything:

  • resolution_x (default -1) - output width in pixels; -1 means "keep the original canvas size from the keypoint data." Set it to your generation width to avoid scale mismatches downstream.
  • score_threshold (default 0.3) - keypoints below this confidence get skipped. Low-confidence jitter is a big source of flickery poses; raise this a touch on noisy footage.
  • stick_width (default 4) - skeleton line width. This is the knob that most affects how a pose ControlNet reads the image.
  • scale_for_xinsir - adaptive thickness scaling for Xinsir ControlNet models. Reach for it when a pose ControlNet seems to ignore fine detail.

The draw_face, draw_hands, draw_feet, draw_mouth, draw_thigh, and draw_calf toggles are genuinely useful, not decoration. The thigh/calf pair is the one people sleep on: some pose ControlNets (and some artists) want only the upper-body skeleton, and turning off the legs keeps the image from dragging the character's legs around when the detection was noisy. face_point_size sets the face landmark radius.

One nice touch in the code: it auto-detects whether your coordinates are normalized (0–1) or in pixels and rescales accordingly, so a mismatched detector output doesn't give you a skeleton drawn in a corner of the frame.

Where it fits

In the pack's standard flow, you chain ProportionTransfer → (Bone Scale / Translate if you're tweaking) → this render node → PreviewImage, so you can actually see whether the proportion mapping did what you wanted before you waste a generation on it. From here the image goes into a ControlNet pose preprocessor input - the ControlNet Auxiliary pack's OpenPose_Preprocessor doesn't fit this flow because you already have the keypoints; this node is your pose preprocessor. The whole-body layout also means face and hand control surfaces survive the trip, which is what you want for character consistency work.

Installation and gotchas

Installation is the pack's standard one (clone into custom_nodes, pip install -r requirements.txt, restart) - see the main ProportionTransfer page. No model downloads.

The classic mistake is feeding it OpenPose-format input with only 17 body joints. It won't crash - it renders what's there - but face, feet, and hands will be blank, and you'll be left wondering why the output looks sparser than the input. Confirm your keypoints have the full SDPose arrays via pose_keypoint preview if output looks thin. Also remember the output is a black-background skeleton: that's correct and normal for ControlNet conditioning - don't try to fix the "black background," that's what pose ControlNets expect.

One note on expectations: this is a pure keypoint renderer. It draws what it's given; it won't fix detection errors, extrapolate missing joints, or smooth jitter. If your rendered skeleton is jittery frame to frame, the problem is upstream in the detector or in ProportionTransfer's stabilizer settings, not here.

CategoryBodyRatioMapper

Inputs (12)

NameTypeDefaultDescription
pose_keypointPOSE_KEYPOINTSDPose format POSE_KEYPOINT data
resolution_xoptINT-1-1–12800Output width (-1 for original)
score_thresholdoptFLOAT0.300–1
scale_for_xinsiroptBOOLEANfalseApply adaptive thickness scaling used in Xinsir ControlNet
stick_widthoptINT41–32Skeleton line width
face_point_sizeoptINT31–16Face keypoint radius
draw_faceoptBOOLEANtrue
draw_mouthoptBOOLEANtrue
draw_handsoptBOOLEANtrue
draw_feetoptBOOLEANtrue
draw_thighoptBOOLEANtrue
draw_calfoptBOOLEANtrue

Outputs (1)

NameTypeDescription
imageIMAGE