ultralytics 8.1.28__py3-none-any.whl → 8.3.62__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 (247) hide show
  1. tests/__init__.py +22 -0
  2. tests/conftest.py +83 -0
  3. tests/test_cli.py +122 -0
  4. tests/test_cuda.py +155 -0
  5. tests/test_engine.py +131 -0
  6. tests/test_exports.py +216 -0
  7. tests/test_integrations.py +150 -0
  8. tests/test_python.py +615 -0
  9. tests/test_solutions.py +94 -0
  10. ultralytics/__init__.py +11 -8
  11. ultralytics/cfg/__init__.py +569 -131
  12. ultralytics/cfg/datasets/Argoverse.yaml +2 -1
  13. ultralytics/cfg/datasets/DOTAv1.5.yaml +3 -2
  14. ultralytics/cfg/datasets/DOTAv1.yaml +3 -2
  15. ultralytics/cfg/datasets/GlobalWheat2020.yaml +3 -2
  16. ultralytics/cfg/datasets/ImageNet.yaml +2 -1
  17. ultralytics/cfg/datasets/Objects365.yaml +5 -4
  18. ultralytics/cfg/datasets/SKU-110K.yaml +2 -1
  19. ultralytics/cfg/datasets/VOC.yaml +3 -2
  20. ultralytics/cfg/datasets/VisDrone.yaml +6 -5
  21. ultralytics/cfg/datasets/african-wildlife.yaml +25 -0
  22. ultralytics/cfg/datasets/brain-tumor.yaml +23 -0
  23. ultralytics/cfg/datasets/carparts-seg.yaml +3 -2
  24. ultralytics/cfg/datasets/coco-pose.yaml +7 -6
  25. ultralytics/cfg/datasets/coco.yaml +3 -2
  26. ultralytics/cfg/datasets/coco128-seg.yaml +4 -3
  27. ultralytics/cfg/datasets/coco128.yaml +4 -3
  28. ultralytics/cfg/datasets/coco8-pose.yaml +3 -2
  29. ultralytics/cfg/datasets/coco8-seg.yaml +3 -2
  30. ultralytics/cfg/datasets/coco8.yaml +3 -2
  31. ultralytics/cfg/datasets/crack-seg.yaml +3 -2
  32. ultralytics/cfg/datasets/dog-pose.yaml +24 -0
  33. ultralytics/cfg/datasets/dota8.yaml +3 -2
  34. ultralytics/cfg/datasets/hand-keypoints.yaml +26 -0
  35. ultralytics/cfg/datasets/lvis.yaml +1236 -0
  36. ultralytics/cfg/datasets/medical-pills.yaml +22 -0
  37. ultralytics/cfg/datasets/open-images-v7.yaml +2 -1
  38. ultralytics/cfg/datasets/package-seg.yaml +5 -4
  39. ultralytics/cfg/datasets/signature.yaml +21 -0
  40. ultralytics/cfg/datasets/tiger-pose.yaml +3 -2
  41. ultralytics/cfg/datasets/xView.yaml +2 -1
  42. ultralytics/cfg/default.yaml +14 -11
  43. ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +24 -0
  44. ultralytics/cfg/models/11/yolo11-cls.yaml +33 -0
  45. ultralytics/cfg/models/11/yolo11-obb.yaml +50 -0
  46. ultralytics/cfg/models/11/yolo11-pose.yaml +51 -0
  47. ultralytics/cfg/models/11/yolo11-seg.yaml +50 -0
  48. ultralytics/cfg/models/11/yolo11.yaml +50 -0
  49. ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +5 -2
  50. ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +5 -2
  51. ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +5 -2
  52. ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +5 -2
  53. ultralytics/cfg/models/v10/yolov10b.yaml +45 -0
  54. ultralytics/cfg/models/v10/yolov10l.yaml +45 -0
  55. ultralytics/cfg/models/v10/yolov10m.yaml +45 -0
  56. ultralytics/cfg/models/v10/yolov10n.yaml +45 -0
  57. ultralytics/cfg/models/v10/yolov10s.yaml +45 -0
  58. ultralytics/cfg/models/v10/yolov10x.yaml +45 -0
  59. ultralytics/cfg/models/v3/yolov3-spp.yaml +5 -2
  60. ultralytics/cfg/models/v3/yolov3-tiny.yaml +5 -2
  61. ultralytics/cfg/models/v3/yolov3.yaml +5 -2
  62. ultralytics/cfg/models/v5/yolov5-p6.yaml +5 -2
  63. ultralytics/cfg/models/v5/yolov5.yaml +5 -2
  64. ultralytics/cfg/models/v6/yolov6.yaml +5 -2
  65. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +5 -2
  66. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +5 -2
  67. ultralytics/cfg/models/v8/yolov8-cls.yaml +5 -2
  68. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +6 -2
  69. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +6 -2
  70. ultralytics/cfg/models/v8/yolov8-ghost.yaml +5 -2
  71. ultralytics/cfg/models/v8/yolov8-obb.yaml +5 -2
  72. ultralytics/cfg/models/v8/yolov8-p2.yaml +5 -2
  73. ultralytics/cfg/models/v8/yolov8-p6.yaml +10 -7
  74. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +5 -2
  75. ultralytics/cfg/models/v8/yolov8-pose.yaml +5 -2
  76. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +5 -2
  77. ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +5 -2
  78. ultralytics/cfg/models/v8/yolov8-seg.yaml +5 -2
  79. ultralytics/cfg/models/v8/yolov8-world.yaml +5 -2
  80. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +5 -2
  81. ultralytics/cfg/models/v8/yolov8.yaml +5 -2
  82. ultralytics/cfg/models/v9/yolov9c-seg.yaml +41 -0
  83. ultralytics/cfg/models/v9/yolov9c.yaml +30 -25
  84. ultralytics/cfg/models/v9/yolov9e-seg.yaml +64 -0
  85. ultralytics/cfg/models/v9/yolov9e.yaml +46 -42
  86. ultralytics/cfg/models/v9/yolov9m.yaml +41 -0
  87. ultralytics/cfg/models/v9/yolov9s.yaml +41 -0
  88. ultralytics/cfg/models/v9/yolov9t.yaml +41 -0
  89. ultralytics/cfg/solutions/default.yaml +24 -0
  90. ultralytics/cfg/trackers/botsort.yaml +8 -5
  91. ultralytics/cfg/trackers/bytetrack.yaml +8 -5
  92. ultralytics/data/__init__.py +14 -3
  93. ultralytics/data/annotator.py +37 -15
  94. ultralytics/data/augment.py +1783 -289
  95. ultralytics/data/base.py +62 -27
  96. ultralytics/data/build.py +36 -8
  97. ultralytics/data/converter.py +196 -36
  98. ultralytics/data/dataset.py +233 -94
  99. ultralytics/data/loaders.py +199 -96
  100. ultralytics/data/split_dota.py +39 -29
  101. ultralytics/data/utils.py +110 -40
  102. ultralytics/engine/__init__.py +1 -1
  103. ultralytics/engine/exporter.py +569 -242
  104. ultralytics/engine/model.py +604 -252
  105. ultralytics/engine/predictor.py +22 -11
  106. ultralytics/engine/results.py +1228 -218
  107. ultralytics/engine/trainer.py +190 -129
  108. ultralytics/engine/tuner.py +18 -18
  109. ultralytics/engine/validator.py +18 -15
  110. ultralytics/hub/__init__.py +31 -13
  111. ultralytics/hub/auth.py +11 -7
  112. ultralytics/hub/google/__init__.py +159 -0
  113. ultralytics/hub/session.py +128 -94
  114. ultralytics/hub/utils.py +20 -21
  115. ultralytics/models/__init__.py +4 -2
  116. ultralytics/models/fastsam/__init__.py +2 -3
  117. ultralytics/models/fastsam/model.py +26 -4
  118. ultralytics/models/fastsam/predict.py +127 -63
  119. ultralytics/models/fastsam/utils.py +1 -44
  120. ultralytics/models/fastsam/val.py +1 -1
  121. ultralytics/models/nas/__init__.py +1 -1
  122. ultralytics/models/nas/model.py +21 -10
  123. ultralytics/models/nas/predict.py +3 -6
  124. ultralytics/models/nas/val.py +4 -4
  125. ultralytics/models/rtdetr/__init__.py +1 -1
  126. ultralytics/models/rtdetr/model.py +1 -1
  127. ultralytics/models/rtdetr/predict.py +6 -8
  128. ultralytics/models/rtdetr/train.py +6 -2
  129. ultralytics/models/rtdetr/val.py +3 -3
  130. ultralytics/models/sam/__init__.py +3 -3
  131. ultralytics/models/sam/amg.py +29 -23
  132. ultralytics/models/sam/build.py +211 -13
  133. ultralytics/models/sam/model.py +91 -30
  134. ultralytics/models/sam/modules/__init__.py +1 -1
  135. ultralytics/models/sam/modules/blocks.py +1129 -0
  136. ultralytics/models/sam/modules/decoders.py +381 -53
  137. ultralytics/models/sam/modules/encoders.py +515 -324
  138. ultralytics/models/sam/modules/memory_attention.py +237 -0
  139. ultralytics/models/sam/modules/sam.py +969 -21
  140. ultralytics/models/sam/modules/tiny_encoder.py +425 -154
  141. ultralytics/models/sam/modules/transformer.py +159 -60
  142. ultralytics/models/sam/modules/utils.py +293 -0
  143. ultralytics/models/sam/predict.py +1263 -132
  144. ultralytics/models/utils/__init__.py +1 -1
  145. ultralytics/models/utils/loss.py +36 -24
  146. ultralytics/models/utils/ops.py +3 -7
  147. ultralytics/models/yolo/__init__.py +3 -3
  148. ultralytics/models/yolo/classify/__init__.py +1 -1
  149. ultralytics/models/yolo/classify/predict.py +7 -8
  150. ultralytics/models/yolo/classify/train.py +17 -22
  151. ultralytics/models/yolo/classify/val.py +8 -4
  152. ultralytics/models/yolo/detect/__init__.py +1 -1
  153. ultralytics/models/yolo/detect/predict.py +3 -5
  154. ultralytics/models/yolo/detect/train.py +11 -4
  155. ultralytics/models/yolo/detect/val.py +90 -52
  156. ultralytics/models/yolo/model.py +14 -9
  157. ultralytics/models/yolo/obb/__init__.py +1 -1
  158. ultralytics/models/yolo/obb/predict.py +2 -2
  159. ultralytics/models/yolo/obb/train.py +5 -3
  160. ultralytics/models/yolo/obb/val.py +41 -23
  161. ultralytics/models/yolo/pose/__init__.py +1 -1
  162. ultralytics/models/yolo/pose/predict.py +3 -5
  163. ultralytics/models/yolo/pose/train.py +2 -2
  164. ultralytics/models/yolo/pose/val.py +51 -17
  165. ultralytics/models/yolo/segment/__init__.py +1 -1
  166. ultralytics/models/yolo/segment/predict.py +3 -5
  167. ultralytics/models/yolo/segment/train.py +2 -2
  168. ultralytics/models/yolo/segment/val.py +60 -19
  169. ultralytics/models/yolo/world/__init__.py +5 -0
  170. ultralytics/models/yolo/world/train.py +92 -0
  171. ultralytics/models/yolo/world/train_world.py +109 -0
  172. ultralytics/nn/__init__.py +1 -1
  173. ultralytics/nn/autobackend.py +228 -93
  174. ultralytics/nn/modules/__init__.py +39 -14
  175. ultralytics/nn/modules/activation.py +21 -0
  176. ultralytics/nn/modules/block.py +527 -67
  177. ultralytics/nn/modules/conv.py +24 -7
  178. ultralytics/nn/modules/head.py +177 -34
  179. ultralytics/nn/modules/transformer.py +6 -5
  180. ultralytics/nn/modules/utils.py +1 -2
  181. ultralytics/nn/tasks.py +225 -77
  182. ultralytics/solutions/__init__.py +30 -1
  183. ultralytics/solutions/ai_gym.py +96 -143
  184. ultralytics/solutions/analytics.py +247 -0
  185. ultralytics/solutions/distance_calculation.py +78 -135
  186. ultralytics/solutions/heatmap.py +93 -247
  187. ultralytics/solutions/object_counter.py +184 -259
  188. ultralytics/solutions/parking_management.py +246 -0
  189. ultralytics/solutions/queue_management.py +112 -0
  190. ultralytics/solutions/region_counter.py +116 -0
  191. ultralytics/solutions/security_alarm.py +144 -0
  192. ultralytics/solutions/solutions.py +178 -0
  193. ultralytics/solutions/speed_estimation.py +86 -174
  194. ultralytics/solutions/streamlit_inference.py +190 -0
  195. ultralytics/solutions/trackzone.py +68 -0
  196. ultralytics/trackers/__init__.py +1 -1
  197. ultralytics/trackers/basetrack.py +32 -13
  198. ultralytics/trackers/bot_sort.py +61 -28
  199. ultralytics/trackers/byte_tracker.py +83 -51
  200. ultralytics/trackers/track.py +21 -6
  201. ultralytics/trackers/utils/__init__.py +1 -1
  202. ultralytics/trackers/utils/gmc.py +62 -48
  203. ultralytics/trackers/utils/kalman_filter.py +166 -35
  204. ultralytics/trackers/utils/matching.py +40 -21
  205. ultralytics/utils/__init__.py +511 -239
  206. ultralytics/utils/autobatch.py +40 -22
  207. ultralytics/utils/benchmarks.py +266 -85
  208. ultralytics/utils/callbacks/__init__.py +1 -1
  209. ultralytics/utils/callbacks/base.py +1 -3
  210. ultralytics/utils/callbacks/clearml.py +7 -6
  211. ultralytics/utils/callbacks/comet.py +39 -17
  212. ultralytics/utils/callbacks/dvc.py +1 -1
  213. ultralytics/utils/callbacks/hub.py +16 -16
  214. ultralytics/utils/callbacks/mlflow.py +28 -24
  215. ultralytics/utils/callbacks/neptune.py +6 -2
  216. ultralytics/utils/callbacks/raytune.py +3 -4
  217. ultralytics/utils/callbacks/tensorboard.py +18 -18
  218. ultralytics/utils/callbacks/wb.py +27 -20
  219. ultralytics/utils/checks.py +160 -100
  220. ultralytics/utils/dist.py +2 -1
  221. ultralytics/utils/downloads.py +44 -37
  222. ultralytics/utils/errors.py +1 -1
  223. ultralytics/utils/files.py +72 -38
  224. ultralytics/utils/instance.py +41 -19
  225. ultralytics/utils/loss.py +84 -56
  226. ultralytics/utils/metrics.py +61 -56
  227. ultralytics/utils/ops.py +94 -89
  228. ultralytics/utils/patches.py +30 -14
  229. ultralytics/utils/plotting.py +600 -269
  230. ultralytics/utils/tal.py +67 -26
  231. ultralytics/utils/torch_utils.py +302 -102
  232. ultralytics/utils/triton.py +2 -1
  233. ultralytics/utils/tuner.py +21 -12
  234. ultralytics-8.3.62.dist-info/METADATA +370 -0
  235. ultralytics-8.3.62.dist-info/RECORD +241 -0
  236. {ultralytics-8.1.28.dist-info → ultralytics-8.3.62.dist-info}/WHEEL +1 -1
  237. ultralytics/data/explorer/__init__.py +0 -5
  238. ultralytics/data/explorer/explorer.py +0 -472
  239. ultralytics/data/explorer/gui/__init__.py +0 -1
  240. ultralytics/data/explorer/gui/dash.py +0 -268
  241. ultralytics/data/explorer/utils.py +0 -166
  242. ultralytics/models/fastsam/prompt.py +0 -357
  243. ultralytics-8.1.28.dist-info/METADATA +0 -373
  244. ultralytics-8.1.28.dist-info/RECORD +0 -197
  245. {ultralytics-8.1.28.dist-info → ultralytics-8.3.62.dist-info}/LICENSE +0 -0
  246. {ultralytics-8.1.28.dist-info → ultralytics-8.3.62.dist-info}/entry_points.txt +0 -0
  247. {ultralytics-8.1.28.dist-info → ultralytics-8.3.62.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,68 @@
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
+
3
+ import cv2
4
+ import numpy as np
5
+
6
+ from ultralytics.solutions.solutions import BaseSolution
7
+ from ultralytics.utils.plotting import Annotator, colors
8
+
9
+
10
+ class TrackZone(BaseSolution):
11
+ """
12
+ A class to manage region-based object tracking in a video stream.
13
+
14
+ This class extends the BaseSolution class and provides functionality for tracking objects within a specific region
15
+ defined by a polygonal area. Objects outside the region are excluded from tracking. It supports dynamic initialization
16
+ of the region, allowing either a default region or a user-specified polygon.
17
+
18
+ Attributes:
19
+ region (ndarray): The polygonal region for tracking, represented as a convex hull.
20
+
21
+ Methods:
22
+ trackzone: Processes each frame of the video, applying region-based tracking.
23
+
24
+ Examples:
25
+ >>> tracker = TrackZone()
26
+ >>> frame = cv2.imread("frame.jpg")
27
+ >>> processed_frame = tracker.trackzone(frame)
28
+ >>> cv2.imshow("Tracked Frame", processed_frame)
29
+ """
30
+
31
+ def __init__(self, **kwargs):
32
+ """Initializes the TrackZone class for tracking objects within a defined region in video streams."""
33
+ super().__init__(**kwargs)
34
+ default_region = [(150, 150), (1130, 150), (1130, 570), (150, 570)]
35
+ self.region = cv2.convexHull(np.array(self.region or default_region, dtype=np.int32))
36
+
37
+ def trackzone(self, im0):
38
+ """
39
+ Processes the input frame to track objects within a defined region.
40
+
41
+ This method initializes the annotator, creates a mask for the specified region, extracts tracks
42
+ only from the masked area, and updates tracking information. Objects outside the region are ignored.
43
+
44
+ Args:
45
+ im0 (numpy.ndarray): The input image or frame to be processed.
46
+
47
+ Returns:
48
+ (numpy.ndarray): The processed image with tracking id and bounding boxes annotations.
49
+
50
+ Examples:
51
+ >>> tracker = TrackZone()
52
+ >>> frame = cv2.imread("path/to/image.jpg")
53
+ >>> tracker.trackzone(frame)
54
+ """
55
+ self.annotator = Annotator(im0, line_width=self.line_width) # Initialize annotator
56
+ # Create a mask for the region and extract tracks from the masked image
57
+ masked_frame = cv2.bitwise_and(im0, im0, mask=cv2.fillPoly(np.zeros_like(im0[:, :, 0]), [self.region], 255))
58
+ self.extract_tracks(masked_frame)
59
+
60
+ cv2.polylines(im0, [self.region], isClosed=True, color=(255, 255, 255), thickness=self.line_width * 2)
61
+
62
+ # Iterate over boxes, track ids, classes indexes list and draw bounding boxes
63
+ for box, track_id, cls in zip(self.boxes, self.track_ids, self.clss):
64
+ self.annotator.box_label(box, label=f"{self.names[cls]}:{track_id}", color=colors(track_id, True))
65
+
66
+ self.display_output(im0) # display output with base class function
67
+
68
+ return im0 # return output image for more usage
@@ -1,4 +1,4 @@
1
- # Ultralytics YOLO 🚀, AGPL-3.0 license
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
3
  from .bot_sort import BOTSORT
4
4
  from .byte_tracker import BYTETracker
@@ -1,5 +1,5 @@
1
- # Ultralytics YOLO 🚀, AGPL-3.0 license
2
- """This module defines the base classes and structures for object tracking in YOLO."""
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
+ """Module defines the base classes and structures for object tracking in YOLO."""
3
3
 
4
4
  from collections import OrderedDict
5
5
 
@@ -15,6 +15,11 @@ class TrackState:
15
15
  Tracked (int): State when the object is successfully tracked in subsequent frames.
16
16
  Lost (int): State when the object is no longer tracked.
17
17
  Removed (int): State when the object is removed from tracking.
18
+
19
+ Examples:
20
+ >>> state = TrackState.New
21
+ >>> if state == TrackState.New:
22
+ >>> print("Object is newly detected.")
18
23
  """
19
24
 
20
25
  New = 0
@@ -33,8 +38,8 @@ class BaseTrack:
33
38
  is_activated (bool): Flag indicating whether the track is currently active.
34
39
  state (TrackState): Current state of the track.
35
40
  history (OrderedDict): Ordered history of the track's states.
36
- features (list): List of features extracted from the object for tracking.
37
- curr_feature (any): The current feature of the object being tracked.
41
+ features (List): List of features extracted from the object for tracking.
42
+ curr_feature (Any): The current feature of the object being tracked.
38
43
  score (float): The confidence score of the tracking.
39
44
  start_frame (int): The frame number where tracking started.
40
45
  frame_id (int): The most recent frame ID processed by the track.
@@ -50,12 +55,26 @@ class BaseTrack:
50
55
  mark_lost: Marks the track as lost.
51
56
  mark_removed: Marks the track as removed.
52
57
  reset_id: Resets the global track ID counter.
58
+
59
+ Examples:
60
+ Initialize a new track and mark it as lost:
61
+ >>> track = BaseTrack()
62
+ >>> track.mark_lost()
63
+ >>> print(track.state) # Output: 2 (TrackState.Lost)
53
64
  """
54
65
 
55
66
  _count = 0
56
67
 
57
68
  def __init__(self):
58
- """Initializes a new track with unique ID and foundational tracking attributes."""
69
+ """
70
+ Initializes a new track with a unique ID and foundational tracking attributes.
71
+
72
+ Examples:
73
+ Initialize a new track
74
+ >>> track = BaseTrack()
75
+ >>> print(track.track_id)
76
+ 0
77
+ """
59
78
  self.track_id = 0
60
79
  self.is_activated = False
61
80
  self.state = TrackState.New
@@ -70,36 +89,36 @@ class BaseTrack:
70
89
 
71
90
  @property
72
91
  def end_frame(self):
73
- """Return the last frame ID of the track."""
92
+ """Returns the ID of the most recent frame where the object was tracked."""
74
93
  return self.frame_id
75
94
 
76
95
  @staticmethod
77
96
  def next_id():
78
- """Increment and return the global track ID counter."""
97
+ """Increment and return the next unique global track ID for object tracking."""
79
98
  BaseTrack._count += 1
80
99
  return BaseTrack._count
81
100
 
82
101
  def activate(self, *args):
83
- """Abstract method to activate the track with provided arguments."""
102
+ """Activates the track with provided arguments, initializing necessary attributes for tracking."""
84
103
  raise NotImplementedError
85
104
 
86
105
  def predict(self):
87
- """Abstract method to predict the next state of the track."""
106
+ """Predicts the next state of the track based on the current state and tracking model."""
88
107
  raise NotImplementedError
89
108
 
90
109
  def update(self, *args, **kwargs):
91
- """Abstract method to update the track with new observations."""
110
+ """Updates the track with new observations and data, modifying its state and attributes accordingly."""
92
111
  raise NotImplementedError
93
112
 
94
113
  def mark_lost(self):
95
- """Mark the track as lost."""
114
+ """Marks the track as lost by updating its state to TrackState.Lost."""
96
115
  self.state = TrackState.Lost
97
116
 
98
117
  def mark_removed(self):
99
- """Mark the track as removed."""
118
+ """Marks the track as removed by setting its state to TrackState.Removed."""
100
119
  self.state = TrackState.Removed
101
120
 
102
121
  @staticmethod
103
122
  def reset_id():
104
- """Reset the global track ID counter."""
123
+ """Reset the global track ID counter to its initial value."""
105
124
  BaseTrack._count = 0
@@ -1,4 +1,4 @@
1
- # Ultralytics YOLO 🚀, AGPL-3.0 license
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
3
  from collections import deque
4
4
 
@@ -15,6 +15,9 @@ class BOTrack(STrack):
15
15
  """
16
16
  An extended version of the STrack class for YOLOv8, adding object tracking features.
17
17
 
18
+ This class extends the STrack class to include additional functionalities for object tracking, such as feature
19
+ smoothing, Kalman filter prediction, and reactivation of tracks.
20
+
18
21
  Attributes:
19
22
  shared_kalman (KalmanFilterXYWH): A shared Kalman filter for all instances of BOTrack.
20
23
  smooth_feat (np.ndarray): Smoothed feature vector.
@@ -34,16 +37,35 @@ class BOTrack(STrack):
34
37
  convert_coords(tlwh): Converts tlwh bounding box coordinates to xywh format.
35
38
  tlwh_to_xywh(tlwh): Convert bounding box to xywh format `(center x, center y, width, height)`.
36
39
 
37
- Usage:
38
- bo_track = BOTrack(tlwh, score, cls, feat)
39
- bo_track.predict()
40
- bo_track.update(new_track, frame_id)
40
+ Examples:
41
+ Create a BOTrack instance and update its features
42
+ >>> bo_track = BOTrack(tlwh=[100, 50, 80, 40], score=0.9, cls=1, feat=np.random.rand(128))
43
+ >>> bo_track.predict()
44
+ >>> new_track = BOTrack(tlwh=[110, 60, 80, 40], score=0.85, cls=1, feat=np.random.rand(128))
45
+ >>> bo_track.update(new_track, frame_id=2)
41
46
  """
42
47
 
43
48
  shared_kalman = KalmanFilterXYWH()
44
49
 
45
50
  def __init__(self, tlwh, score, cls, feat=None, feat_history=50):
46
- """Initialize YOLOv8 object with temporal parameters, such as feature history, alpha and current features."""
51
+ """
52
+ Initialize a BOTrack object with temporal parameters, such as feature history, alpha, and current features.
53
+
54
+ Args:
55
+ tlwh (np.ndarray): Bounding box coordinates in tlwh format (top left x, top left y, width, height).
56
+ score (float): Confidence score of the detection.
57
+ cls (int): Class ID of the detected object.
58
+ feat (np.ndarray | None): Feature vector associated with the detection.
59
+ feat_history (int): Maximum length of the feature history deque.
60
+
61
+ Examples:
62
+ Initialize a BOTrack object with bounding box, score, class ID, and feature vector
63
+ >>> tlwh = np.array([100, 50, 80, 120])
64
+ >>> score = 0.9
65
+ >>> cls = 1
66
+ >>> feat = np.random.rand(128)
67
+ >>> bo_track = BOTrack(tlwh, score, cls, feat)
68
+ """
47
69
  super().__init__(tlwh, score, cls)
48
70
 
49
71
  self.smooth_feat = None
@@ -54,7 +76,7 @@ class BOTrack(STrack):
54
76
  self.alpha = 0.9
55
77
 
56
78
  def update_features(self, feat):
57
- """Update features vector and smooth it using exponential moving average."""
79
+ """Update the feature vector and apply exponential moving average smoothing."""
58
80
  feat /= np.linalg.norm(feat)
59
81
  self.curr_feat = feat
60
82
  if self.smooth_feat is None:
@@ -65,7 +87,7 @@ class BOTrack(STrack):
65
87
  self.smooth_feat /= np.linalg.norm(self.smooth_feat)
66
88
 
67
89
  def predict(self):
68
- """Predicts the mean and covariance using Kalman filter."""
90
+ """Predicts the object's future state using the Kalman filter to update its mean and covariance."""
69
91
  mean_state = self.mean.copy()
70
92
  if self.state != TrackState.Tracked:
71
93
  mean_state[6] = 0
@@ -80,14 +102,14 @@ class BOTrack(STrack):
80
102
  super().re_activate(new_track, frame_id, new_id)
81
103
 
82
104
  def update(self, new_track, frame_id):
83
- """Update the YOLOv8 instance with new track and frame ID."""
105
+ """Updates the YOLOv8 instance with new track information and the current frame ID."""
84
106
  if new_track.curr_feat is not None:
85
107
  self.update_features(new_track.curr_feat)
86
108
  super().update(new_track, frame_id)
87
109
 
88
110
  @property
89
111
  def tlwh(self):
90
- """Get current position in bounding box format `(top left x, top left y, width, height)`."""
112
+ """Returns the current bounding box position in `(top left x, top left y, width, height)` format."""
91
113
  if self.mean is None:
92
114
  return self._tlwh.copy()
93
115
  ret = self.mean[:4].copy()
@@ -96,7 +118,7 @@ class BOTrack(STrack):
96
118
 
97
119
  @staticmethod
98
120
  def multi_predict(stracks):
99
- """Predicts the mean and covariance of multiple object tracks using shared Kalman filter."""
121
+ """Predicts the mean and covariance for multiple object tracks using a shared Kalman filter."""
100
122
  if len(stracks) <= 0:
101
123
  return
102
124
  multi_mean = np.asarray([st.mean.copy() for st in stracks])
@@ -111,12 +133,12 @@ class BOTrack(STrack):
111
133
  stracks[i].covariance = cov
112
134
 
113
135
  def convert_coords(self, tlwh):
114
- """Converts Top-Left-Width-Height bounding box coordinates to X-Y-Width-Height format."""
136
+ """Converts tlwh bounding box coordinates to xywh format."""
115
137
  return self.tlwh_to_xywh(tlwh)
116
138
 
117
139
  @staticmethod
118
140
  def tlwh_to_xywh(tlwh):
119
- """Convert bounding box to format `(center x, center y, width, height)`."""
141
+ """Convert bounding box from tlwh (top-left-width-height) to xywh (center-x-center-y-width-height) format."""
120
142
  ret = np.asarray(tlwh).copy()
121
143
  ret[:2] += ret[2:] / 2
122
144
  return ret
@@ -129,9 +151,9 @@ class BOTSORT(BYTETracker):
129
151
  Attributes:
130
152
  proximity_thresh (float): Threshold for spatial proximity (IoU) between tracks and detections.
131
153
  appearance_thresh (float): Threshold for appearance similarity (ReID embeddings) between tracks and detections.
132
- encoder (object): Object to handle ReID embeddings, set to None if ReID is not enabled.
154
+ encoder (Any): Object to handle ReID embeddings, set to None if ReID is not enabled.
133
155
  gmc (GMC): An instance of the GMC algorithm for data association.
134
- args (object): Parsed command-line arguments containing tracking parameters.
156
+ args (Any): Parsed command-line arguments containing tracking parameters.
135
157
 
136
158
  Methods:
137
159
  get_kalmanfilter(): Returns an instance of KalmanFilterXYWH for object tracking.
@@ -139,17 +161,29 @@ class BOTSORT(BYTETracker):
139
161
  get_dists(tracks, detections): Get distances between tracks and detections using IoU and (optionally) ReID.
140
162
  multi_predict(tracks): Predict and track multiple objects with YOLOv8 model.
141
163
 
142
- Usage:
143
- bot_sort = BOTSORT(args, frame_rate)
144
- bot_sort.init_track(dets, scores, cls, img)
145
- bot_sort.multi_predict(tracks)
164
+ Examples:
165
+ Initialize BOTSORT and process detections
166
+ >>> bot_sort = BOTSORT(args, frame_rate=30)
167
+ >>> bot_sort.init_track(dets, scores, cls, img)
168
+ >>> bot_sort.multi_predict(tracks)
146
169
 
147
170
  Note:
148
171
  The class is designed to work with the YOLOv8 object detection model and supports ReID only if enabled via args.
149
172
  """
150
173
 
151
174
  def __init__(self, args, frame_rate=30):
152
- """Initialize YOLOv8 object with ReID module and GMC algorithm."""
175
+ """
176
+ Initialize YOLOv8 object with ReID module and GMC algorithm.
177
+
178
+ Args:
179
+ args (object): Parsed command-line arguments containing tracking parameters.
180
+ frame_rate (int): Frame rate of the video being processed.
181
+
182
+ Examples:
183
+ Initialize BOTSORT with command-line arguments and a specified frame rate:
184
+ >>> args = parse_args()
185
+ >>> bot_sort = BOTSORT(args, frame_rate=30)
186
+ """
153
187
  super().__init__(args, frame_rate)
154
188
  # ReID module
155
189
  self.proximity_thresh = args.proximity_thresh
@@ -161,11 +195,11 @@ class BOTSORT(BYTETracker):
161
195
  self.gmc = GMC(method=args.gmc_method)
162
196
 
163
197
  def get_kalmanfilter(self):
164
- """Returns an instance of KalmanFilterXYWH for object tracking."""
198
+ """Returns an instance of KalmanFilterXYWH for predicting and updating object states in the tracking process."""
165
199
  return KalmanFilterXYWH()
166
200
 
167
201
  def init_track(self, dets, scores, cls, img=None):
168
- """Initialize track with detections, scores, and classes."""
202
+ """Initialize object tracks using detection bounding boxes, scores, class labels, and optional ReID features."""
169
203
  if len(dets) == 0:
170
204
  return []
171
205
  if self.args.with_reid and self.encoder is not None:
@@ -175,13 +209,12 @@ class BOTSORT(BYTETracker):
175
209
  return [BOTrack(xyxy, s, c) for (xyxy, s, c) in zip(dets, scores, cls)] # detections
176
210
 
177
211
  def get_dists(self, tracks, detections):
178
- """Get distances between tracks and detections using IoU and (optionally) ReID embeddings."""
212
+ """Calculates distances between tracks and detections using IoU and optionally ReID embeddings."""
179
213
  dists = matching.iou_distance(tracks, detections)
180
214
  dists_mask = dists > self.proximity_thresh
181
215
 
182
- # TODO: mot20
183
- # if not self.args.mot20:
184
- dists = matching.fuse_score(dists, detections)
216
+ if self.args.fuse_score:
217
+ dists = matching.fuse_score(dists, detections)
185
218
 
186
219
  if self.args.with_reid and self.encoder is not None:
187
220
  emb_dists = matching.embedding_distance(tracks, detections) / 2.0
@@ -191,10 +224,10 @@ class BOTSORT(BYTETracker):
191
224
  return dists
192
225
 
193
226
  def multi_predict(self, tracks):
194
- """Predict and track multiple objects with YOLOv8 model."""
227
+ """Predicts the mean and covariance of multiple object tracks using a shared Kalman filter."""
195
228
  BOTrack.multi_predict(tracks)
196
229
 
197
230
  def reset(self):
198
- """Reset tracker."""
231
+ """Resets the BOTSORT tracker to its initial state, clearing all tracked objects and internal states."""
199
232
  super().reset()
200
233
  self.gmc.reset_params()