Nodes/ComfyUI-UtilsCollection/Batched OpenPose Pose
ComfyUI Node

Batched OpenPose Pose

OpenPose That Actually Enjoys Being Fed a Video

By silveroxides·Created 3 months ago·Updated about 12 hours ago· 35
Batched OpenPose Pose
  • image
  • image
  • pose_keypoint
  • Pose Overlay Mask
detect_handtrue
detect_bodytrue
detect_facetrue
resolution0
batch_size4
scale_stick_for_xinsr_cnfalse
body_threshold0.45
hand_threshold0.45
face_threshold0.45
limb_threshold0.45
limb_support0.80
min_body_parts4
min_body_score0.40
temporal_filterfalse
temporal_radius2
temporal_min_support2
temporal_max_distance0.10
temporal_match_iou0.30

If you've ever run a pose pass over a 200-frame clip with the classic OpenPose preprocessor, you know the shape of that afternoon. UC_BatchedOpenPose is a from-scratch, eager-PyTorch OpenPose implementation that takes an image batch - a video frame sequence - and works through it in chunks, with a video-specific filter tacked on.

It ships in ComfyUI-UtilsCollection, a kitchen-sink pack from silveroxides - obscure enough that you'll be reading tooltips, not forum threads.

What it actually does

Pose conditioning still matters in the edit-model era: an edit model has no strength dial, so partial strength - or two conditions at once - still means ControlNet. OpenPose is the pose half of that, with 17 body joints, 70 face landmarks and 21 points per hand.

Mechanically it's the classic 2017 pipeline: the body model predicts heatmaps plus part-affinity fields, joints fall out of the heatmaps, and the affinity field is what decides whether two joints are actually connected. Then it crops boxes around the detected hands and face and runs those models on the crops.

Unlike comfyui_controlnet_aux, none of Ultralytics, ONNX Runtime, MMPose or TorchScript is a runtime dependency here. But the author is upfront in the README that speed and prediction parity against the original preprocessors "need real-model validation" - the converted weights are verified for shape/dtype/value correctness, not for matching the reference implementation joint for joint. If your whole pipeline is tuned around exact legacy pose maps, test before you rebuild anything.

The inputs worth touching

image takes the batch; for the temporal options, feed consecutive frames in order, not a folder of unrelated pictures.

detect_hand, detect_face and detect_body all default on. Hand and face off genuinely skips those models - that's your speed lever. Body off does not skip body inference; it only stops drawing it, because body inference is what locates the hands and faces in the first place.

resolution (0 = leave the frames as supplied, otherwise the shortest edge in pixels) and batch_size (default 4) are the memory pair. Drop batch_size first if you're running out of VRAM, since hand and face crops are also processed batch_size at a time.

The body threshold cluster is where you tune quality: body_threshold (0.45), hand_threshold, face_threshold, limb_threshold (how much evidence a limb line needs), limb_support (0.8 - the fraction of sampled limb points that must pass limb_threshold, and strictly, so 1 rejects everything), min_body_parts (4) and min_body_score (0.4, not a probability). Raising them rejects junk skeletons and partly-visible people along with it.

Below-threshold face landmarks are kept as empty slots rather than dropped, so landmark indices can't shift between frames of a video.

Then there are the six temporal options, off by default: temporal_filter, temporal_radius (2), temporal_min_support (2), temporal_max_distance (0.1 = 10% of the body-box diagonal), temporal_match_iou (0.3). It prunes joints that nearby frames can't confirm, from both the drawing and the keypoints. It does not smooth, and it does not fill anything in. Matching spans your batch_size chunks, so raising the batch doesn't break the filter. Leave it off for unrelated stills.

Outputs

image is the pose map in frame order - the thing you feed a pose ControlNet. pose_keypoint is OpenPose-format keypoints after thresholding and temporal filtering. Pose Overlay Mask is white on drawn limbs and points, black elsewhere: handy for compositing the pose map over your footage. It's not a person silhouette.

Install

Manager → search "ComfyUI-UtilsCollection", or:

cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-UtilsCollection
# restart ComfyUI

Models are not in the repo. They download on first execution from silveroxides/ComfyUI-UtilsCollection-Models via huggingface_hub, and land flat in ComfyUI/models/controlnet/preprocessors (registered off your normal controlnet roots, so extra model paths work). Files: openpose_body.safetensors, openpose_hand.safetensors, openpose_face.safetensors. To place them yourself:

mkdir -p ComfyUI/models/controlnet/preprocessors
huggingface-cli download silveroxides/ComfyUI-UtilsCollection-Models \
  preprocessors/openpose/openpose_body.safetensors --local-dir /tmp/uc
