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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- __version__ = "8.3.162"
3
+ __version__ = "8.3.163"
4
4
 
5
5
  import os
6
6
 
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
- assert points.max() <= 1, f"non-normalized or out of bounds coordinates {points[points > 1]}"
218
- assert lb.min() >= 0, f"negative label values {lb[lb < 0]}"
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:
@@ -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.56", "onnxruntime" + ("-gpu" if torch.cuda.is_available() else "")]
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.56",
955
+ "onnxslim>=0.1.59",
956
956
  "onnxruntime-gpu" if cuda else "onnxruntime",
957
957
  "protobuf>=5",
958
958
  ),
@@ -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(str(self.save_dir / p.name), frame)
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: str = "", frame: int = 0):
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 (str): Path to save the results.
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.split('.', 1)[0]}_frames/"
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(Path(save_path).with_suffix(".jpg")), im) # save to JPG for best support
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
- ) -> None:
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
- # Ensure self.region is initialized and structured as a dictionary
94
- if not isinstance(self.region, dict):
95
- self.region = {"Region#01": self.region or self.initialize_region()}
96
-
97
- # Draw only valid regions
98
- for idx, (region_name, reg_pts) in enumerate(self.region.items(), start=1):
99
- color = colors(idx, True)
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
- region["polygon"].bounds,
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.162
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=mghg3KP-MAGasMWYrfuWs4NQuSHe4GXzeqmSc_T9E0k,730
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=fJqVJkjaub-xT0cB1o40Hl1WIH1ljKINT0SJaJyZse4,36637
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=oz6jsQbYapyc29Bw1DTQuDbk_RnOKphlVeLrCwQehs4,73261
122
+ ultralytics/engine/exporter.py,sha256=6ScFs_fTm9kHuEO4C0DA4JXhxFUzW0mG9qqDSeY2JkY,73261
123
123
  ultralytics/engine/model.py,sha256=FmLwiKuItVNgoyXhAvesUnD3UeHBzCVzGHDrqB8J4ms,53453
124
- ultralytics/engine/predictor.py,sha256=88zrgZP91ehwdeGl8BM_cQ_caeuwKIPDy3OzxcRBjTU,22474
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=vw_TNacAv-RN24rusFzKuYL6qRBD7cve8EpB7gOlU_8,72505
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=j6f5VAaE1JWGdWOecZpWMFp6yF1GdCnHjftN6CRybjQ,5967
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.162.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
269
- ultralytics-8.3.162.dist-info/METADATA,sha256=FVyaNE5gD0l3PqFA1ZmpXu1W_AnhrGttVey3N0zCH0w,37576
270
- ultralytics-8.3.162.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
271
- ultralytics-8.3.162.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
272
- ultralytics-8.3.162.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
273
- ultralytics-8.3.162.dist-info/RECORD,,
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,,