Nodes/Teskor's Utils/TS Pose Data Smoother
ComfyUI Node

TS Pose Data Smoother

OpenPose jitter is ruining your video ControlNet. This is the fix.

By teskor-hub·Created 8 months ago·Updated 9 days ago· 4
TS Pose Data Smoother
  • pose_data
  • IMAGE
  • pose_data
filter_extra_peopletrue
smooth_alpha0.70
gap_frames12
min_run_frames3
conf_thresh_body0.35
conf_thresh_hands0.60
force_body_18false
smooth_handsfalse
smooth_facetrue

Raw OpenPose output jitters. Keypoints vibrate while the subject stands still, joints drop out for a frame and pop back, a limb occasionally snaps to somewhere impossible. Feed that into ControlNet OpenPose and your generated video inherits every bit of it - the wobble becomes the motion. TS Pose Data Smoother cleans the whole pose sequence before it reaches generation: temporal smoothing, gap filling, outlier rejection, and real subject tracking. It's the flagship of the Teskor's Utils pack and, if you do any pose-driven video on Wan, AnimateDiff, or ControlNet, the reason to install it.

The name is accurate but undersells it. This isn't a moving-average slapped on keypoints - it's a multi-stage pipeline. It decides which person is the subject, then repairs the skeleton frame by frame.

How it works

Stage zero is the part most smoothers skip: OpenPose returns an unordered list of people per frame with no identity across frames, so the node first stitches detections into tracks over the whole clip and picks the main subject. It scores each track on how much of the clip it covers, how large it is (closer to camera), how centrally it sits, and its mean confidence. That combination matters more than it sounds - ranking purely by "appears in the most frames" loses to a steadily-detected bystander the moment the real subject's detection flickers, which is exactly the footage you're trying to repair.

Then the cleanup, roughly: spatial outlier suppression, gap fill, short-run rejection, a 3-tap median filter, a zero-lag EMA (run forward and backward so it can't introduce phase lag), and finally a velocity-predictive causal EMA with a per-step limit - smooths jitter without clipping real motion. The author reports subject-tracking error dropping from 150.6px to 10.2px against a synthetic ground-truth skeleton, across three seeds.

The inputs that matter

You get a pose_data in, a smoothed pose_data plus a rendered preview IMAGE out. Of the eight widgets, a beginner sets maybe three:

  • smooth_alpha (0.7) - the one to touch. Higher tracks raw detection more closely; lower is smoother but lags fast motion. Start at the default.
  • gap_frames (12) - longest dropout, in frames, that gets interpolated rather than left empty. Bump it if your detector keeps losing the subject for stretches.
  • min_run_frames (3) - detections that appear for fewer frames than this are treated as noise and removed.

The rest are reasonable out of the box: filter_extra_people (true) keeps only the tracked subject and drops bystanders; conf_thresh_body (0.35) and conf_thresh_hands (0.6) gate low-confidence keypoints. Two optional flags matter when they apply: force_body_18 truncates the 25-joint BODY_25 skeleton to the first 18 (COCO) for consumers that reject the 25-joint layout, and smooth_hands (experimental) extends the pipeline to the 21 finger keypoints. Hands are left untouched by default - "hand jitter" in the arms is fixed, fingers are not, unless you flip it on. That's deliberate, so updating the node can't change output you already like.

Outputs: pose_data → ControlNet OpenPose or your AnimateDiff/Wan conditioning. IMAGE → a rendered preview of the smoothed subject so you can see exactly what you're feeding forward without wiring up a separate renderer.

Install

Part of Teskor's Utils. ComfyUI Manager → search Teskor's Utils → Install → Restart. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/teskor-hub/comfyui-teskors-utils
pip install -r comfyui-teskors-utils/requirements.txt

Restart, find it under TS Utils/Pose. Deps are numpy and opencv-python only - no model downloads, no PyTorch (ComfyUI already ships it, and the README is explicit about not letting pip touch it).

Where people get burned

Wire it as Load Video → OpenPose Detection → TS Pose Data Smoother → ControlNet OpenPose → Generation, and if your output still shimmies, check two things. First, smooth_alpha - if fast motion looks rubbery, raise it toward 0.9. Second, gap_frames - set too high on fast footage, interpolation over a long dropout produces limbs that stretch. And remember smooth_hands is off: if the fingers are what's jittering, you have to opt in. There are example workflows in the repo - openpose smoother example.json, plus a full WanVideo pipeline alongside Kijai's nodes.

CategoryTS Utils/Pose

Inputs (10)

NameTypeDefaultDescription
pose_dataPOSEDATA
filter_extra_peopleBOOLEANtrue
smooth_alphaFLOAT0.700.01–0.99
gap_framesINT120–100
min_run_framesINT31–60
conf_thresh_bodyFLOAT0.350–1
conf_thresh_handsFLOAT0.600–1
force_body_18optBOOLEANfalseTruncate the body skeleton to the first 18 joints (COCO), for consumers that reject the 25-joint BODY_25 layout.
smooth_handsoptBOOLEANfalseEXPERIMENTAL: also clean and smooth the hand keypoints. Off by default; leaving it off reproduces previous output exactly.
smooth_faceoptBOOLEANtrueClean and temporally smooth the native DWPose/OpenPose face keypoints. Enabled by default so facial landmarks do not flicker between frames.

Outputs (2)

NameTypeDescription
IMAGEIMAGE
pose_dataPOSEDATA