ultralytics 8.3.142__py3-none-any.whl → 8.3.143__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.
tests/test_solutions.py CHANGED
@@ -245,7 +245,7 @@ def test_analytics_graph_not_supported():
245
245
  """Test that unsupported analytics type raises ModuleNotFoundError."""
246
246
  try:
247
247
  analytics = solutions.Analytics(analytics_type="test") # 'test' is unsupported
248
- analytics.process(im0=None, frame_number=0)
248
+ analytics.process(im0=np.zeros((640, 480, 3), dtype=np.uint8), frame_number=0)
249
249
  assert False, "Expected ModuleNotFoundError for unsupported chart type"
250
250
  except ModuleNotFoundError as e:
251
251
  assert "test chart is not supported" in str(e)
ultralytics/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- __version__ = "8.3.142"
3
+ __version__ = "8.3.143"
4
4
 
5
5
  import os
6
6
 
@@ -171,7 +171,7 @@ class ObjectCounter(BaseSolution):
171
171
  for box, track_id, cls, conf in zip(self.boxes, self.track_ids, self.clss, self.confs):
172
172
  # Draw bounding box and counting region
173
173
  self.annotator.box_label(box, label=self.adjust_box_label(cls, conf, track_id), color=colors(cls, True))
174
- self.store_tracking_history(track_id, box, is_obb=is_obb) # Store track history
174
+ self.store_tracking_history(track_id, box) # Store track history
175
175
 
176
176
  # Store previous position of track for object counting
177
177
  prev_position = None
@@ -67,9 +67,15 @@ class ObjectCropper(BaseSolution):
67
67
  >>> results = cropper.process(frame)
68
68
  >>> print(f"Total cropped objects: {results.total_crop_objects}")
69
69
  """
70
- results = self.model.predict(
71
- im0, classes=self.classes, conf=self.conf, iou=self.iou, device=self.CFG["device"]
72
- )[0]
70
+ with self.profilers[0]:
71
+ results = self.model.predict(
72
+ im0,
73
+ classes=self.classes,
74
+ conf=self.conf,
75
+ iou=self.iou,
76
+ device=self.CFG["device"],
77
+ verbose=False,
78
+ )[0]
73
79
 
74
80
  for box in results.boxes:
75
81
  self.crop_idx += 1
@@ -8,7 +8,7 @@ import numpy as np
8
8
 
9
9
  from ultralytics import YOLO
10
10
  from ultralytics.solutions.config import SolutionConfig
11
- from ultralytics.utils import ASSETS_URL, LOGGER
11
+ from ultralytics.utils import ASSETS_URL, LOGGER, ops
12
12
  from ultralytics.utils.checks import check_imshow, check_requirements
13
13
  from ultralytics.utils.plotting import Annotator
14
14
 
@@ -75,6 +75,7 @@ class BaseSolution:
75
75
  self.track_line = None
76
76
  self.masks = None
77
77
  self.r_s = None
78
+ self.frame_no = -1 # Only for logging
78
79
 
79
80
  self.LOGGER.info(f"Ultralytics Solutions: ✅ {self.CFG}")
80
81
  self.region = self.CFG["region"] # Store region data for other classes usage
@@ -88,9 +89,10 @@ class BaseSolution:
88
89
  self.classes = self.CFG["classes"]
89
90
  self.show_conf = self.CFG["show_conf"]
90
91
  self.show_labels = self.CFG["show_labels"]
92
+ self.device = self.CFG["device"]
91
93
 
92
94
  self.track_add_args = { # Tracker additional arguments for advance configuration
93
- k: self.CFG[k] for k in ["iou", "conf", "device", "max_det", "half", "tracker", "device", "verbose"]
95
+ k: self.CFG[k] for k in ["iou", "conf", "device", "max_det", "half", "tracker"]
94
96
  } # verbose must be passed to track method; setting it False in YOLO still logs the track information.
95
97
 
96
98
  if is_cli and self.CFG["source"] is None:
@@ -105,6 +107,11 @@ class BaseSolution:
105
107
  self.env_check = check_imshow(warn=True)
106
108
  self.track_history = defaultdict(list)
107
109
 
110
+ self.profilers = (
111
+ ops.Profile(device=self.device), # track
112
+ ops.Profile(device=self.device), # solution
113
+ )
114
+
108
115
  def adjust_box_label(self, cls, conf, track_id=None):
109
116
  """
