Image Color Track Bind (Pro)
Pin an Image to a Moving Colored Object, the OpenCV Way
- image
- video_frames
- mask
- output_frames
Want to stick a logo onto a moving coffee cup, or attach a sprite to someone's red hat across a whole video clip - without drawing masks every frame? Image Color Track Bind (Pro) is SwiftCut's attempt at that: classic OpenCV color tracking, packaged as one node. Feed it a still image (the thing you want pasted) and a video batch (the footage), pick a color, and it tracks the biggest blob of that color through every frame and keeps your image glued to it.
"Pro" is doing a lot of work here. This isn't a learned object detector - no model, no weights, no GPU. It's the old-school technique: match pixels near a color, find contours, track the biggest one, paste. That's both the appeal (instant, zero setup) and the ceiling (one color, one blob, and it loses hard objects that blend into the background).
How it works, under the hood
For every frame of video_frames it:
- Converts to HSV and masks pixels within
color_toleranceoftarget_color(hex, default#FF0000red). - Erodes/dilates to kill noise, finds contours, and scores candidates by area - with a distance penalty from the previous frame's center so it doesn't jump to a random blob mid-clip.
- Rescales your overlay
imagebybase_scale, rotates it ifenable_rotationis on, and pastes it centered on the tracked point, plusanchor_offset_x/yin pixels for fine positioning. - Also optional:
maskcontrols the overlay's alpha (where the sticker is actually visible), not the tracking region.
The tracking data gets smoothed with an exponential moving average (smoothing_factor, lower = more stable, higher = more jittery) and any frames where the color disappears get linear-interpolated positions rather than dropped - so a couple of bad frames won't rip your sticker off the object.
The extras are where "Pro" earns its name: enable_auto_scale sizes the overlay to the contour's area (so the sticker grows as the object gets closer), rotation_offset fixes the starting angle, and motion_blur_strength smears the overlay along its own motion vector - the touch that makes a glued-on PNG look less fake. Processing happens at processing_width (default 640px) for speed, then centers get mapped back to full resolution.
The install gotcha that will bite you
Here's the thing nobody tells you: this node imports cv2, and the pack's requirements.txt doesn't list opencv. If you don't already have opencv-python in your ComfyUI environment, the node simply won't appear in your menu. The pack's __init__.py loads each node file in a try/except and skips the ones that fail, so the rest of SwiftCut shows up fine and ColorTrack silently vanishes. Fix:
cd ComfyUI/custom_nodes/ComfyUI_SwiftCut
pip install opencv-python
then restart ComfyUI. If you see every other SwiftCut node but not this one, that's your culprit.
Using it well
target_color is a hex string (#FF0000 default). color_tolerance is the single knob for how much shade variation counts as "the color" - start at 30 and raise it if tracking drops out under lighting changes, but know that a high tolerance starts swallowing everything near that hue. Smoothing at 0.1 is a sane starting point; push it toward 0.9 only if the sticker is wiggling too much, and accept lag in return.
Install is otherwise the standard pack dance - ComfyUI Manager, search "ComfyUI_SwiftCut", or:
cd ComfyUI/custom_nodes
git clone https://github.com/yichengup/ComfyUI_SwiftCut
The realistic use cases are stickers, subtitles-as-sprites, logo burns, or attaching labels to a colored prop in an AI-generated clip. Just don't expect it to track a face - for that you'd want a real tracker. This is a color matcher with a paste-on-top habit, and for exactly that job it's remarkably capable for being three dozen lines of OpenCV.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| video_frames | IMAGE | — | |
| target_color | STRING | #FF0000 | — |
| color_tolerance | INT | 300–255 | — |
| smoothing_factor | FLOAT | 0.100–0.99 | — |
| processing_width | INT | 640100–4096 | — |
| anchor_offset_x | INT | 0 | — |
| anchor_offset_y | INT | 0 | — |
| base_scale | FLOAT | 1.000.1–10 | — |
| enable_rotation | BOOLEAN | false | — |
| rotation_offset | FLOAT | 0.00-360–360 | — |
| enable_auto_scale | BOOLEAN | false | — |
| motion_blur_strength | FLOAT | 0.00–5 | — |
| maskopt | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| output_frames | IMAGE | — |