cp /tmp/uc/preprocessors/openpose/openpose_body.safetensors \
  ComfyUI/models/controlnet/preprocessors/

Where people get burned

The node imports kornia at module load, and kornia isn't in the pack's requirements.txt. If you don't already have it from another pack, the whole node pack fails to import until you pip install kornia in ComfyUI's environment. Same story for torchaudio, scipy and torchvision, which the pack also imports - those normally arrive with ComfyUI, kornia often doesn't.

The first queue with the pack installed hits the network. Offline or behind a proxy, you get a download error instead of a pose map; pre-place the three files above and it will reuse them.

One more install detail: this pack is written against ComfyUI's newer V3 node schema (comfy_api.latest) and uses autogrow/dynamic inputs, so it wants a current ComfyUI. On an old build you get import errors and missing nodes, not a subtly wrong pose map.

And the usual one: a pose map is only as good as the ControlNet reading it. Current union models want their published scale - 0.65–0.8 on most 2026 ones - so don't carry an SDXL-era 1.0 across and then blame the estimator.

Categoryimage/pose

Inputs (19)

NameTypeDefaultDescription
imageIMAGEImage or image batch to process. For temporal filtering, supply consecutive video frames in order, not unrelated images.
detect_handBOOLEANtrueDetect and draw hand joints. Turn off to skip the hand model and reduce processing time; hand keypoints will be omitted.
detect_bodyBOOLEANtrueDraw body skeletons. Body inference still locates hands/faces and produces keypoints.
detect_faceBOOLEANtrueDetect and draw facial landmarks. Turn off to skip the face model and reduce processing time; face keypoints will be omitted.
resolutionINT00–40960 preserves the input dimensions. A positive value sets the output's shortest edge in pixels, preserving aspect ratio. Larger maps do not increase the body model's fixed processing scale.
batch_sizeINT41–64Maximum frames or person crops per network call. Lower this if VRAM is insufficient.
scale_stick_for_xinsr_cnBOOLEANfalseScale body-line thickness with image size for Xinsir-style pose maps. Changes drawing only, not detected coordinates.
body_thresholdFLOAT0.450–1Minimum strength of a body-joint candidate. Raise to reject weak joints; lower to recover faint joints at the risk of false detections.
hand_thresholdFLOAT0.450–1Minimum strength of a hand-joint candidate. Raise to remove uncertain fingers; lower to retain more joints. Only used when hand detection is on.
face_thresholdFLOAT0.450–1Minimum strength of a facial landmark. Raise to remove uncertain points; lower to retain more detail. Only used when face detection is on.
limb_thresholdFLOAT0.450–1Required evidence along the line connecting two body joints. Raise to reject unlikely limb connections; too high can break valid skeletons.
limb_supportFLOAT0.800–1Fraction of sampled positions along a limb that must pass limb_threshold; the accepted fraction must be strictly greater. Raise for stricter connections; 1 rejects every connection.
min_body_partsINT41–18Minimum connected joints needed to keep a person. Raise to reject tiny false skeletons; lower for partly visible people.
min_body_scoreFLOAT0.400–10Minimum average skeleton score, combining joint and connection evidence. Raise to reject weak people; lower for difficult poses. This is not a probability.
temporal_filterBOOLEANfalseVideo frames only: remove joints unsupported by nearby frames from both pose maps and keypoints. Keeps person entries; does not smooth or fill missing joints. Leave off for unrelated images.
temporal_radiusINT21–30Temporal filter only: frames to inspect before and after each frame. 2 checks up to four neighbors, across batch_size chunks. Larger windows cost more and may reject fast motion.
temporal_min_supportINT21–60Temporal filter only: neighboring frames that must confirm a joint. Raise to remove more flicker; lower to retain brief poses. Limited to available neighbors, including at clip edges.
temporal_max_distanceFLOAT0.100.001–1Temporal filter only: allowed joint displacement relative to the person's body-box diagonal; 0.1 means 10%. Raise for faster motion; lower to reject sudden jumps.
temporal_match_iouFLOAT0.300–1Temporal filter only: required overlap between body boxes to match a person across frames. Raise to avoid mixing people; lower for faster movement or changing boxes.

Outputs (3)

NameTypeDescription
imageIMAGEPose maps in input-frame order, showing the enabled body, hand and face drawings.
pose_keypointPOSE_KEYPOINTPer-frame OpenPose-format keypoints after thresholding and optional temporal filtering. Disabled hand/face detectors omit those landmarks.
Pose Overlay MaskMASKWhite on rendered pose lines and points; black elsewhere. Use to composite the pose map over an image or video. Matches pose-map size and frame order; not a person silhouette.