Convert Tracking To BBoxes
Turn Pose Tracking Into Boxes You Can Actually Crop
- tracking
- bboxes
Pose tracking data from InstanceDiffusion's Upper Body Tracking From PoseKps node is rich - head, neck, shoulders, torso, arms, all tracked per person per frame - but it comes in a custom TRACKING format that most crop and conditioning nodes can't read. TrackingToBBoxScheduler is the bridge: it converts that tracking data into plain bounding boxes and, in the same pass, lets you pick which person and which body part you want, with the same frame-by-frame schedule control as its sibling BBoxScheduler. One node, convert and filter.
How it works
It walks the tracking data frame by frame, takes the rectangles for the body part you selected (All covers everything), and writes them out as standard BOUNDING_BOX dicts - {"x", "y", "width", "height"} - one list per frame. Then the filtering kicks in exactly like BBoxScheduler: a person_index to keep one person's boxes (0 = everyone, 1+ = that specific person), and an optional schedule string of frame_index:person_index pairs to swap which person is kept partway through the clip when the tracker's person ordering jumps around.
Why this matters: say you're doing face-crop animation with multiple people in frame. Pick body_part = Head, person_index = 1, and you get a clean per-frame box of exactly person one's head, ready to crop. No detector noise, no whole-person bounding box with half the frame's background in it - just the region you wanted, filtered to the person you meant. That's the Wan 2.2 animation use case the author built the pack for: crop one character's head precisely, per frame, even when faces cross.
There's also insert_dummy_bbox, same as its sibling - when a frame ends up with nothing to output (person out of frame, part occluded), it emits a one-pixel box at (0,0) instead of an empty list, which keeps downstream crop nodes from choking.
The inputs that matter
- tracking - the
TRACKINGdata. Unlike the pure-bbox nodes, this input is compatible with the KJ node ecosystem, so it drops into existing KJ-style pose pipelines. - body_part - which part becomes the box:
All,Head,Neck,Shoulder,Torso,LArm,RArm,LForearm,RForearm.Headis the face-crop workhorse. - person_index and schedule - the person selection and the frame-swap string, exactly as in
BBoxScheduler. - insert_dummy_bbox - the one-pixel safety box for empty frames.
The single output, bboxes, is the filtered list - same BOUNDING_BOX type the rest of the pack uses, feeding whatever crop node your workflow already has.
Installing it
Via ComfyUI Manager: search ComfyUI-BBoxNodes. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/masternc80/ComfyUI-BBoxNodes
cd ComfyUI-BBoxNodes && pip install -r requirements.txt
Restart, done. The whole pack only needs pillow and no model downloads, but it does target the newer comfy_api.latest extension API - stale ComfyUI installs won't see the node, so update if it's missing.
Troubleshooting
The output is not KJNodes-compatible even though the input is - you can take tracking from KJ-land, but what comes out is this pack's BOUNDING_BOX format, so your crop node has to accept that. And schedule indices are 1-based, consistent with person_index; a schedule of 0:1, 30:2 means person 1 from frame 0, then person 2 from frame 30. If the boxes you get are mysteriously off, double-check your body_part - a Torso box is not a head box, and both are valid outputs here.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| tracking | TRACKING | Tracking data from InstanceDiffusion | |
| person_index | INT | 00–10 | The person index on the image starting from 1. 0 for all persons |
| body_part | COMBO | All | The body part on the image to draw rectangle for |
| insert_dummy_bbox | BOOLEAN | Insert dummy one-pixel bbox when all bboxes are filtered out | |
| scheduleopt | STRING | Schedule in format 'frame_index:person_index, ...' |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| bboxes | BOUNDING_BOX | Output bboxes (Not compatible with KJNodes) |