tracktors 2.6.0.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. trackers/__init__.py +58 -0
  2. trackers/annotators/__init__.py +5 -0
  3. trackers/annotators/trace.py +219 -0
  4. trackers/core/__init__.py +5 -0
  5. trackers/core/base.py +683 -0
  6. trackers/core/botsort/__init__.py +8 -0
  7. trackers/core/botsort/cmc.py +47 -0
  8. trackers/core/botsort/tracker.py +503 -0
  9. trackers/core/botsort/tracklet.py +252 -0
  10. trackers/core/botsort/utils.py +92 -0
  11. trackers/core/bytetrack/__init__.py +5 -0
  12. trackers/core/bytetrack/tracker.py +427 -0
  13. trackers/core/bytetrack/tracklet.py +71 -0
  14. trackers/core/bytetrack/utils.py +65 -0
  15. trackers/core/cbiou/__init__.py +5 -0
  16. trackers/core/cbiou/tracker.py +335 -0
  17. trackers/core/ocsort/__init__.py +5 -0
  18. trackers/core/ocsort/tracker.py +416 -0
  19. trackers/core/ocsort/tracklet.py +371 -0
  20. trackers/core/ocsort/utils.py +113 -0
  21. trackers/core/sort/__init__.py +5 -0
  22. trackers/core/sort/tracker.py +294 -0
  23. trackers/core/sort/tracklet.py +84 -0
  24. trackers/core/sort/utils.py +153 -0
  25. trackers/datasets/__init__.py +7 -0
  26. trackers/datasets/download.py +167 -0
  27. trackers/datasets/manifest.py +144 -0
  28. trackers/eval/__init__.py +54 -0
  29. trackers/eval/box.py +194 -0
  30. trackers/eval/clear.py +365 -0
  31. trackers/eval/constants.py +17 -0
  32. trackers/eval/evaluate.py +421 -0
  33. trackers/eval/hota.py +350 -0
  34. trackers/eval/identity.py +235 -0
  35. trackers/eval/results.py +704 -0
  36. trackers/io/__init__.py +5 -0
  37. trackers/io/frames.py +67 -0
  38. trackers/io/mot.py +469 -0
  39. trackers/io/paths.py +40 -0
  40. trackers/io/video.py +164 -0
  41. trackers/motion/__init__.py +5 -0
  42. trackers/motion/estimator.py +225 -0
  43. trackers/motion/transformation.py +144 -0
  44. trackers/py.typed +0 -0
  45. trackers/scripts/__init__.py +5 -0
  46. trackers/scripts/__main__.py +70 -0
  47. trackers/scripts/download.py +109 -0
  48. trackers/scripts/eval.py +169 -0
  49. trackers/scripts/progress.py +232 -0
  50. trackers/scripts/track.py +738 -0
  51. trackers/scripts/tune.py +230 -0
  52. trackers/tune/__init__.py +11 -0
  53. trackers/tune/tuner.py +452 -0
  54. trackers/utils/__init__.py +5 -0
  55. trackers/utils/base_tracklet.py +113 -0
  56. trackers/utils/cmc.py +935 -0
  57. trackers/utils/converters.py +115 -0
  58. trackers/utils/detections.py +49 -0
  59. trackers/utils/device.py +30 -0
  60. trackers/utils/downloader.py +230 -0
  61. trackers/utils/general.py +73 -0
  62. trackers/utils/iou.py +202 -0
  63. trackers/utils/kalman_filter.py +155 -0
  64. trackers/utils/motion_models.py +204 -0
  65. trackers/utils/predict_timing.py +60 -0
  66. trackers/utils/state_representations.py +341 -0
  67. tracktors/__init__.py +20 -0
  68. tracktors/py.typed +1 -0
  69. tracktors-2.6.0.dev0.dist-info/METADATA +218 -0
  70. tracktors-2.6.0.dev0.dist-info/RECORD +74 -0
  71. tracktors-2.6.0.dev0.dist-info/WHEEL +5 -0
  72. tracktors-2.6.0.dev0.dist-info/entry_points.txt +3 -0
  73. tracktors-2.6.0.dev0.dist-info/licenses/LICENSE +201 -0
  74. tracktors-2.6.0.dev0.dist-info/top_level.txt +2 -0
