ultralytics 8.3.86__py3-none-any.whl → 8.3.88__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 +47 -39
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/__init__.py +58 -55
- ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +1 -1
- ultralytics/cfg/models/11/yolo11-cls.yaml +6 -6
- ultralytics/data/augment.py +2 -2
- ultralytics/data/loaders.py +1 -1
- ultralytics/engine/exporter.py +1 -1
- ultralytics/engine/results.py +76 -41
- ultralytics/engine/trainer.py +11 -5
- ultralytics/engine/tuner.py +3 -2
- ultralytics/nn/autobackend.py +1 -1
- ultralytics/nn/tasks.py +1 -1
- ultralytics/solutions/__init__.py +14 -6
- ultralytics/solutions/ai_gym.py +39 -28
- ultralytics/solutions/analytics.py +22 -18
- ultralytics/solutions/distance_calculation.py +25 -25
- ultralytics/solutions/heatmap.py +40 -38
- ultralytics/solutions/instance_segmentation.py +69 -0
- ultralytics/solutions/object_blurrer.py +89 -0
- ultralytics/solutions/object_counter.py +35 -33
- ultralytics/solutions/object_cropper.py +84 -0
- ultralytics/solutions/parking_management.py +40 -13
- ultralytics/solutions/queue_management.py +20 -39
- ultralytics/solutions/region_counter.py +54 -51
- ultralytics/solutions/security_alarm.py +40 -30
- ultralytics/solutions/solutions.py +594 -16
- ultralytics/solutions/speed_estimation.py +34 -31
- ultralytics/solutions/streamlit_inference.py +34 -28
- ultralytics/solutions/trackzone.py +29 -18
- ultralytics/solutions/vision_eye.py +69 -0
- ultralytics/trackers/utils/kalman_filter.py +23 -23
- ultralytics/utils/__init__.py +2 -3
- ultralytics/utils/callbacks/comet.py +37 -5
- ultralytics/utils/instance.py +3 -3
- ultralytics/utils/plotting.py +0 -414
- {ultralytics-8.3.86.dist-info → ultralytics-8.3.88.dist-info}/METADATA +8 -8
- {ultralytics-8.3.86.dist-info → ultralytics-8.3.88.dist-info}/RECORD +42 -38
- {ultralytics-8.3.86.dist-info → ultralytics-8.3.88.dist-info}/WHEEL +1 -1
- {ultralytics-8.3.86.dist-info → ultralytics-8.3.88.dist-info}/LICENSE +0 -0
- {ultralytics-8.3.86.dist-info → ultralytics-8.3.88.dist-info}/entry_points.txt +0 -0
- {ultralytics-8.3.86.dist-info → ultralytics-8.3.88.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,10 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
|
-
|
2
|
+
from collections.abc import Callable
|
3
3
|
from types import SimpleNamespace
|
4
|
+
from typing import Any, List, Optional
|
5
|
+
|
6
|
+
import cv2
|
7
|
+
import numpy as np
|
4
8
|
|
5
9
|
from ultralytics.utils import LOGGER, RANK, SETTINGS, TESTS_RUNNING, ops
|
6
10
|
from ultralytics.utils.metrics import ClassifyMetrics, DetMetrics, OBBMetrics, PoseMetrics, SegmentMetrics
|
@@ -16,7 +20,7 @@ try:
|
|
16
20
|
from pathlib import Path
|
17
21
|
|
18
22
|
# Ensures certain logging functions only run for supported tasks
|
19
|
-
COMET_SUPPORTED_TASKS = ["detect"]
|
23
|
+
COMET_SUPPORTED_TASKS = ["detect", "segment"]
|
20
24
|
|
21
25
|
# Names of plots created by Ultralytics that are logged to Comet
|
22
26
|
CONFUSION_MATRIX_PLOT_NAMES = "confusion_matrix", "confusion_matrix_normalized"
|
@@ -177,7 +181,7 @@ def _format_ground_truth_annotations_for_detection(img_idx, image_path, batch, c
|
|
177
181
|
return {"name": "ground_truth", "data": data}
|
178
182
|
|
179
183
|
|
180
|
-
def
|
184
|
+
def _format_prediction_annotations(image_path, metadata, class_label_map=None, class_map=None):
|
181
185
|
"""Format YOLO predictions for object detection visualization."""
|
182
186
|
stem = image_path.stem
|
183
187
|
image_id = int(stem) if stem.isnumeric() else stem
|
@@ -193,6 +197,12 @@ def _format_prediction_annotations_for_detection(image_path, metadata, class_lab
|
|
193
197
|
# with prediction's category ID indices (can start from one)
|
194
198
|
label_index_offset = sorted(class_map)[0]
|
195
199
|
|
200
|
+
try:
|
201
|
+
# import pycotools utilities to decompress annotations for various tasks, e.g. segmentation
|
202
|
+
from pycocotools.mask import decode # noqa
|
203
|
+
except ImportError:
|
204
|
+
decode = None
|
205
|
+
|
196
206
|
data = []
|
197
207
|
for prediction in predictions:
|
198
208
|
boxes = prediction["bbox"]
|
@@ -201,17 +211,39 @@ def _format_prediction_annotations_for_detection(image_path, metadata, class_lab
|
|
201
211
|
if class_label_map:
|
202
212
|
cls_label = str(class_label_map[cls_label - label_index_offset])
|
203
213
|
|
204
|
-
|
214
|
+
annotation_data = {"boxes": [boxes], "label": cls_label, "score": score}
|
215
|
+
|
216
|
+
if decode is not None:
|
217
|
+
# do segmentation processing only if we are able to decode it
|
218
|
+
segments = prediction.get("segmentation", None)
|
219
|
+
if segments is not None:
|
220
|
+
segments = _extract_segmentation_annotation(segments, decode)
|
221
|
+
if segments is not None:
|
222
|
+
annotation_data["points"] = segments
|
223
|
+
|
224
|
+
data.append(annotation_data)
|
205
225
|
|
206
226
|
return {"name": "prediction", "data": data}
|
207
227
|
|
208
228
|
|
229
|
+
def _extract_segmentation_annotation(segmentation_raw: str, decode: Callable) -> Optional[List[List[Any]]]:
|
230
|
+
"""Extracts segmentation annotation from compressed segmentations as list of polygons."""
|
231
|
+
try:
|
232
|
+
mask = decode(segmentation_raw)
|
233
|
+
contours, _ = cv2.findContours(mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
|
234
|
+
annotations = [np.array(polygon).squeeze() for polygon in contours if len(polygon) >= 3]
|
235
|
+
return [annotation.ravel().tolist() for annotation in annotations]
|
236
|
+
except Exception as e:
|
237
|
+
LOGGER.warning(f"COMET WARNING: Failed to extract segmentation annotation: {e}")
|
238
|
+
return None
|
239
|
+
|
240
|
+
|
209
241
|
def _fetch_annotations(img_idx, image_path, batch, prediction_metadata_map, class_label_map, class_map):
|
210
242
|
"""Join the ground truth and prediction annotations if they exist."""
|
211
243
|
ground_truth_annotations = _format_ground_truth_annotations_for_detection(
|
212
244
|
img_idx, image_path, batch, class_label_map
|
213
245
|
)
|
214
|
-
prediction_annotations =
|
246
|
+
prediction_annotations = _format_prediction_annotations(
|
215
247
|
image_path, prediction_metadata_map, class_label_map, class_map
|
216
248
|
)
|
217
249
|
|
ultralytics/utils/instance.py
CHANGED
@@ -188,12 +188,12 @@ class Instances:
|
|
188
188
|
|
189
189
|
Attributes:
|
190
190
|
_bboxes (Bboxes): Internal object for handling bounding box operations.
|
191
|
-
keypoints (ndarray): keypoints(x, y, visible) with shape [N, 17, 3]. Default is None.
|
191
|
+
keypoints (np.ndarray): keypoints(x, y, visible) with shape [N, 17, 3]. Default is None.
|
192
192
|
normalized (bool): Flag indicating whether the bounding box coordinates are normalized.
|
193
|
-
segments (ndarray): Segments array with shape [N, 1000, 2] after resampling.
|
193
|
+
segments (np.ndarray): Segments array with shape [N, 1000, 2] after resampling.
|
194
194
|
|
195
195
|
Args:
|
196
|
-
bboxes (ndarray): An array of bounding boxes with shape [N, 4].
|
196
|
+
bboxes (np.ndarray): An array of bounding boxes with shape [N, 4].
|
197
197
|
segments (list | ndarray, optional): A list or array of object segments. Default is None.
|
198
198
|
keypoints (ndarray, optional): An array of keypoints with shape [N, 17, 3]. Default is None.
|
199
199
|
bbox_format (str, optional): The format of bounding boxes ('xywh' or 'xyxy'). Default is 'xywh'.
|
ultralytics/utils/plotting.py
CHANGED
@@ -271,84 +271,6 @@ class Annotator:
|
|
271
271
|
else:
|
272
272
|
return txt_color
|
273
273
|
|
274
|
-
def circle_label(self, box, label="", color=(128, 128, 128), txt_color=(255, 255, 255), margin=2):
|
275
|
-
"""
|
276
|
-
Draws a label with a background circle centered within a given bounding box.
|
277
|
-
|
278
|
-
Args:
|
279
|
-
box (tuple): The bounding box coordinates (x1, y1, x2, y2).
|
280
|
-
label (str): The text label to be displayed.
|
281
|
-
color (tuple, optional): The background color of the rectangle (B, G, R).
|
282
|
-
txt_color (tuple, optional): The color of the text (R, G, B).
|
283
|
-
margin (int, optional): The margin between the text and the rectangle border.
|
284
|
-
"""
|
285
|
-
# If label have more than 3 characters, skip other characters, due to circle size
|
286
|
-
if len(label) > 3:
|
287
|
-
print(
|
288
|
-
f"Length of label is {len(label)}, initial 3 label characters will be considered for circle annotation!"
|
289
|
-
)
|
290
|
-
label = label[:3]
|
291
|
-
|
292
|
-
# Calculate the center of the box
|
293
|
-
x_center, y_center = int((box[0] + box[2]) / 2), int((box[1] + box[3]) / 2)
|
294
|
-
# Get the text size
|
295
|
-
text_size = cv2.getTextSize(str(label), cv2.FONT_HERSHEY_SIMPLEX, self.sf - 0.15, self.tf)[0]
|
296
|
-
# Calculate the required radius to fit the text with the margin
|
297
|
-
required_radius = int(((text_size[0] ** 2 + text_size[1] ** 2) ** 0.5) / 2) + margin
|
298
|
-
# Draw the circle with the required radius
|
299
|
-
cv2.circle(self.im, (x_center, y_center), required_radius, color, -1)
|
300
|
-
# Calculate the position for the text
|
301
|
-
text_x = x_center - text_size[0] // 2
|
302
|
-
text_y = y_center + text_size[1] // 2
|
303
|
-
# Draw the text
|
304
|
-
cv2.putText(
|
305
|
-
self.im,
|
306
|
-
str(label),
|
307
|
-
(text_x, text_y),
|
308
|
-
cv2.FONT_HERSHEY_SIMPLEX,
|
309
|
-
self.sf - 0.15,
|
310
|
-
self.get_txt_color(color, txt_color),
|
311
|
-
self.tf,
|
312
|
-
lineType=cv2.LINE_AA,
|
313
|
-
)
|
314
|
-
|
315
|
-
def text_label(self, box, label="", color=(128, 128, 128), txt_color=(255, 255, 255), margin=5):
|
316
|
-
"""
|
317
|
-
Draws a label with a background rectangle centered within a given bounding box.
|
318
|
-
|
319
|
-
Args:
|
320
|
-
box (tuple): The bounding box coordinates (x1, y1, x2, y2).
|
321
|
-
label (str): The text label to be displayed.
|
322
|
-
color (tuple, optional): The background color of the rectangle (B, G, R).
|
323
|
-
txt_color (tuple, optional): The color of the text (R, G, B).
|
324
|
-
margin (int, optional): The margin between the text and the rectangle border.
|
325
|
-
"""
|
326
|
-
# Calculate the center of the bounding box
|
327
|
-
x_center, y_center = int((box[0] + box[2]) / 2), int((box[1] + box[3]) / 2)
|
328
|
-
# Get the size of the text
|
329
|
-
text_size = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, self.sf - 0.1, self.tf)[0]
|
330
|
-
# Calculate the top-left corner of the text (to center it)
|
331
|
-
text_x = x_center - text_size[0] // 2
|
332
|
-
text_y = y_center + text_size[1] // 2
|
333
|
-
# Calculate the coordinates of the background rectangle
|
334
|
-
rect_x1 = text_x - margin
|
335
|
-
rect_y1 = text_y - text_size[1] - margin
|
336
|
-
rect_x2 = text_x + text_size[0] + margin
|
337
|
-
rect_y2 = text_y + margin
|
338
|
-
# Draw the background rectangle
|
339
|
-
cv2.rectangle(self.im, (rect_x1, rect_y1), (rect_x2, rect_y2), color, -1)
|
340
|
-
# Draw the text on top of the rectangle
|
341
|
-
cv2.putText(
|
342
|
-
self.im,
|
343
|
-
label,
|
344
|
-
(text_x, text_y),
|
345
|
-
cv2.FONT_HERSHEY_SIMPLEX,
|
346
|
-
self.sf - 0.1,
|
347
|
-
self.get_txt_color(color, txt_color),
|
348
|
-
self.tf,
|
349
|
-
lineType=cv2.LINE_AA,
|
350
|
-
)
|
351
|
-
|
352
274
|
def box_label(self, box, label="", color=(128, 128, 128), txt_color=(255, 255, 255), rotated=False):
|
353
275
|
"""
|
354
276
|
Draws a bounding box to image with label.
|
@@ -591,342 +513,6 @@ class Annotator:
|
|
591
513
|
height = y_max - y_min
|
592
514
|
return width, height, width * height
|
593
515
|
|
594
|
-
def draw_region(self, reg_pts=None, color=(0, 255, 0), thickness=5):
|
595
|
-
"""
|
596
|
-
Draw region line.
|
597
|
-
|
598
|
-
Args:
|
599
|
-
reg_pts (list): Region Points (for line 2 points, for region 4 points)
|
600
|
-
color (tuple): Region Color value
|
601
|
-
thickness (int): Region area thickness value
|
602
|
-
"""
|
603
|
-
cv2.polylines(self.im, [np.array(reg_pts, dtype=np.int32)], isClosed=True, color=color, thickness=thickness)
|
604
|
-
|
605
|
-
# Draw small circles at the corner points
|
606
|
-
for point in reg_pts:
|
607
|
-
cv2.circle(self.im, (point[0], point[1]), thickness * 2, color, -1) # -1 fills the circle
|
608
|
-
|
609
|
-
def draw_centroid_and_tracks(self, track, color=(255, 0, 255), track_thickness=2):
|
610
|
-
"""
|
611
|
-
Draw centroid point and track trails.
|
612
|
-
|
613
|
-
Args:
|
614
|
-
track (list): object tracking points for trails display
|
615
|
-
color (tuple): tracks line color
|
616
|
-
track_thickness (int): track line thickness value
|
617
|
-
"""
|
618
|
-
points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))
|
619
|
-
cv2.polylines(self.im, [points], isClosed=False, color=color, thickness=track_thickness)
|
620
|
-
cv2.circle(self.im, (int(track[-1][0]), int(track[-1][1])), track_thickness * 2, color, -1)
|
621
|
-
|
622
|
-
def queue_counts_display(self, label, points=None, region_color=(255, 255, 255), txt_color=(0, 0, 0)):
|
623
|
-
"""
|
624
|
-
Displays queue counts on an image centered at the points with customizable font size and colors.
|
625
|
-
|
626
|
-
Args:
|
627
|
-
label (str): Queue counts label.
|
628
|
-
points (tuple): Region points for center point calculation to display text.
|
629
|
-
region_color (tuple): RGB queue region color.
|
630
|
-
txt_color (tuple): RGB text display color.
|
631
|
-
"""
|
632
|
-
x_values = [point[0] for point in points]
|
633
|
-
y_values = [point[1] for point in points]
|
634
|
-
center_x = sum(x_values) // len(points)
|
635
|
-
center_y = sum(y_values) // len(points)
|
636
|
-
|
637
|
-
text_size = cv2.getTextSize(label, 0, fontScale=self.sf, thickness=self.tf)[0]
|
638
|
-
text_width = text_size[0]
|
639
|
-
text_height = text_size[1]
|
640
|
-
|
641
|
-
rect_width = text_width + 20
|
642
|
-
rect_height = text_height + 20
|
643
|
-
rect_top_left = (center_x - rect_width // 2, center_y - rect_height // 2)
|
644
|
-
rect_bottom_right = (center_x + rect_width // 2, center_y + rect_height // 2)
|
645
|
-
cv2.rectangle(self.im, rect_top_left, rect_bottom_right, region_color, -1)
|
646
|
-
|
647
|
-
text_x = center_x - text_width // 2
|
648
|
-
text_y = center_y + text_height // 2
|
649
|
-
|
650
|
-
# Draw text
|
651
|
-
cv2.putText(
|
652
|
-
self.im,
|
653
|
-
label,
|
654
|
-
(text_x, text_y),
|
655
|
-
0,
|
656
|
-
fontScale=self.sf,
|
657
|
-
color=txt_color,
|
658
|
-
thickness=self.tf,
|
659
|
-
lineType=cv2.LINE_AA,
|
660
|
-
)
|
661
|
-
|
662
|
-
def display_objects_labels(self, im0, text, txt_color, bg_color, x_center, y_center, margin):
|
663
|
-
"""
|
664
|
-
Display the bounding boxes labels in parking management app.
|
665
|
-
|
666
|
-
Args:
|
667
|
-
im0 (ndarray): Inference image.
|
668
|
-
text (str): Object/class name.
|
669
|
-
txt_color (tuple): Display color for text foreground.
|
670
|
-
bg_color (tuple): Display color for text background.
|
671
|
-
x_center (float): The x position center point for bounding box.
|
672
|
-
y_center (float): The y position center point for bounding box.
|
673
|
-
margin (int): The gap between text and rectangle for better display.
|
674
|
-
"""
|
675
|
-
text_size = cv2.getTextSize(text, 0, fontScale=self.sf, thickness=self.tf)[0]
|
676
|
-
text_x = x_center - text_size[0] // 2
|
677
|
-
text_y = y_center + text_size[1] // 2
|
678
|
-
|
679
|
-
rect_x1 = text_x - margin
|
680
|
-
rect_y1 = text_y - text_size[1] - margin
|
681
|
-
rect_x2 = text_x + text_size[0] + margin
|
682
|
-
rect_y2 = text_y + margin
|
683
|
-
cv2.rectangle(im0, (rect_x1, rect_y1), (rect_x2, rect_y2), bg_color, -1)
|
684
|
-
cv2.putText(im0, text, (text_x, text_y), 0, self.sf, txt_color, self.tf, lineType=cv2.LINE_AA)
|
685
|
-
|
686
|
-
def display_analytics(self, im0, text, txt_color, bg_color, margin):
|
687
|
-
"""
|
688
|
-
Display the overall statistics for parking lots.
|
689
|
-
|
690
|
-
Args:
|
691
|
-
im0 (ndarray): Inference image.
|
692
|
-
text (dict): Labels dictionary.
|
693
|
-
txt_color (tuple): Display color for text foreground.
|
694
|
-
bg_color (tuple): Display color for text background.
|
695
|
-
margin (int): Gap between text and rectangle for better display.
|
696
|
-
"""
|
697
|
-
horizontal_gap = int(im0.shape[1] * 0.02)
|
698
|
-
vertical_gap = int(im0.shape[0] * 0.01)
|
699
|
-
text_y_offset = 0
|
700
|
-
for label, value in text.items():
|
701
|
-
txt = f"{label}: {value}"
|
702
|
-
text_size = cv2.getTextSize(txt, 0, self.sf, self.tf)[0]
|
703
|
-
if text_size[0] < 5 or text_size[1] < 5:
|
704
|
-
text_size = (5, 5)
|
705
|
-
text_x = im0.shape[1] - text_size[0] - margin * 2 - horizontal_gap
|
706
|
-
text_y = text_y_offset + text_size[1] + margin * 2 + vertical_gap
|
707
|
-
rect_x1 = text_x - margin * 2
|
708
|
-
rect_y1 = text_y - text_size[1] - margin * 2
|
709
|
-
rect_x2 = text_x + text_size[0] + margin * 2
|
710
|
-
rect_y2 = text_y + margin * 2
|
711
|
-
cv2.rectangle(im0, (rect_x1, rect_y1), (rect_x2, rect_y2), bg_color, -1)
|
712
|
-
cv2.putText(im0, txt, (text_x, text_y), 0, self.sf, txt_color, self.tf, lineType=cv2.LINE_AA)
|
713
|
-
text_y_offset = rect_y2
|
714
|
-
|
715
|
-
@staticmethod
|
716
|
-
def estimate_pose_angle(a, b, c):
|
717
|
-
"""
|
718
|
-
Calculate the pose angle for object.
|
719
|
-
|
720
|
-
Args:
|
721
|
-
a (float) : The value of pose point a
|
722
|
-
b (float): The value of pose point b
|
723
|
-
c (float): The value o pose point c
|
724
|
-
|
725
|
-
Returns:
|
726
|
-
angle (degree): Degree value of angle between three points
|
727
|
-
"""
|
728
|
-
a, b, c = np.array(a), np.array(b), np.array(c)
|
729
|
-
radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])
|
730
|
-
angle = np.abs(radians * 180.0 / np.pi)
|
731
|
-
if angle > 180.0:
|
732
|
-
angle = 360 - angle
|
733
|
-
return angle
|
734
|
-
|
735
|
-
def draw_specific_points(self, keypoints, indices=None, radius=2, conf_thres=0.25):
|
736
|
-
"""
|
737
|
-
Draw specific keypoints for gym steps counting.
|
738
|
-
|
739
|
-
Args:
|
740
|
-
keypoints (list): Keypoints data to be plotted.
|
741
|
-
indices (list, optional): Keypoint indices to be plotted. Defaults to [2, 5, 7].
|
742
|
-
radius (int, optional): Keypoint radius. Defaults to 2.
|
743
|
-
conf_thres (float, optional): Confidence threshold for keypoints. Defaults to 0.25.
|
744
|
-
|
745
|
-
Returns:
|
746
|
-
(numpy.ndarray): Image with drawn keypoints.
|
747
|
-
|
748
|
-
Note:
|
749
|
-
Keypoint format: [x, y] or [x, y, confidence].
|
750
|
-
Modifies self.im in-place.
|
751
|
-
"""
|
752
|
-
indices = indices or [2, 5, 7]
|
753
|
-
points = [(int(k[0]), int(k[1])) for i, k in enumerate(keypoints) if i in indices and k[2] >= conf_thres]
|
754
|
-
|
755
|
-
# Draw lines between consecutive points
|
756
|
-
for start, end in zip(points[:-1], points[1:]):
|
757
|
-
cv2.line(self.im, start, end, (0, 255, 0), 2, lineType=cv2.LINE_AA)
|
758
|
-
|
759
|
-
# Draw circles for keypoints
|
760
|
-
for pt in points:
|
761
|
-
cv2.circle(self.im, pt, radius, (0, 0, 255), -1, lineType=cv2.LINE_AA)
|
762
|
-
|
763
|
-
return self.im
|
764
|
-
|
765
|
-
def plot_workout_information(self, display_text, position, color=(104, 31, 17), txt_color=(255, 255, 255)):
|
766
|
-
"""
|
767
|
-
Draw text with a background on the image.
|
768
|
-
|
769
|
-
Args:
|
770
|
-
display_text (str): The text to be displayed.
|
771
|
-
position (tuple): Coordinates (x, y) on the image where the text will be placed.
|
772
|
-
color (tuple, optional): Text background color
|
773
|
-
txt_color (tuple, optional): Text foreground color
|
774
|
-
"""
|
775
|
-
(text_width, text_height), _ = cv2.getTextSize(display_text, 0, self.sf, self.tf)
|
776
|
-
|
777
|
-
# Draw background rectangle
|
778
|
-
cv2.rectangle(
|
779
|
-
self.im,
|
780
|
-
(position[0], position[1] - text_height - 5),
|
781
|
-
(position[0] + text_width + 10, position[1] - text_height - 5 + text_height + 10 + self.tf),
|
782
|
-
color,
|
783
|
-
-1,
|
784
|
-
)
|
785
|
-
# Draw text
|
786
|
-
cv2.putText(self.im, display_text, position, 0, self.sf, txt_color, self.tf)
|
787
|
-
|
788
|
-
return text_height
|
789
|
-
|
790
|
-
def plot_angle_and_count_and_stage(
|
791
|
-
self, angle_text, count_text, stage_text, center_kpt, color=(104, 31, 17), txt_color=(255, 255, 255)
|
792
|
-
):
|
793
|
-
"""
|
794
|
-
Plot the pose angle, count value, and step stage.
|
795
|
-
|
796
|
-
Args:
|
797
|
-
angle_text (str): Angle value for workout monitoring
|
798
|
-
count_text (str): Counts value for workout monitoring
|
799
|
-
stage_text (str): Stage decision for workout monitoring
|
800
|
-
center_kpt (list): Centroid pose index for workout monitoring
|
801
|
-
color (tuple, optional): Text background color
|
802
|
-
txt_color (tuple, optional): Text foreground color
|
803
|
-
"""
|
804
|
-
# Format text
|
805
|
-
angle_text, count_text, stage_text = f" {angle_text:.2f}", f"Steps : {count_text}", f" {stage_text}"
|
806
|
-
|
807
|
-
# Draw angle, count and stage text
|
808
|
-
angle_height = self.plot_workout_information(
|
809
|
-
angle_text, (int(center_kpt[0]), int(center_kpt[1])), color, txt_color
|
810
|
-
)
|
811
|
-
count_height = self.plot_workout_information(
|
812
|
-
count_text, (int(center_kpt[0]), int(center_kpt[1]) + angle_height + 20), color, txt_color
|
813
|
-
)
|
814
|
-
self.plot_workout_information(
|
815
|
-
stage_text, (int(center_kpt[0]), int(center_kpt[1]) + angle_height + count_height + 40), color, txt_color
|
816
|
-
)
|
817
|
-
|
818
|
-
def seg_bbox(self, mask, mask_color=(255, 0, 255), label=None, txt_color=(255, 255, 255)):
|
819
|
-
"""
|
820
|
-
Function for drawing segmented object in bounding box shape.
|
821
|
-
|
822
|
-
Args:
|
823
|
-
mask (np.ndarray): A 2D array of shape (N, 2) containing the contour points of the segmented object.
|
824
|
-
mask_color (tuple): RGB color for the contour and label background.
|
825
|
-
label (str, optional): Text label for the object. If None, no label is drawn.
|
826
|
-
txt_color (tuple): RGB color for the label text.
|
827
|
-
"""
|
828
|
-
if mask.size == 0: # no masks to plot
|
829
|
-
return
|
830
|
-
|
831
|
-
cv2.polylines(self.im, [np.int32([mask])], isClosed=True, color=mask_color, thickness=2)
|
832
|
-
if label:
|
833
|
-
text_size, _ = cv2.getTextSize(label, 0, self.sf, self.tf)
|
834
|
-
cv2.rectangle(
|
835
|
-
self.im,
|
836
|
-
(int(mask[0][0]) - text_size[0] // 2 - 10, int(mask[0][1]) - text_size[1] - 10),
|
837
|
-
(int(mask[0][0]) + text_size[0] // 2 + 10, int(mask[0][1] + 10)),
|
838
|
-
mask_color,
|
839
|
-
-1,
|
840
|
-
)
|
841
|
-
cv2.putText(
|
842
|
-
self.im, label, (int(mask[0][0]) - text_size[0] // 2, int(mask[0][1])), 0, self.sf, txt_color, self.tf
|
843
|
-
)
|
844
|
-
|
845
|
-
def sweep_annotator(self, line_x=0, line_y=0, label=None, color=(221, 0, 186), txt_color=(255, 255, 255)):
|
846
|
-
"""
|
847
|
-
Function for drawing a sweep annotation line and an optional label.
|
848
|
-
|
849
|
-
Args:
|
850
|
-
line_x (int): The x-coordinate of the sweep line.
|
851
|
-
line_y (int): The y-coordinate limit of the sweep line.
|
852
|
-
label (str, optional): Text label to be drawn in center of sweep line. If None, no label is drawn.
|
853
|
-
color (tuple): RGB color for the line and label background.
|
854
|
-
txt_color (tuple): RGB color for the label text.
|
855
|
-
"""
|
856
|
-
# Draw the sweep line
|
857
|
-
cv2.line(self.im, (line_x, 0), (line_x, line_y), color, self.tf * 2)
|
858
|
-
|
859
|
-
# Draw label, if provided
|
860
|
-
if label:
|
861
|
-
(text_width, text_height), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, self.sf, self.tf)
|
862
|
-
cv2.rectangle(
|
863
|
-
self.im,
|
864
|
-
(line_x - text_width // 2 - 10, line_y // 2 - text_height // 2 - 10),
|
865
|
-
(line_x + text_width // 2 + 10, line_y // 2 + text_height // 2 + 10),
|
866
|
-
color,
|
867
|
-
-1,
|
868
|
-
)
|
869
|
-
cv2.putText(
|
870
|
-
self.im,
|
871
|
-
label,
|
872
|
-
(line_x - text_width // 2, line_y // 2 + text_height // 2),
|
873
|
-
cv2.FONT_HERSHEY_SIMPLEX,
|
874
|
-
self.sf,
|
875
|
-
txt_color,
|
876
|
-
self.tf,
|
877
|
-
)
|
878
|
-
|
879
|
-
def plot_distance_and_line(
|
880
|
-
self, pixels_distance, centroids, line_color=(104, 31, 17), centroid_color=(255, 0, 255)
|
881
|
-
):
|
882
|
-
"""
|
883
|
-
Plot the distance and line on frame.
|
884
|
-
|
885
|
-
Args:
|
886
|
-
pixels_distance (float): Pixels distance between two bbox centroids.
|
887
|
-
centroids (list): Bounding box centroids data.
|
888
|
-
line_color (tuple, optional): Distance line color.
|
889
|
-
centroid_color (tuple, optional): Bounding box centroid color.
|
890
|
-
"""
|
891
|
-
# Get the text size
|
892
|
-
text = f"Pixels Distance: {pixels_distance:.2f}"
|
893
|
-
(text_width_m, text_height_m), _ = cv2.getTextSize(text, 0, self.sf, self.tf)
|
894
|
-
|
895
|
-
# Define corners with 10-pixel margin and draw rectangle
|
896
|
-
cv2.rectangle(self.im, (15, 25), (15 + text_width_m + 20, 25 + text_height_m + 20), line_color, -1)
|
897
|
-
|
898
|
-
# Calculate the position for the text with a 10-pixel margin and draw text
|
899
|
-
text_position = (25, 25 + text_height_m + 10)
|
900
|
-
cv2.putText(
|
901
|
-
self.im,
|
902
|
-
text,
|
903
|
-
text_position,
|
904
|
-
0,
|
905
|
-
self.sf,
|
906
|
-
(255, 255, 255),
|
907
|
-
self.tf,
|
908
|
-
cv2.LINE_AA,
|
909
|
-
)
|
910
|
-
|
911
|
-
cv2.line(self.im, centroids[0], centroids[1], line_color, 3)
|
912
|
-
cv2.circle(self.im, centroids[0], 6, centroid_color, -1)
|
913
|
-
cv2.circle(self.im, centroids[1], 6, centroid_color, -1)
|
914
|
-
|
915
|
-
def visioneye(self, box, center_point, color=(235, 219, 11), pin_color=(255, 0, 255)):
|
916
|
-
"""
|
917
|
-
Function for pinpoint human-vision eye mapping and plotting.
|
918
|
-
|
919
|
-
Args:
|
920
|
-
box (list): Bounding box coordinates
|
921
|
-
center_point (tuple): center point for vision eye view
|
922
|
-
color (tuple): object centroid and line color value
|
923
|
-
pin_color (tuple): visioneye point color value
|
924
|
-
"""
|
925
|
-
center_bbox = int((box[0] + box[2]) / 2), int((box[1] + box[3]) / 2)
|
926
|
-
cv2.circle(self.im, center_point, self.tf * 2, pin_color, -1)
|
927
|
-
cv2.circle(self.im, center_bbox, self.tf * 2, color, -1)
|
928
|
-
cv2.line(self.im, center_point, center_bbox, color, self.tf)
|
929
|
-
|
930
516
|
|
931
517
|
@TryExcept() # known issue https://github.com/ultralytics/yolov5/issues/5395
|
932
518
|
@plt_settings()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: ultralytics
|
3
|
-
Version: 8.3.
|
3
|
+
Version: 8.3.88
|
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>
|
@@ -63,7 +63,7 @@ Provides-Extra: export
|
|
63
63
|
Requires-Dist: onnx>=1.12.0; extra == "export"
|
64
64
|
Requires-Dist: coremltools>=7.0; (platform_system != "Windows" and python_version <= "3.11") and extra == "export"
|
65
65
|
Requires-Dist: scikit-learn>=1.3.2; (platform_system != "Windows" and python_version <= "3.11") and extra == "export"
|
66
|
-
Requires-Dist: openvino
|
66
|
+
Requires-Dist: openvino!=2025.0.0,>=2024.0.0; extra == "export"
|
67
67
|
Requires-Dist: tensorflow>=2.0.0; extra == "export"
|
68
68
|
Requires-Dist: tensorflowjs>=3.9.0; extra == "export"
|
69
69
|
Requires-Dist: tensorstore>=0.1.63; (platform_machine == "aarch64" and python_version >= "3.9") and extra == "export"
|
@@ -248,13 +248,13 @@ See [Segmentation Docs](https://docs.ultralytics.com/tasks/segment/) for usage e
|
|
248
248
|
|
249
249
|
See [Classification Docs](https://docs.ultralytics.com/tasks/classify/) for usage examples with these models trained on [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/), which include 1000 pretrained classes.
|
250
250
|
|
251
|
-
| Model | size<br><sup>(pixels) | acc<br><sup>top1 | acc<br><sup>top5 | Speed<br><sup>CPU ONNX<br>(ms) | Speed<br><sup>T4 TensorRT10<br>(ms) | params<br><sup>(M) | FLOPs<br><sup>(B) at
|
251
|
+
| Model | size<br><sup>(pixels) | acc<br><sup>top1 | acc<br><sup>top5 | Speed<br><sup>CPU ONNX<br>(ms) | Speed<br><sup>T4 TensorRT10<br>(ms) | params<br><sup>(M) | FLOPs<br><sup>(B) at 224 |
|
252
252
|
| -------------------------------------------------------------------------------------------- | --------------------- | ---------------- | ---------------- | ------------------------------ | ----------------------------------- | ------------------ | ------------------------ |
|
253
|
-
| [YOLO11n-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n-cls.pt) | 224 | 70.0 | 89.4 | 5.0 ± 0.3 | 1.1 ± 0.0 | 1.6 |
|
254
|
-
| [YOLO11s-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11s-cls.pt) | 224 | 75.4 | 92.7 | 7.9 ± 0.2 | 1.3 ± 0.0 | 5.5 |
|
255
|
-
| [YOLO11m-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11m-cls.pt) | 224 | 77.3 | 93.9 | 17.2 ± 0.4 | 2.0 ± 0.0 | 10.4 |
|
256
|
-
| [YOLO11l-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11l-cls.pt) | 224 | 78.3 | 94.3 | 23.2 ± 0.3 | 2.8 ± 0.0 | 12.9 |
|
257
|
-
| [YOLO11x-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11x-cls.pt) | 224 | 79.5 | 94.9 | 41.4 ± 0.9 | 3.8 ± 0.0 | 28.4 |
|
253
|
+
| [YOLO11n-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n-cls.pt) | 224 | 70.0 | 89.4 | 5.0 ± 0.3 | 1.1 ± 0.0 | 1.6 | 0.5 |
|
254
|
+
| [YOLO11s-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11s-cls.pt) | 224 | 75.4 | 92.7 | 7.9 ± 0.2 | 1.3 ± 0.0 | 5.5 | 1.6 |
|
255
|
+
| [YOLO11m-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11m-cls.pt) | 224 | 77.3 | 93.9 | 17.2 ± 0.4 | 2.0 ± 0.0 | 10.4 | 5.0 |
|
256
|
+
| [YOLO11l-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11l-cls.pt) | 224 | 78.3 | 94.3 | 23.2 ± 0.3 | 2.8 ± 0.0 | 12.9 | 6.2 |
|
257
|
+
| [YOLO11x-cls](https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11x-cls.pt) | 224 | 79.5 | 94.9 | 41.4 ± 0.9 | 3.8 ± 0.0 | 28.4 | 13.7 |
|
258
258
|
|
259
259
|
- **acc** values are model accuracies on the [ImageNet](https://www.image-net.org/) dataset validation set. <br>Reproduce by `yolo val classify data=path/to/ImageNet device=0`
|
260
260
|
- **Speed** averaged over ImageNet val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) instance. <br>Reproduce by `yolo val classify data=path/to/ImageNet batch=1 device=0|cpu`
|