110
117
  Generates a formatted label for a bounding box.
@@ -136,7 +143,10 @@ class BaseSolution:
136
143
  >>> frame = cv2.imread("path/to/image.jpg")
137
144
  >>> solution.extract_tracks(frame)
138
145
  """
139
- self.tracks = self.model.track(source=im0, persist=True, classes=self.classes, **self.track_add_args)
146
+ with self.profilers[0]:
147
+ self.tracks = self.model.track(
148
+ source=im0, persist=True, classes=self.classes, verbose=False, **self.track_add_args
149
+ )
140
150
  self.track_data = self.tracks[0].obb or self.tracks[0].boxes # Extract tracks for OBB or object detection
141
151
 
142
152
  if self.track_data and self.track_data.id is not None:
@@ -148,7 +158,7 @@ class BaseSolution:
148
158
  self.LOGGER.warning("no tracks found!")
149
159
  self.boxes, self.clss, self.track_ids, self.confs = [], [], [], []
150
160
 
151
- def store_tracking_history(self, track_id, box, is_obb=False):
161
+ def store_tracking_history(self, track_id, box):
152
162
  """
153
163
  Stores the tracking history of an object.
154
164
 
@@ -158,7 +168,6 @@ class BaseSolution:
158
168
  Args:
159
169
  track_id (int): The unique identifier for the tracked object.
160
170
  box (List[float]): The bounding box coordinates of the object in the format [x1, y1, x2, y2].
161
- is_obb (bool): True if OBB model is used (applies to object counting only).
162
171
 
163
172
  Examples:
164
173
  >>> solution = BaseSolution()
