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 +1 -1
- ultralytics/__init__.py +1 -1
- ultralytics/solutions/object_counter.py +1 -1
- ultralytics/solutions/object_cropper.py +9 -3
- ultralytics/solutions/solutions.py +32 -11
- {ultralytics-8.3.142.dist-info → ultralytics-8.3.143.dist-info}/METADATA +1 -1
- {ultralytics-8.3.142.dist-info → ultralytics-8.3.143.dist-info}/RECORD +11 -11
- {ultralytics-8.3.142.dist-info → ultralytics-8.3.143.dist-info}/WHEEL +0 -0
- {ultralytics-8.3.142.dist-info → ultralytics-8.3.143.dist-info}/entry_points.txt +0 -0
- {ultralytics-8.3.142.dist-info → ultralytics-8.3.143.dist-info}/licenses/LICENSE +0 -0
- {ultralytics-8.3.142.dist-info → ultralytics-8.3.143.dist-info}/top_level.txt +0 -0
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=
|
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
@@ -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
|
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
|
-
|
71
|
-
|
72
|
-
|
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"
|
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
|
-
|
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
|
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
|
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
|
-
|
213
|
-
|
214
|
-
|
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
|
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.
|
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=
|
10
|
-
ultralytics/__init__.py,sha256=
|
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=
|
215
|
-
ultralytics/solutions/object_cropper.py,sha256=
|
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=
|
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.
|
268
|
-
ultralytics-8.3.
|
269
|
-
ultralytics-8.3.
|
270
|
-
ultralytics-8.3.
|
271
|
-
ultralytics-8.3.
|
272
|
-
ultralytics-8.3.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|