ultralytics 8.3.162__py3-none-any.whl → 8.3.163__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.
- ultralytics/__init__.py +1 -1
- ultralytics/data/utils.py +3 -2
- ultralytics/engine/exporter.py +2 -2
- ultralytics/engine/predictor.py +6 -6
- ultralytics/nn/tasks.py +2 -0
- ultralytics/solutions/region_counter.py +29 -32
- {ultralytics-8.3.162.dist-info → ultralytics-8.3.163.dist-info}/METADATA +1 -1
- {ultralytics-8.3.162.dist-info → ultralytics-8.3.163.dist-info}/RECORD +12 -12
- {ultralytics-8.3.162.dist-info → ultralytics-8.3.163.dist-info}/WHEEL +0 -0
- {ultralytics-8.3.162.dist-info → ultralytics-8.3.163.dist-info}/entry_points.txt +0 -0
- {ultralytics-8.3.162.dist-info → ultralytics-8.3.163.dist-info}/licenses/LICENSE +0 -0
- {ultralytics-8.3.162.dist-info → ultralytics-8.3.163.dist-info}/top_level.txt +0 -0
ultralytics/__init__.py
CHANGED
ultralytics/data/utils.py
CHANGED
@@ -214,8 +214,9 @@ def verify_image_label(args: Tuple) -> List:
|
|
214
214
|
else:
|
215
215
|
assert lb.shape[1] == 5, f"labels require 5 columns, {lb.shape[1]} columns detected"
|
216
216
|
points = lb[:, 1:]
|
217
|
-
|
218
|
-
assert
|
217
|
+
# Coordinate points check with 1% tolerance
|
218
|
+
assert points.max() <= 1.01, f"non-normalized or out of bounds coordinates {points[points > 1.01]}"
|
219
|
+
assert lb.min() >= -0.01, f"negative class labels {lb[lb < -0.01]}"
|
219
220
|
|
220
221
|
# All labels
|
221
222
|
if single_cls:
|
ultralytics/engine/exporter.py
CHANGED
@@ -574,7 +574,7 @@ class Exporter:
|
|
574
574
|
"""Export YOLO model to ONNX format."""
|
575
575
|
requirements = ["onnx>=1.12.0,<1.18.0"]
|
576
576
|
if self.args.simplify:
|
577
|
-
requirements += ["onnxslim>=0.1.
|
577
|
+
requirements += ["onnxslim>=0.1.59", "onnxruntime" + ("-gpu" if torch.cuda.is_available() else "")]
|
578
578
|
check_requirements(requirements)
|
579
579
|
import onnx # noqa
|
580
580
|
|
@@ -952,7 +952,7 @@ class Exporter:
|
|
952
952
|
"ai-edge-litert>=1.2.0,<1.4.0", # required by 'onnx2tf' package
|
953
953
|
"onnx>=1.12.0,<1.18.0",
|
954
954
|
"onnx2tf>=1.26.3",
|
955
|
-
"onnxslim>=0.1.
|
955
|
+
"onnxslim>=0.1.59",
|
956
956
|
"onnxruntime-gpu" if cuda else "onnxruntime",
|
957
957
|
"protobuf>=5",
|
958
958
|
),
|
ultralytics/engine/predictor.py
CHANGED
@@ -452,16 +452,16 @@ class BasePredictor:
|
|
452
452
|
if self.args.show:
|
453
453
|
self.show(str(p))
|
454
454
|
if self.args.save:
|
455
|
-
self.save_predicted_images(
|
455
|
+
self.save_predicted_images(self.save_dir / p.name, frame)
|
456
456
|
|
457
457
|
return string
|
458
458
|
|
459
|
-
def save_predicted_images(self, save_path:
|
459
|
+
def save_predicted_images(self, save_path: Path, frame: int = 0):
|
460
460
|
"""
|
461
461
|
Save video predictions as mp4 or images as jpg at specified path.
|
462
462
|
|
463
463
|
Args:
|
464
|
-
save_path (
|
464
|
+
save_path (Path): Path to save the results.
|
465
465
|
frame (int): Frame number for video mode.
|
466
466
|
"""
|
467
467
|
im = self.plotted_img
|
@@ -469,7 +469,7 @@ class BasePredictor:
|
|
469
469
|
# Save videos and streams
|
470
470
|
if self.dataset.mode in {"stream", "video"}:
|
471
471
|
fps = self.dataset.fps if self.dataset.mode == "video" else 30
|
472
|
-
frames_path = f"{save_path.
|
472
|
+
frames_path = self.save_dir / f"{save_path.stem}_frames" # save frames to a separate directory
|
473
473
|
if save_path not in self.vid_writer: # new video
|
474
474
|
if self.args.save_frames:
|
475
475
|
Path(frames_path).mkdir(parents=True, exist_ok=True)
|
@@ -484,11 +484,11 @@ class BasePredictor:
|
|
484
484
|
# Save video
|
485
485
|
self.vid_writer[save_path].write(im)
|
486
486
|
if self.args.save_frames:
|
487
|
-
cv2.imwrite(f"{frames_path}{frame}.jpg", im)
|
487
|
+
cv2.imwrite(f"{frames_path}/{save_path.stem}_{frame}.jpg", im)
|
488
488
|
|
489
489
|
# Save images
|
490
490
|
else:
|
491
|
-
cv2.imwrite(str(
|
491
|
+
cv2.imwrite(str(save_path.with_suffix(".jpg")), im) # save to JPG for best support
|
492
492
|
|
493
493
|
def show(self, p: str = ""):
|
494
494
|
"""Display an image in a window."""
|
ultralytics/nn/tasks.py
CHANGED
@@ -249,6 +249,8 @@ class BaseModel(torch.nn.Module):
|
|
249
249
|
m.forward = m.forward_fuse
|
250
250
|
if isinstance(m, v10Detect):
|
251
251
|
m.fuse() # remove one2many head
|
252
|
+
if isinstance(m, YOLOEDetect) and hasattr(self, "pe"):
|
253
|
+
m.fuse(self.pe.to(next(self.model.parameters()).device))
|
252
254
|
self.info(verbose=verbose)
|
253
255
|
|
254
256
|
return self
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
-
from typing import Any, List, Tuple
|
3
|
+
from typing import Any, Dict, List, Tuple
|
4
4
|
|
5
5
|
import numpy as np
|
6
6
|
|
@@ -26,6 +26,7 @@ class RegionCounter(BaseSolution):
|
|
26
26
|
Methods:
|
27
27
|
add_region: Add a new counting region with specified attributes.
|
28
28
|
process: Process video frames to count objects in each region.
|
29
|
+
initialize_regions: Initialize zones to count the objects in each one. Zones could be multiple as well.
|
29
30
|
|
30
31
|
Examples:
|
31
32
|
Initialize a RegionCounter and add a counting region
|
@@ -42,12 +43,12 @@ class RegionCounter(BaseSolution):
|
|
42
43
|
"name": "Default Region",
|
43
44
|
"polygon": None,
|
44
45
|
"counts": 0,
|
45
|
-
"dragging": False,
|
46
46
|
"region_color": (255, 255, 255),
|
47
47
|
"text_color": (0, 0, 0),
|
48
48
|
}
|
49
49
|
self.region_counts = {}
|
50
50
|
self.counting_regions = []
|
51
|
+
self.initialize_regions()
|
51
52
|
|
52
53
|
def add_region(
|
53
54
|
self,
|
@@ -55,7 +56,7 @@ class RegionCounter(BaseSolution):
|
|
55
56
|
polygon_points: List[Tuple],
|
56
57
|
region_color: Tuple[int, int, int],
|
57
58
|
text_color: Tuple[int, int, int],
|
58
|
-
) ->
|
59
|
+
) -> Dict[str, Any]:
|
59
60
|
"""
|
60
61
|
Add a new region to the counting list based on the provided template with specific attributes.
|
61
62
|
|
@@ -64,6 +65,9 @@ class RegionCounter(BaseSolution):
|
|
64
65
|
polygon_points (List[Tuple]): List of (x, y) coordinates defining the region's polygon.
|
65
66
|
region_color (Tuple[int, int, int]): BGR color for region visualization.
|
66
67
|
text_color (Tuple[int, int, int]): BGR color for the text within the region.
|
68
|
+
|
69
|
+
Returns:
|
70
|
+
(Dict[str, any]): Returns a dictionary including the region information i.e. name, region_color etc.
|
67
71
|
"""
|
68
72
|
region = self.region_template.copy()
|
69
73
|
region.update(
|
@@ -75,6 +79,17 @@ class RegionCounter(BaseSolution):
|
|
75
79
|
}
|
76
80
|
)
|
77
81
|
self.counting_regions.append(region)
|
82
|
+
return region
|
83
|
+
|
84
|
+
def initialize_regions(self):
|
85
|
+
"""Initialize regions only once."""
|
86
|
+
if self.region is None:
|
87
|
+
self.initialize_region()
|
88
|
+
if not isinstance(self.region, dict): # Ensure self.region is initialized and structured as a dictionary
|
89
|
+
self.region = {"Region#01": self.region}
|
90
|
+
for i, (name, pts) in enumerate(self.region.items()):
|
91
|
+
region = self.add_region(name, pts, colors(i, True), (255, 255, 255))
|
92
|
+
region["prepared_polygon"] = self.prep(region["polygon"])
|
78
93
|
|
79
94
|
def process(self, im0: np.ndarray) -> SolutionResults:
|
80
95
|
"""
|
@@ -90,39 +105,21 @@ class RegionCounter(BaseSolution):
|
|
90
105
|
self.extract_tracks(im0)
|
91
106
|
annotator = SolutionAnnotator(im0, line_width=self.line_width)
|
92
107
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
annotator.draw_region(reg_pts, color, self.line_width * 2)
|
101
|
-
self.add_region(region_name, reg_pts, color, annotator.get_txt_color())
|
102
|
-
|
103
|
-
# Prepare regions for containment check (only process valid ones)
|
104
|
-
for region in self.counting_regions:
|
105
|
-
if "prepared_polygon" not in region:
|
106
|
-
region["prepared_polygon"] = self.prep(region["polygon"])
|
107
|
-
|
108
|
-
# Convert bounding boxes to NumPy array for center points
|
109
|
-
boxes_np = np.array([((box[0] + box[2]) / 2, (box[1] + box[3]) / 2) for box in self.boxes], dtype=np.float32)
|
110
|
-
points = [self.Point(pt) for pt in boxes_np] # Convert centers to Point objects
|
111
|
-
|
112
|
-
# Process bounding boxes & check containment
|
113
|
-
if points:
|
114
|
-
for point, cls, track_id, box, conf in zip(points, self.clss, self.track_ids, self.boxes, self.confs):
|
115
|
-
annotator.box_label(box, label=self.adjust_box_label(cls, conf, track_id), color=colors(track_id, True))
|
116
|
-
|
117
|
-
for region in self.counting_regions:
|
118
|
-
if region["prepared_polygon"].contains(point):
|
119
|
-
region["counts"] += 1
|
120
|
-
self.region_counts[region["name"]] = region["counts"]
|
108
|
+
for box, cls, track_id, conf in zip(self.boxes, self.clss, self.track_ids, self.confs):
|
109
|
+
annotator.box_label(box, label=self.adjust_box_label(cls, conf, track_id), color=colors(track_id, True))
|
110
|
+
center = self.Point(((box[0] + box[2]) / 2, (box[1] + box[3]) / 2))
|
111
|
+
for region in self.counting_regions:
|
112
|
+
if region["prepared_polygon"].contains(center):
|
113
|
+
region["counts"] += 1
|
114
|
+
self.region_counts[region["name"]] = region["counts"]
|
121
115
|
|
122
116
|
# Display region counts
|
123
117
|
for region in self.counting_regions:
|
118
|
+
x1, y1, x2, y2 = map(int, region["polygon"].bounds)
|
119
|
+
pts = [(x1, y1), (x2, y1), (x2, y2), (x1, y2)]
|
120
|
+
annotator.draw_region(pts, region["region_color"], self.line_width * 2)
|
124
121
|
annotator.text_label(
|
125
|
-
|
122
|
+
[x1, y1, x2, y2],
|
126
123
|
label=str(region["counts"]),
|
127
124
|
color=region["region_color"],
|
128
125
|
txt_color=region["text_color"],
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ultralytics
|
3
|
-
Version: 8.3.
|
3
|
+
Version: 8.3.163
|
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>
|
@@ -7,7 +7,7 @@ tests/test_exports.py,sha256=HmMKOTCia9ZDC0VYc_EPmvBTM5LM5eeI1NF_pKjLpd8,9677
|
|
7
7
|
tests/test_integrations.py,sha256=kl_AKmE_Qs1GB0_91iVwbzNxofm_hFTt0zzU6JF-pg4,6323
|
8
8
|
tests/test_python.py,sha256=JJu-69IfuUf1dLK7Ko9elyPONiQ1yu7yhapMVIAt_KI,27907
|
9
9
|
tests/test_solutions.py,sha256=tuf6n_fsI8KvSdJrnc-cqP2qYdiYqCWuVrx0z9dOz3Q,13213
|
10
|
-
ultralytics/__init__.py,sha256=
|
10
|
+
ultralytics/__init__.py,sha256=6O34X8CQb6O0LdQxuAb1p_K16CimZHrdPN1T75KtT8A,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=VIpPHImhjb0XLJquGZrG_LBGZchtOtBSXR7HYTYV2GU,39602
|
@@ -113,15 +113,15 @@ ultralytics/data/dataset.py,sha256=0VjzciGleGGF_XN5fEnS3c5UT0r533HMmQ9DfEQ_lA4,3
|
|
113
113
|
ultralytics/data/loaders.py,sha256=kTGO1P-HntpQk078i1ASyXYckDx9Z7Pe7o1YbePcjC4,31657
|
114
114
|
ultralytics/data/split.py,sha256=F6O73bAbESj70FQZzqkydXQeXgPXGHGiC06b5MkLHjQ,5109
|
115
115
|
ultralytics/data/split_dota.py,sha256=rr-lLpTUVaFZMggV_fUYZdFVIJk_zbbSOpgB_Qp50_M,12893
|
116
|
-
ultralytics/data/utils.py,sha256=
|
116
|
+
ultralytics/data/utils.py,sha256=KAWSi0pqzCbG1QL9lblgeEyz12QoLtTx-f-LNmJ49Xw,36711
|
117
117
|
ultralytics/data/scripts/download_weights.sh,sha256=0y8XtZxOru7dVThXDFUXLHBuICgOIqZNUwpyL4Rh6lg,595
|
118
118
|
ultralytics/data/scripts/get_coco.sh,sha256=UuJpJeo3qQpTHVINeOpmP0NYmg8PhEFE3A8J3jKrnPw,1768
|
119
119
|
ultralytics/data/scripts/get_coco128.sh,sha256=qmRQl_hOKrsdHrTrnyQuFIH01oDz3lfaz138OgGfLt8,650
|
120
120
|
ultralytics/data/scripts/get_imagenet.sh,sha256=hr42H16bM47iT27rgS7MpEo-GeOZAYUQXgr0B2cwn48,1705
|
121
121
|
ultralytics/engine/__init__.py,sha256=lm6MckFYCPTbqIoX7w0s_daxdjNeBeKW6DXppv1-QUM,70
|
122
|
-
ultralytics/engine/exporter.py,sha256=
|
122
|
+
ultralytics/engine/exporter.py,sha256=6ScFs_fTm9kHuEO4C0DA4JXhxFUzW0mG9qqDSeY2JkY,73261
|
123
123
|
ultralytics/engine/model.py,sha256=FmLwiKuItVNgoyXhAvesUnD3UeHBzCVzGHDrqB8J4ms,53453
|
124
|
-
ultralytics/engine/predictor.py,sha256=
|
124
|
+
ultralytics/engine/predictor.py,sha256=xxl1kdAzKrN8Y_5MQ5f92uFPeeRq1mYOl6hNlzpPjy8,22520
|
125
125
|
ultralytics/engine/results.py,sha256=rLQlttkgPudiV0u0d6Xy5hKKr1x3SJL1zrXA5W5vw7Y,71999
|
126
126
|
ultralytics/engine/trainer.py,sha256=28FeqASvQRxCaK96SXDM-BfPJjqy5KNiWhf8v6GXTug,39785
|
127
127
|
ultralytics/engine/tuner.py,sha256=sfQ8_yzgLNcGlKyz9b2vAzyggGZXiQzdZ5tKstyqjHM,12825
|
@@ -195,7 +195,7 @@ ultralytics/models/yolo/yoloe/train_seg.py,sha256=aCV7M8oQOvODFnU4piZdJh3tIrBJYA
|
|
195
195
|
ultralytics/models/yolo/yoloe/val.py,sha256=yebPkxwKKt__cY05Zbh1YXg4_BKzzpcDc3Cv3FJ5SAA,9769
|
196
196
|
ultralytics/nn/__init__.py,sha256=rjociYD9lo_K-d-1s6TbdWklPLjTcEHk7OIlRDJstIE,615
|
197
197
|
ultralytics/nn/autobackend.py,sha256=n-2ADzX3Y2MRE8nHFeVvFCJFJP9rCbkkNbcufPZ24dE,41532
|
198
|
-
ultralytics/nn/tasks.py,sha256=
|
198
|
+
ultralytics/nn/tasks.py,sha256=jRUjYn1xz_LEa_zx6Upb0UpXvy0Bca1o5HEc7FCRgwM,72653
|
199
199
|
ultralytics/nn/text_model.py,sha256=cYwD-0el4VeToDBP4iPFOQGqyEQatJOBHrVyONL3K_s,15282
|
200
200
|
ultralytics/nn/modules/__init__.py,sha256=2nY0X69Z5DD5SWt6v3CUTZa5gXSzC9TQr3VTVqhyGho,3158
|
201
201
|
ultralytics/nn/modules/activation.py,sha256=75JcIMH2Cu9GTC2Uf55r_5YLpxcrXQDaVoeGQ0hlUAU,2233
|
@@ -216,7 +216,7 @@ ultralytics/solutions/object_counter.py,sha256=ccKuchrVkNE8AD4EvArtl6LCVf442jTOy
|
|
216
216
|
ultralytics/solutions/object_cropper.py,sha256=mS3iT_CgqfqG9ldM_AM5ptq5bfYFyTycPQY5DxxMlSA,3525
|
217
217
|
ultralytics/solutions/parking_management.py,sha256=IfPUn15aelxz6YZNo9WYkVEl5IOVSw8VD0OrpKtExPE,13613
|
218
218
|
ultralytics/solutions/queue_management.py,sha256=u0VFzRqa0OxIWY7xXItsXEm073CzkQGFhhXG-6VK3SI,4393
|
219
|
-
ultralytics/solutions/region_counter.py,sha256=
|
219
|
+
ultralytics/solutions/region_counter.py,sha256=nmtCoq1sFIU2Hx4gKImYNF7Yf5YpADHwujxxQGDvf1s,5916
|
220
220
|
ultralytics/solutions/security_alarm.py,sha256=U6FTbg3cthKLfWeLunsFhOJvB6GGmwYDDxZ3K0GCx-Q,6351
|
221
221
|
ultralytics/solutions/similarity_search.py,sha256=H9MPf8F5AvVfmb9hnng0FrIOTbLU_I-CkVHGpC81CE0,9496
|
222
222
|
ultralytics/solutions/solutions.py,sha256=KtoSUSxM4s-Ti5EAzT21pItuv70qlIOH6ymJP95Gl-E,37318
|
@@ -265,9 +265,9 @@ ultralytics/utils/callbacks/neptune.py,sha256=j8pecmlcsM8FGzLKWoBw5xUsi5t8E5HuxY
|
|
265
265
|
ultralytics/utils/callbacks/raytune.py,sha256=S6Bq16oQDQ8BQgnZzA0zJHGN_BBr8iAM_WtGoLiEcwg,1283
|
266
266
|
ultralytics/utils/callbacks/tensorboard.py,sha256=MDPBW7aDes-66OE6YqKXXvqA_EocjzEMHWGM-8z9vUQ,5281
|
267
267
|
ultralytics/utils/callbacks/wb.py,sha256=Tm_-aRr2CN32MJkY9tylpMBJkb007-MSRNSQ7rDJ5QU,7521
|
268
|
-
ultralytics-8.3.
|
269
|
-
ultralytics-8.3.
|
270
|
-
ultralytics-8.3.
|
271
|
-
ultralytics-8.3.
|
272
|
-
ultralytics-8.3.
|
273
|
-
ultralytics-8.3.
|
268
|
+
ultralytics-8.3.163.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
269
|
+
ultralytics-8.3.163.dist-info/METADATA,sha256=qDmztrvTzggmS225ow6FcaQwpEK2o1tooVtx_QRtBks,37576
|
270
|
+
ultralytics-8.3.163.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
271
|
+
ultralytics-8.3.163.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
|
272
|
+
ultralytics-8.3.163.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
|
273
|
+
ultralytics-8.3.163.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|