@@ -166,7 +175,7 @@ class BaseSolution:
166
175
  """
167
176
  # Store tracking history
168
177
  self.track_line = self.track_history[track_id]
169
- self.track_line.append(tuple(box.mean(dim=0)) if is_obb else (box[:4:2].mean(), box[1:4:2].mean()))
178
+ self.track_line.append(tuple(box.mean(dim=0)) if box.numel() > 4 else (box[:4:2].mean(), box[1:4:2].mean()))
170
179
  if len(self.track_line) > 30:
171
180
  self.track_line.pop(0)
172
181
 
@@ -209,9 +218,20 @@ class BaseSolution:
209
218
 
210
219
  def __call__(self, *args, **kwargs):
211
220
  """Allow instances to be called like a function with flexible arguments."""
212
- result = self.process(*args, **kwargs) # Call the subclass-specific process method
213
- if self.CFG["verbose"]: # extract verbose value to display the output logs if True
214
- LOGGER.info(f"🚀 Results: {result}")
221
+ with self.profilers[1]:
222
+ result = self.process(*args, **kwargs) # Call the subclass-specific process method
223
+ track_or_predict = "predict" if type(self).__name__ == "ObjectCropper" else "track"
224
+ track_or_predict_speed = self.profilers[0].dt * 1e3
225
+ solution_speed = (self.profilers[1].dt - self.profilers[0].dt) * 1e3 # solution time = process - track
226
+ result.speed = {track_or_predict: track_or_predict_speed, "solution": solution_speed}
227
+ if self.CFG["verbose"]:
228
+ self.frame_no += 1
229
+ LOGGER.info(
230
+ f"{self.frame_no}: {result.plot_im.shape[0]}x{result.plot_im.shape[1]} {solution_speed:.1f}ms\n"
231
+ f"Speed: {track_or_predict_speed:.1f}ms {track_or_predict}, "
232
+ f"{solution_speed:.1f}ms solution per image at shape "
233
+ f"(1, {getattr(self.model, 'ch', 3)}, {result.plot_im.shape[0]}, {result.plot_im.shape[1]})\n"
234
+ )
215
235
  return result
216
236
 
217
237
 
@@ -703,8 +723,9 @@ class SolutionResults:
703
723
  self.email_sent = False
704
724
  self.total_tracks = 0
705
725
  self.region_counts = {}
706
- self.speed_dict = {}
726
+ self.speed_dict = {} # for speed estimation
707
727
  self.total_crop_objects = 0
728
+ self.speed = {}
708
729
 
709
730
  # Override with user-defined values
710
731
  self.__dict__.update(kwargs)
@@ -721,4 +742,4 @@ class SolutionResults:
721
742
  for k, v in self.__dict__.items()
722
743
  if k != "plot_im" and v not in [None, {}, 0, 0.0, False] # Exclude `plot_im` explicitly
723
744
  }
724
- return f"SolutionResults({', '.join(f'{k}={v}' for k, v in attrs.items())})"
745
+ return ", ".join(f"{k}={v}" for k, v in attrs.items())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ultralytics
3
- Version: 8.3.142
3
+ Version: 8.3.143
4
4
  Summary: Ultralytics YOLO 🚀 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
5
5
  Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>, Jing Qiu <jing.qiu@ultralytics.com>
6
6
  Maintainer-email: Ultralytics <hello@ultralytics.com>
@@ -6,8 +6,8 @@ tests/test_engine.py,sha256=aGqZ8P7QO5C_nOa1b4FOyk92Ysdk5WiP-ST310Vyxys,4962
6
6
  tests/test_exports.py,sha256=dhZn86LdbapW15RthQF870LGxDjC1MUZhlGdBgPmgIQ,9716
7
7
  tests/test_integrations.py,sha256=dQteeRsRVuT_p5-T88-7jqT65Zm9iAXkyKg-KQ1_TQ8,6341
8
8
  tests/test_python.py,sha256=Zx9OlPN11_D1WSLpi9nPFqORNHNz0lEn6mxVNL2ZHjE,25852
9
- tests/test_solutions.py,sha256=8qntPMu_k278R3ZTxaFXq1N7m9wLnvpXPdw33fobKSU,13045
10
- ultralytics/__init__.py,sha256=T4ynXZmZYPUGqZx8ZNeiubG6VRJpCbJSj5EVAnFqGtg,730
9
+ tests/test_solutions.py,sha256=4TryDaWOeY3HF33RZuYe9ofUZhgQrp4_nFI8tPUdiOc,13080
10
+ ultralytics/__init__.py,sha256=XEt2XO7rEliN-Fgis0qJ7S8kTmeX8cMWBWgI0jROIRY,730
11
11
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
12
12
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
13
13
  ultralytics/cfg/__init__.py,sha256=nDPCpYipxJ5XLjwwaoB5DNbovbOH-GM26_e2G5jDQ28,39580
@@ -211,14 +211,14 @@ ultralytics/solutions/distance_calculation.py,sha256=JyB1KC1WihwGLFX2R2kk4QEvo8Q
211
211
  ultralytics/solutions/heatmap.py,sha256=0Hw2Vhg4heglpnbNkM-RiGrQOkvgYbPRf4x8x4-zTjg,5418
212
212
  ultralytics/solutions/instance_segmentation.py,sha256=IuAxxEkKrbTPHmD0jV3VEjNWpBc78o8exg00nE0ldeQ,3558
213
213
  ultralytics/solutions/object_blurrer.py,sha256=-wXOdqqZisVhxLutZz7JvZmdgVGmsN7Ymary0JHc2qo,3946
214
- ultralytics/solutions/object_counter.py,sha256=iNy4D1VUNYZ1JzMa8RUqQq5RBPcpSIuG60Qe3hsfZiw,9534
215
- ultralytics/solutions/object_cropper.py,sha256=L6QZC5as_cUT42TMzeyXmkHa7vBi2UpNFf_-Jc7C1G0,3316
214
+ ultralytics/solutions/object_counter.py,sha256=49ixmy1OPv5D3CZmsZWQCigJstQvYIdK5aHypNBsZg8,9519
215
+ ultralytics/solutions/object_cropper.py,sha256=s56XQMpgCgeQg9KEZs2_7_cP_V-eH6315cY1bxt2oGs,3456
216
216
  ultralytics/solutions/parking_management.py,sha256=BV-2lpSfgmK7fib3DnPSZ5rtLdy11c8pBQm-72iTetc,13289
217
217
  ultralytics/solutions/queue_management.py,sha256=p1-cuI_rs4ygtlBryXjE65NYG2bnZXhp3ylggFnWcRs,4344
218
218
  ultralytics/solutions/region_counter.py,sha256=Zn35YRXNzhBk27D9MLOHBYe2L1o6H2ey3mEwCXofB_E,5418
219
219
  ultralytics/solutions/security_alarm.py,sha256=JdkQUjqJl3iCd2MLVYkh1L7askvhi3_gp0RLXG6s390,6247
220
220
  ultralytics/solutions/similarity_search.py,sha256=NVjrlxWStXPhSaE_tGW0g1_j8vD0evaT9IjGOHYERFg,7323
221
- ultralytics/solutions/solutions.py,sha256=1iZIj3Z5bs14WbVT8MIDXABfW-pBmfvQNdBJ6l21uVY,32696
221
+ ultralytics/solutions/solutions.py,sha256=zJ7CZh2U2VEUWe5LfC3XhVuc_HGOAQeHPM8ls3cmiZU,33681
222
222
  ultralytics/solutions/speed_estimation.py,sha256=r7S5nGIx8PTV-zC4zCI36lQD2DVy5cen5cTXItfQIHo,5318
223
223
  ultralytics/solutions/streamlit_inference.py,sha256=p1bBKTtmvB6zStXdOzS0CGYurm4zu82WKii5rJriizA,9849
224
224
  ultralytics/solutions/trackzone.py,sha256=mfklnZcVRqI3bbhPiHF2iSoV6INcd10wwwGP4tlK7L0,3854
@@ -264,9 +264,9 @@ ultralytics/utils/callbacks/neptune.py,sha256=yYUgEgSv6L39sSev6vjwhAWU3DlPDsbSDV
264
264
  ultralytics/utils/callbacks/raytune.py,sha256=A8amUGpux7dYES-L1iSeMoMXBySGWCD1aUqT7vcG-pU,1284
265
265
  ultralytics/utils/callbacks/tensorboard.py,sha256=jgYnym3cUQFAgN1GzTyO7l3jINtfAh8zhrllDvnLuVQ,5339
266
266
  ultralytics/utils/callbacks/wb.py,sha256=iDRFXI4IIDm8R5OI89DMTmjs8aHLo1HRCLkOFKdaMG4,7507
267
- ultralytics-8.3.142.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
268
- ultralytics-8.3.142.dist-info/METADATA,sha256=7W-oMpyVcu-nwCAur5sQWeVc38sKhvf3T0gpZw_WOwE,37200
269
- ultralytics-8.3.142.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
270
- ultralytics-8.3.142.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
271
- ultralytics-8.3.142.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
272
- ultralytics-8.3.142.dist-info/RECORD,,
267
+ ultralytics-8.3.143.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
268
+ ultralytics-8.3.143.dist-info/METADATA,sha256=6h1WXbu7DIx5NK21IIt4TCh-X9wA1uzwt5byThUM4kg,37200
269
+ ultralytics-8.3.143.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
270
+ ultralytics-8.3.143.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
271
+ ultralytics-8.3.143.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
272
+ ultralytics-8.3.143.dist-info/RECORD,,