Install SDK
Install the Python wheel, Node package, or release bundle on the machine that will run tracking.
Sky Tracker is a C++ CPU tracker exposed through a CLI, Python binding, and Node.js wrapper. The current SDK does not automatically classify every aircraft or drone in a scene: you seed it with an initial bounding box, then it locks, coasts, reacquires, and reports frame-level telemetry.
Install the Python wheel, Node package, or release bundle on the machine that will run tracking.
Use the SDK to print the 32-character request token for that device before requesting access.
Paste the generated SDK request token into the evaluation form so the key can be issued.
Packaged builds validate SKY_TRACKER_LICENSE_KEY or sky_tracker.lic before tracker initialization.
Provide an initial x,y,w,h bbox or select it interactively, then read telemetry from CSV, JSON, or SDK objects.
The tracker is optimized for small, fast-moving targets in video: drones, birds, aircraft, and similar high-contrast objects. You choose the target once, either with an explicit bbox or an interactive selector, and the runtime follows that object frame by frame.
Use the CLI for batch video jobs, Python when you already own the OpenCV frame loop, and Node.js when a service needs to launch tracking runs and parse output files.
Sky Tracker is a selected-target tracker, not a general detector. The initial bbox tells the runtime what object to follow. After that, call update for each frame and read the returned target position, bounding box, state, and confidence.
Provide one or more initial bounding boxes, either directly or with the interactive selector.
The tracker follows each selected object and updates its position and visible bounding box.
If the object is briefly unclear, the tracker can predict its motion and try to recover it without changing its ID.
Each update returns the target ID, position, bbox, state, confidence, and optional diagnostic fields.
The first bbox becomes the tracker reference. A tight box focuses scoring on the target; a loose box teaches the tracker background pixels and can make drift more likely.
The motion model uses frame time to estimate speed and predict where to search next. For offline video, pass a deterministic dt from FPS so results are repeatable.
Evaluation builds are licence-gated and evaluation keys can be locked to a device. Before submitting the access request form, install the SDK on the target device, generate the SDK request token, and attach that token to the form.
The SDK request token is generated locally by the SDK. It is used to issue the evaluation key for that device; it is not a password and does not provide remote access.
Select the tab for your target operating system. To generate the SDK request token, choose one option in that tab: either the Python wheel command or the release bundle CLI command. You do not need to run both.
After access is granted, set the environment variable in the same terminal or process that imports the SDK or starts the CLI, or use a sky_tracker.lic file containing the raw token.
The licence file path is resolved in this order: explicit CLI --license-file, SKY_TRACKER_LICENSE_KEY, SKY_TRACKER_LICENSE_FILE, sky_tracker.lic next to the executable, then sky_tracker.lic in the current working directory.
# Choose ONE option below. Run it on the device that will run Sky Tracker.# Option A: Python wheelpip install sky-tracker-sdkpython -c "import sky_tracker; print(sky_tracker.get_machine_id())"# Option B: release bundle CLI.\sky-tracker-sdk\bin\sky_tracker.exe --get-machine-idpip install sky-tracker-sdk$env:SKY_TRACKER_LICENSE_KEY = "SKT1.<your-token>"npm install @sky-tracker/node$env:SKY_TRACKER_LICENSE_KEY = "SKT1.<your-token>"Expand-Archive .\sky-tracker-sdk-0.1.6-2026-05-31.zip .\sky-tracker-sdk$env:SKY_TRACKER_LICENSE_KEY = "SKT1.<your-token>".\sky-tracker-sdk\bin\sky_tracker.exe --helpSKT1.<your-token>$env:SKY_TRACKER_LICENSE_FILE = ".\sky_tracker.lic"sky_tracker --source footage.mp4 --bbox 715,174,32,20sky_tracker --license-file .\sky_tracker.lic --source footage.mp4 --bbox 715,174,32,20The bbox format is always x,y,w,h in original frame pixels. Tight boxes usually work better than loose boxes because template matching has less background to learn.
sky_tracker --source footage.mp4 --bbox 715,174,32,20 --csv track.csvsky_tracker --source footage.mp4 --select-target --display --csv track.csvThe CLI is the quickest path for evaluation videos. It can emit CSV and JSON telemetry, write annotated output, limit frame count, and apply profiles or low-level tuning flags.
sky_tracker --source footage.mp4 --bbox 715,174,32,20 --profile default --csv track.csv --json track.json --max-frames 500sky_tracker --source footage.mp4 --bbox 715,174,32,20 --target-search 220 --target-max-speed 1600 --target-surrounding-clutter 0.35 --target-reacquire-stride 2Python gives direct access to OpenCV frames and result objects. Pass a deterministic dt for offline video so speed and prediction are repeatable.
import cv2import sky_trackercap = cv2.VideoCapture("footage.mp4")ok, frame = cap.read()if not ok: raise RuntimeError("failed to read first frame")tracker = sky_tracker.Tracker("default")tracker.lock(frame, bbox=(715, 174, 32, 20))fps = cap.get(cv2.CAP_PROP_FPS) or 30.0dt = 1.0 / fpswhile True: ok, frame = cap.read() if not ok: break result = tracker.update(frame, dt=dt) if not result.lost: print(result.frame, result.center(), result.confidence, result.reason)For multiple selected targets, initialize every bbox together. Each result keeps the same stable target_id assigned at lock time. If objects become too close to separate confidently, a result may briefly be suppressed instead of switching IDs.
multi = sky_tracker.MultiTracker("default")multi.lock(frame, bboxes=[ (715, 174, 32, 20), (804, 168, 30, 22),])results = multi.update(frame, dt=dt)for result in results: print( result.target_id, result.state, result.bbox(), result.suppressed, result.prediction_only, )The Node.js package wraps the CLI-style video workflow. It is useful for workers, backend jobs, dashboards, and CSV parsing without building an OpenCV frame loop in JavaScript.
import { trackVideo, parseTrackCsv } from "@sky-tracker/node";const run = await trackVideo({ source: "footage.mp4", bbox: [715, 174, 32, 20], profile: "default", maxFrames: 500, csv: "track.csv",});const rows = await parseTrackCsv(run.csv);console.log(run.metrics);console.log(rows.at(-1));CSV rows and SDK results expose the same core state: position, bbox, track lifecycle, confidence, and the internal reason for the selected update path.
frame,id,state,center_x,center_y,speed_px_s,bbox_x,bbox_y,bbox_w,bbox_h,hits,misses,target_score,target_candidate_score,target_confidence,target_reason,target_anchor_appearance,target_suppressed,target_suppressed_by_id,target_interacting,target_model_learning_suppressed,target_geometry_update_suppressed,target_geometry_ownership_constrained,target_geometry_confidence,target_prediction_onlyconfirmed, tentative, or lost.
Normalized confidence for the selected target update.
Reason string such as template, contrast, coast, or reacquire.
Stable selected-target ID assigned from initialization.
True when the target coasted because ownership was ambiguous or another target owned the observation.
The owning target ID, or 0 when no unique owner could be selected.
True while this target is inside a guarded close interaction.
True when visible bbox geometry was clipped to this target's ownership cell.
Confidence of the accepted owned geometry measurement.
True when the output is a short-gap motion prediction rather than a confirmed image observation.
Prediction-only rows are explicit motion estimates. They never update appearance or bbox geometry and should not be treated as confirmed image observations.
Profiles are starting points, not guarantees. Pick the closest one, then adjust bbox quality, search padding, maximum speed, and clutter penalty based on your footage.
Older names such as pi4-target, adaptive-target, hybrid-target, and sota-target remain accepted as deprecated compatibility aliases. New integrations should use the three canonical names above.
Sky Tracker is a local CPU tracker, not a general detector or classifier. It performs best when the target is visible, has stable contrast, and is seeded accurately in the first frame used for tracking.
During a close interaction, an ambiguous target may temporarily coast or report suppression instead of jumping to its neighbour. Its bbox may pause until the objects separate.
A long complete overlap between visually identical targets is not observable from RGB frames alone. The tracker preserves motion and anchor state and waits for separation rather than inventing identity confidence.
Use the repaired wheel or release bundle so OpenCV runtime DLLs are included.
Set SKY_TRACKER_LICENSE_KEY or pass the correct licence file before creating a tracker. If the key is device-locked, confirm it was issued for the current SDK request token.
Check that x,y,w,h are in original video pixels, not a scaled preview size.
Start with a tighter bbox, try a profile, or increase --target-search for fast targets.
Start with --profile default, lower input resolution, reduce target count, or shorten reacquisition search before enabling more expensive adaptive geometry.