trackers/__init__.py ADDED
@@ -0,0 +1,58 @@
1
+ # ------------------------------------------------------------------------
2
+ # Trackers
3
+ # Copyright (c) 2026 Roboflow. All Rights Reserved.
4
+ # Licensed under the Apache License, Version 2.0 [see LICENSE for details]
5
+ # ------------------------------------------------------------------------
6
+
7
+ from __future__ import annotations
8
+
9
+ from trackers.annotators.trace import MotionAwareTraceAnnotator
10
+ from trackers.core.botsort.tracker import BoTSORTTracker
11
+ from trackers.core.bytetrack.tracker import ByteTrackTracker
12
+ from trackers.core.cbiou.tracker import CBIoUTracker
13
+ from trackers.core.ocsort.tracker import OCSORTTracker
14
+ from trackers.core.sort.tracker import SORTTracker
15
+ from trackers.datasets.download import download_dataset
16
+ from trackers.datasets.manifest import Dataset, DatasetAsset, DatasetSplit
17
+ from trackers.io.mot import load_mot_file
18
+ from trackers.io.video import frames_from_source
19
+ from trackers.motion.estimator import MotionEstimator
20
+ from trackers.motion.transformation import (
21
+ CoordinatesTransformation,
22
+ HomographyTransformation,
23
+ IdentityTransformation,
24
+ )
25
+ from trackers.utils.cmc import CMC, CMCConfig, CMCMethod, CMCTMethod
26
+ from trackers.utils.converters import xcycsr_to_xyxy, xyxy_to_xcycsr
27
+ from trackers.utils.iou import BaseIoU, BIoU, CIoU, DIoU, GIoU, IoU
28
+
29
+ __all__ = [
30
+ "CMC",
31
+ "BIoU",
32
+ "BaseIoU",
33
+ "BoTSORTTracker",
34
+ "ByteTrackTracker",
35
+ "CBIoUTracker",
36
+ "CIoU",
37
+ "CMCConfig",
38
+ "CMCMethod",
39
+ "CMCTMethod",
40
+ "CoordinatesTransformation",
41
+ "DIoU",
42
+ "Dataset",
43
+ "DatasetAsset",
44
+ "DatasetSplit",
45
+ "GIoU",
46
+ "HomographyTransformation",
47
+ "IdentityTransformation",
48
+ "IoU",
49
+ "MotionAwareTraceAnnotator",
50
+ "MotionEstimator",
51
+ "OCSORTTracker",
52
+ "SORTTracker",
53
+ "download_dataset",
54
+ "frames_from_source",
55
+ "load_mot_file",
56
+ "xcycsr_to_xyxy",
57
+ "xyxy_to_xcycsr",
58
+ ]
@@ -0,0 +1,5 @@
1
+ # ------------------------------------------------------------------------
2
+ # Trackers
3
+ # Copyright (c) 2026 Roboflow. All Rights Reserved.
4
+ # Licensed under the Apache License, Version 2.0 [see LICENSE for details]
5
+ # ------------------------------------------------------------------------
@@ -0,0 +1,219 @@
1
+ # ------------------------------------------------------------------------
2
+ # Trackers
3
+ # Copyright (c) 2026 Roboflow. All Rights Reserved.
4
+ # Licensed under the Apache License, Version 2.0 [see LICENSE for details]
5
+ # ------------------------------------------------------------------------
6
+
7
+ from __future__ import annotations
8
+
9
+ from collections import defaultdict
10
+
11
+ import cv2
12
+ import numpy as np
13
+ import supervision as sv
14
+ from supervision.annotators.utils import ColorLookup, resolve_color
15
+ from supervision.draw.color import Color, ColorPalette
16
+ from supervision.geometry.core import Position
17
+
18
+ from trackers.motion.transformation import (
19
+ CoordinatesTransformation,
20
+ IdentityTransformation,
21
+ )
22
+
23
+
24
+ class MotionAwareTraceAnnotator:
25
+ """Draws object trajectories with camera motion compensation.
26
+
27
+ This annotator maintains a history of object positions in world coordinates
28
+ and draws them as trajectories (traces) on each frame. When used with camera
29
+ motion compensation, trajectories appear stable even when the camera moves.
30
+
31
+ The API is compatible with supervision annotators, using the same color
32
+ resolution strategy and position anchoring.
33
+
34
+ Args:
35
+ color: The color to draw the trace. Can be a single `Color` or a
36
+ `ColorPalette`. Defaults to `ColorPalette.DEFAULT`.
37
+ position: The anchor position on the bounding box for the trace point.
38
+ Defaults to `Position.CENTER`.
39
+ trace_length: Maximum number of points to store per trajectory.
40
+ Defaults to `30`.
41
+ thickness: Line thickness for drawing traces. Defaults to `2`.
42
+ color_lookup: Strategy for mapping colors to annotations.
43
+ Options are `INDEX`, `CLASS`, `TRACK`. Defaults to `ColorLookup.TRACK`.
44
+
45
+ Example:
46
+ ```python
47
+ import cv2
48
+ import supervision as sv
49
+ from inference import get_model
50
+
51
+ from trackers import (
52
+ ByteTrackTracker,
53
+ MotionAwareTraceAnnotator,
54
+ MotionEstimator,
55
+ )
56
+
57
+ model = get_model("rfdetr-nano")
58
+ tracker = ByteTrackTracker()
59
+ motion_estimator = MotionEstimator()
60
+ trace_annotator = MotionAwareTraceAnnotator()
61
+
62
+ cap = cv2.VideoCapture("moving_camera.mp4")
63
+ while True:
64
+ ret, frame = cap.read()
65
+ if not ret:
66
+ break
67
+
68
+ coord_transform = motion_estimator.update(frame)
69
+
70
+ result = model.infer(frame)[0]
71
+ detections = sv.Detections.from_inference(result)
72
+ detections = tracker.update(detections)
73
+
74
+ frame = trace_annotator.annotate(
75
+ scene=frame,
76
+ detections=detections,
77
+ coord_transform=coord_transform,
78
+ )
79
+ ```
80
+ """
81
+
82
+ def __init__(
83
+ self,
84
+ color: Color | ColorPalette | None = None,
85
+ position: Position | None = None,
86
+ trace_length: int = 30,
87
+ thickness: int = 2,
88
+ color_lookup: ColorLookup | None = None,
89
+ ) -> None:
90
+ self.color: Color | ColorPalette = color if color is not None else ColorPalette.DEFAULT
91
+ self.position: Position = position if position is not None else Position.CENTER
92
+ self.trace_length = trace_length
93
+ self.thickness = thickness
94
+ self.color_lookup: ColorLookup = color_lookup if color_lookup is not None else ColorLookup.TRACK
95
+
96
+ self._trajectories: dict[int, list[tuple[float, float]]] = defaultdict(list)
97
+
98
+ def _get_anchor_points(self, detections: sv.Detections) -> np.ndarray:
99
+ """Extract anchor points from detections based on position setting.
100
+
101
+ Args:
102
+ detections: Detections object with xyxy boxes.
103
+
104
+ Returns:
105
+ Array of shape `(N, 2)` with `(x, y)` anchor points.
106
+ """
107
+ return detections.get_anchors_coordinates(self.position)
108
+
109
+ def annotate(
110
+ self,
111
+ scene: np.ndarray,
112
+ detections: sv.Detections,
113
+ custom_color_lookup: np.ndarray | None = None,
114
+ coord_transform: CoordinatesTransformation | None = None,
115
+ ) -> np.ndarray:
116
+ """Draw motion-compensated trace paths on the scene.
117
+
118
+ Updates internal trajectory storage with new detection positions (converted
119
+ to world coordinates), then draws all trajectories transformed back to
120
+ frame coordinates.
121
+
122
+ Args:
123
+ scene: The image on which traces will be drawn. Modified in place.
124
+ detections: Detections with `tracker_id` field populated.
125
+ custom_color_lookup: Optional custom color lookup array to override
126
+ the default color mapping strategy.
127
+ coord_transform: Coordinate transformation for the current frame.
128
+ If None, uses identity transformation (no motion compensation).
129
+
130
+ Returns:
131
+ The annotated image.
132
+
133
+ Raises:
134
+ ValueError: If detections don't have tracker_id field.
135
+ """
136
+ if detections.tracker_id is None:
137
+ raise ValueError(
138
+ "The `tracker_id` field is missing in the provided detections. "
139
+ "See: https://supervision.roboflow.com/latest/how_to/track_objects"
140
+ )
141
+
142
+ if coord_transform is None:
143
+ coord_transform = IdentityTransformation()
144
+
145
+ anchor_points = self._get_anchor_points(detections)
146
+
147
+ if len(anchor_points) > 0:
148
+ world_points = coord_transform.rel_to_abs(anchor_points)
149
+
150
+ for tracker_id, world_point in zip(detections.tracker_id, world_points):
151
+ if tracker_id is None or tracker_id < 0:
152
+ continue
153
+ tracker_id = int(tracker_id)
154
+ trajectory = self._trajectories[tracker_id]
155
+ trajectory.append((float(world_point[0]), float(world_point[1])))
156
+
157
+ if len(trajectory) > self.trace_length:
158
+ self._trajectories[tracker_id] = trajectory[-self.trace_length :]
159
+
160
+ for detection_idx in range(len(detections)):
161
+ tracker_id = detections.tracker_id[detection_idx]
162
+ if tracker_id is None or tracker_id < 0:
163
+ continue
164
+ tracker_id = int(tracker_id)
165
+
166
+ trajectory = self._trajectories.get(tracker_id, [])
167
+ if len(trajectory) < 2:
168
+ continue
169
+
170
+ color = resolve_color(
171
+ color=self.color,
172
+ detections=detections,
173
+ detection_idx=detection_idx,
174
+ color_lookup=(self.color_lookup if custom_color_lookup is None else custom_color_lookup),
175
+ )
176
+
177
+ world_points = np.array(trajectory, dtype=np.float32)
178
+ frame_points = coord_transform.abs_to_rel(world_points)
179
+
180
+ # Filter out points outside the frame bounds
181
+ height, width = scene.shape[:2]
182
+ valid_mask = (
183
+ (frame_points[:, 0] >= 0)
184
+ & (frame_points[:, 0] < width)
185
+ & (frame_points[:, 1] >= 0)
186
+ & (frame_points[:, 1] < height)
187
+ & np.isfinite(frame_points[:, 0])
188
+ & np.isfinite(frame_points[:, 1])
189
+ )
190
+
191
+ if np.sum(valid_mask) < 2:
192
+ continue
193
+
194
+ points: np.ndarray = frame_points[valid_mask].astype(np.int32)
195
+
196
+ scene = cv2.polylines(
197
+ scene,
198
+ [points],
199
+ isClosed=False,
200
+ color=color.as_bgr(),
201
+ thickness=self.thickness,
202
+ )
203
+
204
+ return scene
205
+
206
+ def reset(self) -> None:
207
+ """Clear all stored trajectories.
208
+
209
+ Call this when switching videos or when you want to reset trajectory history.
210
+ """
211
+ self._trajectories.clear()
212
+
213
+ def clear_tracker(self, tracker_id: int) -> None:
214
+ """Clear the trajectory for a specific tracker ID.
215
+
216
+ Args:
217
+ tracker_id: The tracker ID to clear.
218
+ """
219
+ self._trajectories.pop(tracker_id, None)
@@ -0,0 +1,5 @@
1
+ # ------------------------------------------------------------------------
2
+ # Trackers
3
+ # Copyright (c) 2026 Roboflow. All Rights Reserved.
4
+ # Licensed under the Apache License, Version 2.0 [see LICENSE for details]
5
+ # ------------------------------------------------------------------------