ultralytics 8.3.6__py3-none-any.whl → 8.3.8__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.

Potentially problematic release.


This version of ultralytics might be problematic. Click here for more details.

tests/test_solutions.py CHANGED
@@ -22,7 +22,7 @@ def test_major_solutions():
22
22
  counter = solutions.ObjectCounter(region=region_points, model="yolo11n.pt", show=False)
23
23
  heatmap = solutions.Heatmap(colormap=cv2.COLORMAP_PARULA, model="yolo11n.pt", show=False)
24
24
  speed = solutions.SpeedEstimator(reg_pts=region_points, names=names, view_img=False)
25
- queue = solutions.QueueManager(names=names, reg_pts=region_points, view_img=False)
25
+ queue = solutions.QueueManager(region=region_points, model="yolo11n.pt", show=False)
26
26
  while cap.isOpened():
27
27
  success, im0 = cap.read()
28
28
  if not success:
@@ -32,7 +32,7 @@ def test_major_solutions():
32
32
  _ = counter.count(original_im0.copy())
33
33
  _ = heatmap.generate_heatmap(original_im0.copy())
34
34
  _ = speed.estimate_speed(original_im0.copy(), tracks)
35
- _ = queue.process_queue(original_im0.copy(), tracks)
35
+ _ = queue.process_queue(original_im0.copy())
36
36
  cap.release()
37
37
  cv2.destroyAllWindows()
38
38
 
ultralytics/__init__.py CHANGED
@@ -1,11 +1,12 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- __version__ = "8.3.6"
3
+ __version__ = "8.3.8"
4
4
 
5
5
  import os
6
6
 
7
- # Set ENV Variables (place before imports)
8
- os.environ["OMP_NUM_THREADS"] = "1" # reduce CPU utilization during training
7
+ # Set ENV variables (place before imports)
8
+ if not os.environ.get("OMP_NUM_THREADS"):
9
+ os.environ["OMP_NUM_THREADS"] = "1" # default for reduced CPU utilization during training
9
10
 
10
11
  from ultralytics.data.explorer.explorer import Explorer
11
12
  from ultralytics.models import NAS, RTDETR, SAM, YOLO, FastSAM, YOLOWorld
@@ -669,9 +669,10 @@ def smart_value(v):
669
669
  elif v_lower == "false":
670
670
  return False
671
671
  else:
672
- with contextlib.suppress(Exception):
672
+ try:
673
673
  return eval(v)
674
- return v
674
+ except: # noqa E722
675
+ return v
675
676
 
676
677
 
677
678
  def entrypoint(debug=""):
@@ -1,13 +1,18 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
3
  import json
4
+ import random
5
+ import shutil
4
6
  from collections import defaultdict
7
+ from concurrent.futures import ThreadPoolExecutor, as_completed
5
8
  from pathlib import Path
6
9
 
7
10
  import cv2
8
11
  import numpy as np
12
+ from PIL import Image
9
13
 
10
- from ultralytics.utils import LOGGER, TQDM
14
+ from ultralytics.utils import DATASETS_DIR, LOGGER, NUM_THREADS, TQDM
15
+ from ultralytics.utils.downloads import download
11
16
  from ultralytics.utils.files import increment_path
12
17
 
13
18
 
@@ -588,15 +593,13 @@ def yolo_bbox2segment(im_dir, save_dir=None, sam_model="sam_b.pt"):
588
593
 
589
594
  - im_dir
590
595
  ├─ 001.jpg
591
- ├─ ..
596
+ ├─ ...
592
597
  └─ NNN.jpg
593
598
  - labels
594
599
  ├─ 001.txt
595
- ├─ ..
600
+ ├─ ...
596
601
  └─ NNN.txt
597
602
  """
598
- from tqdm import tqdm
599
-
600
603
  from ultralytics import SAM
601
604
  from ultralytics.data import YOLODataset
602
605
  from ultralytics.utils import LOGGER
@@ -610,7 +613,7 @@ def yolo_bbox2segment(im_dir, save_dir=None, sam_model="sam_b.pt"):
610
613
 
611
614
  LOGGER.info("Detection labels detected, generating segment labels by SAM model!")
612
615
  sam_model = SAM(sam_model)
613
- for label in tqdm(dataset.labels, total=len(dataset.labels), desc="Generating segment labels"):
616
+ for label in TQDM(dataset.labels, total=len(dataset.labels), desc="Generating segment labels"):
614
617
  h, w = label["shape"]
615
618
  boxes = label["bboxes"]
616
619
  if len(boxes) == 0: # skip empty labels
@@ -635,3 +638,61 @@ def yolo_bbox2segment(im_dir, save_dir=None, sam_model="sam_b.pt"):
635
638
  with open(txt_file, "a") as f:
636
639
  f.writelines(text + "\n" for text in texts)
637
640
  LOGGER.info(f"Generated segment labels saved in {save_dir}")
641
+
642
+
643
+ def create_synthetic_coco_dataset():
644
+ """
645
+ Creates a synthetic COCO dataset with random images based on filenames from label lists.
646
+
647
+ This function downloads COCO labels, reads image filenames from label list files,
648
+ creates synthetic images for train2017 and val2017 subsets, and organizes
649
+ them in the COCO dataset structure. It uses multithreading to generate images efficiently.
650
+
651
+ Examples:
652
+ >>> from ultralytics.data.converter import create_synthetic_coco_dataset
653
+ >>> create_synthetic_coco_dataset()
654
+
655
+ Notes:
656
+ - Requires internet connection to download label files.
657
+ - Generates random RGB images of varying sizes (480x480 to 640x640 pixels).
658
+ - Existing test2017 directory is removed as it's not needed.
659
+ - Reads image filenames from train2017.txt and val2017.txt files.
660
+ """
661
+
662
+ def create_synthetic_image(image_file):
663
+ """Generates synthetic images with random sizes and colors for dataset augmentation or testing purposes."""
664
+ if not image_file.exists():
665
+ size = (random.randint(480, 640), random.randint(480, 640))
666
+ Image.new(
667
+ "RGB",
668
+ size=size,
669
+ color=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),
670
+ ).save(image_file)
671
+
672
+ # Download labels
673
+ dir = DATASETS_DIR / "coco"
674
+ url = "https://github.com/ultralytics/assets/releases/download/v0.0.0/"
675
+ label_zip = "coco2017labels-segments.zip"
676
+ download([url + label_zip], dir=dir.parent)
677
+
678
+ # Create synthetic images
679
+ shutil.rmtree(dir / "labels" / "test2017", ignore_errors=True) # Remove test2017 directory as not needed
680
+ with ThreadPoolExecutor(max_workers=NUM_THREADS) as executor:
681
+ for subset in ["train2017", "val2017"]:
682
+ subset_dir = dir / "images" / subset
683
+ subset_dir.mkdir(parents=True, exist_ok=True)
684
+
685
+ # Read image filenames from label list file
686
+ label_list_file = dir / f"{subset}.txt"
687
+ if label_list_file.exists():
688
+ with open(label_list_file) as f:
689
+ image_files = [dir / line.strip() for line in f]
690
+
691
+ # Submit all tasks
692
+ futures = [executor.submit(create_synthetic_image, image_file) for image_file in image_files]
693
+ for _ in TQDM(as_completed(futures), total=len(futures), desc=f"Generating images for {subset}"):
694
+ pass # The actual work is done in the background
695
+ else:
696
+ print(f"Warning: Labels file {label_list_file} does not exist. Skipping image creation for {subset}.")
697
+
698
+ print("Synthetic COCO dataset created successfully.")
@@ -1,6 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- import contextlib
4
3
  import json
5
4
  from collections import defaultdict
6
5
  from itertools import repeat
@@ -483,7 +482,7 @@ class ClassificationDataset:
483
482
  desc = f"{self.prefix}Scanning {self.root}..."
484
483
  path = Path(self.root).with_suffix(".cache") # *.cache file path
485
484
 
486
- with contextlib.suppress(FileNotFoundError, AssertionError, AttributeError):
485
+ try:
487
486
  cache = load_dataset_cache_file(path) # attempt to load a *.cache file
488
487
  assert cache["version"] == DATASET_CACHE_VERSION # matches current version
489
488
  assert cache["hash"] == get_hash([x[0] for x in self.samples]) # identical hash
@@ -495,24 +494,25 @@ class ClassificationDataset:
495
494
  LOGGER.info("\n".join(cache["msgs"])) # display warnings
496
495
  return samples
497
496
 
498
- # Run scan if *.cache retrieval failed
499
- nf, nc, msgs, samples, x = 0, 0, [], [], {}
500
- with ThreadPool(NUM_THREADS) as pool:
501
- results = pool.imap(func=verify_image, iterable=zip(self.samples, repeat(self.prefix)))
502
- pbar = TQDM(results, desc=desc, total=len(self.samples))
503
- for sample, nf_f, nc_f, msg in pbar:
504
- if nf_f:
505
- samples.append(sample)
506
- if msg:
507
- msgs.append(msg)
508
- nf += nf_f
509
- nc += nc_f
510
- pbar.desc = f"{desc} {nf} images, {nc} corrupt"
511
- pbar.close()
512
- if msgs:
513
- LOGGER.info("\n".join(msgs))
514
- x["hash"] = get_hash([x[0] for x in self.samples])
515
- x["results"] = nf, nc, len(samples), samples
516
- x["msgs"] = msgs # warnings
517
- save_dataset_cache_file(self.prefix, path, x, DATASET_CACHE_VERSION)
518
- return samples
497
+ except (FileNotFoundError, AssertionError, AttributeError):
498
+ # Run scan if *.cache retrieval failed
499
+ nf, nc, msgs, samples, x = 0, 0, [], [], {}
500
+ with ThreadPool(NUM_THREADS) as pool:
501
+ results = pool.imap(func=verify_image, iterable=zip(self.samples, repeat(self.prefix)))
502
+ pbar = TQDM(results, desc=desc, total=len(self.samples))
503
+ for sample, nf_f, nc_f, msg in pbar:
504
+ if nf_f:
505
+ samples.append(sample)
506
+ if msg:
507
+ msgs.append(msg)
508
+ nf += nf_f
509
+ nc += nc_f
510
+ pbar.desc = f"{desc} {nf} images, {nc} corrupt"
511
+ pbar.close()
512
+ if msgs:
513
+ LOGGER.info("\n".join(msgs))
514
+ x["hash"] = get_hash([x[0] for x in self.samples])
515
+ x["results"] = nf, nc, len(samples), samples
516
+ x["msgs"] = msgs # warnings
517
+ save_dataset_cache_file(self.prefix, path, x, DATASET_CACHE_VERSION)
518
+ return samples
@@ -39,24 +39,11 @@ def init_explorer_form(data=None, model=None):
39
39
  else:
40
40
  ds = [data]
41
41
 
42
+ prefixes = ["yolov8", "yolo11"]
43
+ sizes = ["n", "s", "m", "l", "x"]
44
+ tasks = ["", "-seg", "-pose"]
42
45
  if model is None:
43
- models = [
44
- "yolov8n.pt",
45
- "yolov8s.pt",
46
- "yolov8m.pt",
47
- "yolov8l.pt",
48
- "yolov8x.pt",
49
- "yolov8n-seg.pt",
50
- "yolov8s-seg.pt",
51
- "yolov8m-seg.pt",
52
- "yolov8l-seg.pt",
53
- "yolov8x-seg.pt",
54
- "yolov8n-pose.pt",
55
- "yolov8s-pose.pt",
56
- "yolov8m-pose.pt",
57
- "yolov8l-pose.pt",
58
- "yolov8x-pose.pt",
59
- ]
46
+ models = [f"{p}{s}{t}" for p in prefixes for s in sizes for t in tasks]
60
47
  else:
61
48
  models = [model]
62
49
 
ultralytics/data/utils.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- import contextlib
4
3
  import hashlib
5
4
  import json
6
5
  import os
@@ -60,12 +59,14 @@ def exif_size(img: Image.Image):
60
59
  """Returns exif-corrected PIL size."""
61
60
  s = img.size # (width, height)
62
61
  if img.format == "JPEG": # only support JPEG images
63
- with contextlib.suppress(Exception):
62
+ try:
64
63
  exif = img.getexif()
65
64
  if exif:
66
65
  rotation = exif.get(274, None) # the EXIF key for the orientation tag is 274
67
66
  if rotation in {6, 8}: # rotation 270 or 90
68
67
  s = s[1], s[0]
68
+ except: # noqa E722
69
+ pass
69
70
  return s
70
71
 
71
72
 
@@ -543,7 +543,7 @@ class Model(nn.Module):
543
543
  prompts = args.pop("prompts", None) # for SAM-type models
544
544
 
545
545
  if not self.predictor:
546
- self.predictor = predictor or self._smart_load("predictor")(overrides=args, _callbacks=self.callbacks)
546
+ self.predictor = (predictor or self._smart_load("predictor"))(overrides=args, _callbacks=self.callbacks)
547
547
  self.predictor.setup_model(model=self.model, verbose=is_cli)
548
548
  else: # only update args if predictor is already setup
549
549
  self.predictor.args = get_cfg(self.predictor.args, args)
@@ -75,7 +75,7 @@ class DetectionValidator(BaseValidator):
75
75
  ) # is COCO
76
76
  self.is_lvis = isinstance(val, str) and "lvis" in val and not self.is_coco # is LVIS
77
77
  self.class_map = converter.coco80_to_coco91_class() if self.is_coco else list(range(len(model.names)))
78
- self.args.save_json |= (self.is_coco or self.is_lvis) and not self.training # run on final val if training COCO
78
+ self.args.save_json |= self.args.val and (self.is_coco or self.is_lvis) and not self.training # run final val
79
79
  self.names = model.names
80
80
  self.nc = len(model.names)
81
81
  self.metrics.names = self.names
@@ -1,7 +1,6 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
3
  import ast
4
- import contextlib
5
4
  import json
6
5
  import platform
7
6
  import zipfile
@@ -45,8 +44,10 @@ def check_class_names(names):
45
44
  def default_class_names(data=None):
46
45
  """Applies default class names to an input YAML file or returns numerical class names."""
47
46
  if data:
48
- with contextlib.suppress(Exception):
47
+ try:
49
48
  return yaml_load(check_yaml(data))["names"]
49
+ except: # noqa E722
50
+ pass
50
51
  return {i: f"class{i}" for i in range(999)} # return default if above errors
51
52
 
52
53
 
@@ -321,8 +322,10 @@ class AutoBackend(nn.Module):
321
322
  with open(w, "rb") as f:
322
323
  gd.ParseFromString(f.read())
323
324
  frozen_func = wrap_frozen_graph(gd, inputs="x:0", outputs=gd_outputs(gd))
324
- with contextlib.suppress(StopIteration): # find metadata in SavedModel alongside GraphDef
325
+ try: # find metadata in SavedModel alongside GraphDef
325
326
  metadata = next(Path(w).resolve().parent.rglob(f"{Path(w).stem}_saved_model*/metadata.yaml"))
327
+ except StopIteration:
328
+ pass
326
329
 
327
330
  # TFLite or TFLite Edge TPU
328
331
  elif tflite or edgetpu: # https://www.tensorflow.org/lite/guide/python#install_tensorflow_lite_for_python
@@ -345,10 +348,12 @@ class AutoBackend(nn.Module):
345
348
  input_details = interpreter.get_input_details() # inputs
346
349
  output_details = interpreter.get_output_details() # outputs
347
350
  # Load metadata
348
- with contextlib.suppress(zipfile.BadZipFile):
351
+ try:
349
352
  with zipfile.ZipFile(w, "r") as model:
350
353
  meta_file = model.namelist()[0]
351
354
  metadata = ast.literal_eval(model.read(meta_file).decode("utf-8"))
355
+ except zipfile.BadZipFile:
356
+ pass
352
357
 
353
358
  # TF.js
354
359
  elif tfjs:
ultralytics/nn/tasks.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import contextlib
4
4
  import pickle
5
+ import re
5
6
  import types
6
7
  from copy import deepcopy
7
8
  from pathlib import Path
@@ -958,8 +959,10 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
958
959
  m = getattr(torch.nn, m[3:]) if "nn." in m else globals()[m] # get module
959
960
  for j, a in enumerate(args):
960
961
  if isinstance(a, str):
961
- with contextlib.suppress(ValueError):
962
+ try:
962
963
  args[j] = locals()[a] if a in locals() else ast.literal_eval(a)
964
+ except ValueError:
965
+ pass
963
966
 
964
967
  n = n_ = max(round(n * depth), 1) if n > 1 else n # depth gain
965
968
  if m in {
@@ -1072,8 +1075,6 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
1072
1075
 
1073
1076
  def yaml_model_load(path):
1074
1077
  """Load a YOLOv8 model from a YAML file."""
1075
- import re
1076
-
1077
1078
  path = Path(path)
1078
1079
  if path.stem in (f"yolov{d}{x}6" for x in "nsmlx" for d in (5, 8)):
1079
1080
  new_stem = re.sub(r"(\d+)([nslmx])6(.+)?$", r"\1\2-p6\3", path.stem)
@@ -1100,11 +1101,10 @@ def guess_model_scale(model_path):
1100
1101
  Returns:
1101
1102
  (str): The size character of the model's scale, which can be n, s, m, l, or x.
1102
1103
  """
1103
- with contextlib.suppress(AttributeError):
1104
- import re
1105
-
1104
+ try:
1106
1105
  return re.search(r"yolo[v]?\d+([nslmx])", Path(model_path).stem).group(1) # n, s, m, l, or x
1107
- return ""
1106
+ except AttributeError:
1107
+ return ""
1108
1108
 
1109
1109
 
1110
1110
  def guess_model_task(model):
@@ -1137,17 +1137,23 @@ def guess_model_task(model):
1137
1137
 
1138
1138
  # Guess from model cfg
1139
1139
  if isinstance(model, dict):
1140
- with contextlib.suppress(Exception):
1140
+ try:
1141
1141
  return cfg2task(model)
1142
+ except: # noqa E722
1143
+ pass
1142
1144
 
1143
1145
  # Guess from PyTorch model
1144
1146
  if isinstance(model, nn.Module): # PyTorch model
1145
1147
  for x in "model.args", "model.model.args", "model.model.model.args":
1146
- with contextlib.suppress(Exception):
1148
+ try:
1147
1149
  return eval(x)["task"]
1150
+ except: # noqa E722
1151
+ pass
1148
1152
  for x in "model.yaml", "model.model.yaml", "model.model.model.yaml":
1149
- with contextlib.suppress(Exception):
1153
+ try:
1150
1154
  return cfg2task(eval(x))
1155
+ except: # noqa E722
1156
+ pass
1151
1157
 
1152
1158
  for m in model.modules():
1153
1159
  if isinstance(m, Segment):
@@ -116,7 +116,7 @@ class ObjectCounter(BaseSolution):
116
116
  self.store_tracking_history(track_id, box) # Store track history
117
117
  self.store_classwise_counts(cls) # store classwise counts in dict
118
118
 
119
- # Draw centroid of objects
119
+ # Draw tracks of objects
120
120
  self.annotator.draw_centroid_and_tracks(
121
121
  self.track_line, color=colors(int(track_id), True), track_thickness=self.line_width
122
122
  )
@@ -1,127 +1,64 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- from collections import defaultdict
3
+ from shapely.geometry import Point
4
4
 
5
- import cv2
6
-
7
- from ultralytics.utils.checks import check_imshow, check_requirements
5
+ from ultralytics.solutions.solutions import BaseSolution # Import a parent class
8
6
  from ultralytics.utils.plotting import Annotator, colors
9
7
 
10
- check_requirements("shapely>=2.0.0")
11
-
12
- from shapely.geometry import Point, Polygon
13
-
14
8
 
15
- class QueueManager:
9
+ class QueueManager(BaseSolution):
16
10
  """A class to manage the queue in a real-time video stream based on object tracks."""
17
11
 
18
- def __init__(
19
- self,
20
- names,
21
- reg_pts=None,
22
- line_thickness=2,
23
- view_img=False,
24
- draw_tracks=False,
25
- ):
12
+ def __init__(self, **kwargs):
13
+ """Initializes the QueueManager with specified parameters for tracking and counting objects."""
14
+ super().__init__(**kwargs)
15
+ self.initialize_region()
16
+ self.counts = 0 # Queue counts Information
17
+ self.rect_color = (255, 255, 255) # Rectangle color
18
+ self.region_length = len(self.region) # Store region length for further usage
19
+
20
+ def process_queue(self, im0):
26
21
  """
27
- Initializes the QueueManager with specified parameters for tracking and counting objects.
22
+ Main function to start the queue management process.
28
23
 
29
24
  Args:
30
- names (dict): A dictionary mapping class IDs to class names.
31
- reg_pts (list of tuples, optional): Points defining the counting region polygon. Defaults to a predefined
32
- rectangle.
33
- line_thickness (int, optional): Thickness of the annotation lines. Defaults to 2.
34
- view_img (bool, optional): Whether to display the image frames. Defaults to False.
35
- draw_tracks (bool, optional): Whether to draw tracks of the objects. Defaults to False.
25
+ im0 (ndarray): The input image that will be used for processing
26
+ Returns
27
+ im0 (ndarray): The processed image for more usage
36
28
  """
37
- # Region & Line Information
38
- self.reg_pts = reg_pts if reg_pts is not None else [(20, 60), (20, 680), (1120, 680), (1120, 60)]
39
- self.counting_region = (
40
- Polygon(self.reg_pts) if len(self.reg_pts) >= 3 else Polygon([(20, 60), (20, 680), (1120, 680), (1120, 60)])
41
- )
42
-
43
- # annotation Information
44
- self.tf = line_thickness
45
- self.view_img = view_img
46
-
47
- self.names = names # Class names
48
-
49
- # Object counting Information
50
- self.counts = 0
51
-
52
- # Tracks info
53
- self.track_history = defaultdict(list)
54
- self.draw_tracks = draw_tracks
55
-
56
- # Check if environment supports imshow
57
- self.env_check = check_imshow(warn=True)
58
-
59
- def extract_and_process_tracks(self, tracks, im0):
60
- """Extracts and processes tracks for queue management in a video stream."""
61
- # Initialize annotator and draw the queue region
62
- annotator = Annotator(im0, self.tf, self.names)
63
29
  self.counts = 0 # Reset counts every frame
64
- if tracks[0].boxes.id is not None:
65
- boxes = tracks[0].boxes.xyxy.cpu()
66
- clss = tracks[0].boxes.cls.cpu().tolist()
67
- track_ids = tracks[0].boxes.id.int().cpu().tolist()
30
+ self.annotator = Annotator(im0, line_width=self.line_width) # Initialize annotator
31
+ self.extract_tracks(im0) # Extract tracks
68
32
 
69
- # Extract tracks
70
- for box, track_id, cls in zip(boxes, track_ids, clss):
71
- # Draw bounding box
72
- annotator.box_label(box, label=self.names[cls], color=colors(int(track_id), True))
33
+ self.annotator.draw_region(
34
+ reg_pts=self.region, color=self.rect_color, thickness=self.line_width * 2
35
+ ) # Draw region
73
36
 
74
- # Update track history
75
- track_line = self.track_history[track_id]
76
- track_line.append((float((box[0] + box[2]) / 2), float((box[1] + box[3]) / 2)))
77
- if len(track_line) > 30:
78
- track_line.pop(0)
37
+ for box, track_id, cls in zip(self.boxes, self.track_ids, self.clss):
38
+ # Draw bounding box and counting region
39
+ self.annotator.box_label(box, label=self.names[cls], color=colors(track_id, True))
40
+ self.store_tracking_history(track_id, box) # Store track history
79
41
 
80
- # Draw track trails if enabled
81
- if self.draw_tracks:
82
- annotator.draw_centroid_and_tracks(
83
- track_line,
84
- color=colors(int(track_id), True),
85
- track_thickness=self.line_thickness,
86
- )
87
-
88
- prev_position = self.track_history[track_id][-2] if len(self.track_history[track_id]) > 1 else None
89
-
90
- # Check if the object is inside the counting region
91
- if len(self.reg_pts) >= 3:
92
- is_inside = self.counting_region.contains(Point(track_line[-1]))
93
- if prev_position is not None and is_inside:
94
- self.counts += 1
95
-
96
- # Display queue counts
97
- label = f"Queue Counts : {str(self.counts)}"
98
- if label is not None:
99
- annotator.queue_counts_display(
100
- label,
101
- points=self.reg_pts,
102
- region_color=(255, 0, 255),
103
- txt_color=(104, 31, 17),
42
+ # Draw tracks of objects
43
+ self.annotator.draw_centroid_and_tracks(
44
+ self.track_line, color=colors(int(track_id), True), track_thickness=self.line_width
104
45
  )
105
46
 
106
- if self.env_check and self.view_img:
107
- annotator.draw_region(reg_pts=self.reg_pts, thickness=self.tf * 2, color=(255, 0, 255))
108
- cv2.imshow("Ultralytics YOLOv8 Queue Manager", im0)
109
- # Close window on 'q' key press
110
- if cv2.waitKey(1) & 0xFF == ord("q"):
111
- return
47
+ # Cache frequently accessed attributes
48
+ track_history = self.track_history.get(track_id, [])
112
49
 
113
- def process_queue(self, im0, tracks):
114
- """
115
- Main function to start the queue management process.
116
-
117
- Args:
118
- im0 (ndarray): Current frame from the video stream.
119
- tracks (list): List of tracks obtained from the object tracking process.
120
- """
121
- self.extract_and_process_tracks(tracks, im0) # Extract and process tracks
122
- return im0
50
+ # store previous position of track and check if the object is inside the counting region
51
+ prev_position = track_history[-2] if len(track_history) > 1 else None
52
+ if self.region_length >= 3 and prev_position and self.r_s.contains(Point(self.track_line[-1])):
53
+ self.counts += 1
123
54
 
55
+ # Display queue counts
56
+ self.annotator.queue_counts_display(
57
+ f"Queue Counts : {str(self.counts)}",
58
+ points=self.region,
59
+ region_color=self.rect_color,
60
+ txt_color=(104, 31, 17),
61
+ )
62
+ self.display_output(im0) # display output with base class function
124
63
 
125
- if __name__ == "__main__":
126
- classes_names = {0: "person", 1: "car"} # example class names
127
- queue_manager = QueueManager(classes_names)
64
+ return im0 # return output image for more usage
@@ -76,9 +76,11 @@ class BaseSolution:
76
76
 
77
77
  def initialize_region(self):
78
78
  """Initialize the counting region and line segment based on config."""
79
- self.region = [(20, 400), (1260, 400)] if self.region is None else self.region
80
- self.r_s = Polygon(self.region) if len(self.region) >= 3 else LineString(self.region)
81
- self.l_s = LineString([(self.region[0][0], self.region[0][1]), (self.region[1][0], self.region[1][1])])
79
+ self.region = [(20, 400), (1080, 404), (1080, 360), (20, 360)] if self.region is None else self.region
80
+ self.r_s = Polygon(self.region) if len(self.region) >= 3 else LineString(self.region) # region segment
81
+ self.l_s = LineString(
82
+ [(self.region[0][0], self.region[0][1]), (self.region[1][0], self.region[1][1])]
83
+ ) # line segment
82
84
 
83
85
  def display_output(self, im0):
84
86
  """
@@ -523,10 +523,11 @@ def read_device_model() -> str:
523
523
  Returns:
524
524
  (str): Model file contents if read successfully or empty string otherwise.
525
525
  """
526
- with contextlib.suppress(Exception):
526
+ try:
527
527
  with open("/proc/device-tree/model") as f:
528
528
  return f.read()
529
- return ""
529
+ except: # noqa E722
530
+ return ""
530
531
 
531
532
 
532
533
  def is_ubuntu() -> bool:
@@ -536,10 +537,11 @@ def is_ubuntu() -> bool:
536
537
  Returns:
537
538
  (bool): True if OS is Ubuntu, False otherwise.
538
539
  """
539
- with contextlib.suppress(FileNotFoundError):
540
+ try:
540
541
  with open("/etc/os-release") as f:
541
542
  return "ID=ubuntu" in f.read()
542
- return False
543
+ except FileNotFoundError:
544
+ return False
543
545
 
544
546
 
545
547
  def is_colab():
@@ -569,11 +571,7 @@ def is_jupyter():
569
571
  Returns:
570
572
  (bool): True if running inside a Jupyter Notebook, False otherwise.
571
573
  """
572
- with contextlib.suppress(Exception):
573
- from IPython import get_ipython
574
-
575
- return get_ipython() is not None
576
- return False
574
+ return "get_ipython" in locals()
577
575
 
578
576
 
579
577
  def is_docker() -> bool:
@@ -583,10 +581,11 @@ def is_docker() -> bool:
583
581
  Returns:
584
582
  (bool): True if the script is running inside a Docker container, False otherwise.
585
583
  """
586
- with contextlib.suppress(Exception):
584
+ try:
587
585
  with open("/proc/self/cgroup") as f:
588
586
  return "docker" in f.read()
589
- return False
587
+ except: # noqa E722
588
+ return False
590
589
 
591
590
 
592
591
  def is_raspberrypi() -> bool:
@@ -617,14 +616,15 @@ def is_online() -> bool:
617
616
  Returns:
618
617
  (bool): True if connection is successful, False otherwise.
619
618
  """
620
- with contextlib.suppress(Exception):
619
+ try:
621
620
  assert str(os.getenv("YOLO_OFFLINE", "")).lower() != "true" # check if ENV var YOLO_OFFLINE="True"
622
621
  import socket
623
622
 
624
623
  for dns in ("1.1.1.1", "8.8.8.8"): # check Cloudflare and Google DNS
625
624
  socket.create_connection(address=(dns, 80), timeout=2.0).close()
626
625
  return True
627
- return False
626
+ except: # noqa E722
627
+ return False
628
628
 
629
629
 
630
630
  def is_pip_package(filepath: str = __name__) -> bool:
@@ -711,9 +711,11 @@ def get_git_origin_url():
711
711
  (str | None): The origin URL of the git repository or None if not git directory.
712
712
  """
713
713
  if IS_GIT_DIR:
714
- with contextlib.suppress(subprocess.CalledProcessError):
714
+ try:
715
715
  origin = subprocess.check_output(["git", "config", "--get", "remote.origin.url"])
716
716
  return origin.decode().strip()
717
+ except subprocess.CalledProcessError:
718
+ return None
717
719
 
718
720
 
719
721
  def get_git_branch():
@@ -724,9 +726,11 @@ def get_git_branch():
724
726
  (str | None): The current git branch name or None if not a git directory.
725
727
  """
726
728
  if IS_GIT_DIR:
727
- with contextlib.suppress(subprocess.CalledProcessError):
729
+ try:
728
730
  origin = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"])
729
731
  return origin.decode().strip()
732
+ except subprocess.CalledProcessError:
733
+ return None
730
734
 
731
735
 
732
736
  def get_default_args(func):
@@ -751,9 +755,11 @@ def get_ubuntu_version():
751
755
  (str): Ubuntu version or None if not an Ubuntu OS.
752
756
  """
753
757
  if is_ubuntu():
754
- with contextlib.suppress(FileNotFoundError, AttributeError):
758
+ try:
755
759
  with open("/etc/os-release") as f:
756
760
  return re.search(r'VERSION_ID="(\d+\.\d+)"', f.read())[1]
761
+ except (FileNotFoundError, AttributeError):
762
+ return None
757
763
 
758
764
 
759
765
  def get_user_config_dir(sub_dir="Ultralytics"):
@@ -1,6 +1,7 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
  """Functions for estimating the best YOLO batch size to use a fraction of the available CUDA memory in PyTorch."""
3
3
 
4
+ import os
4
5
  from copy import deepcopy
5
6
 
6
7
  import numpy as np
@@ -57,7 +58,7 @@ def autobatch(model, imgsz=640, fraction=0.60, batch_size=DEFAULT_CFG.batch):
57
58
 
58
59
  # Inspect CUDA memory
59
60
  gb = 1 << 30 # bytes to GiB (1024 ** 3)
60
- d = str(device).upper() # 'CUDA:0'
61
+ d = f"CUDA:{os.getenv('CUDA_VISIBLE_DEVICES', '0').strip()[0]}" # 'CUDA:0'
61
62
  properties = torch.cuda.get_device_properties(device) # device properties
62
63
  t = properties.total_memory / gb # GiB total
63
64
  r = torch.cuda.memory_reserved(device) / gb # GiB reserved
@@ -69,7 +70,7 @@ def autobatch(model, imgsz=640, fraction=0.60, batch_size=DEFAULT_CFG.batch):
69
70
  batch_sizes = [1, 2, 4, 8, 16]
70
71
  try:
71
72
  img = [torch.empty(b, 3, imgsz, imgsz) for b in batch_sizes]
72
- results = profile(img, model, n=3, device=device)
73
+ results = profile(img, model, n=1, device=device)
73
74
 
74
75
  # Fit a solution
75
76
  y = [x[2] for x in results if x] # memory [2]
@@ -89,3 +90,5 @@ def autobatch(model, imgsz=640, fraction=0.60, batch_size=DEFAULT_CFG.batch):
89
90
  except Exception as e:
90
91
  LOGGER.warning(f"{prefix}WARNING ⚠️ error detected: {e}, using default batch-size {batch_size}.")
91
92
  return batch_size
93
+ finally:
94
+ torch.cuda.empty_cache()
@@ -1,6 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- import contextlib
4
3
 
5
4
  from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING, colorstr
6
5
 
@@ -45,26 +44,27 @@ def _log_tensorboard_graph(trainer):
45
44
  warnings.simplefilter("ignore", category=torch.jit.TracerWarning) # suppress jit trace warning
46
45
 
47
46
  # Try simple method first (YOLO)
48
- with contextlib.suppress(Exception):
47
+ try:
49
48
  trainer.model.eval() # place in .eval() mode to avoid BatchNorm statistics changes
50
49
  WRITER.add_graph(torch.jit.trace(de_parallel(trainer.model), im, strict=False), [])
51
50
  LOGGER.info(f"{PREFIX}model graph visualization added ✅")
52
51
  return
53
52
 
54
- # Fallback to TorchScript export steps (RTDETR)
55
- try:
56
- model = deepcopy(de_parallel(trainer.model))
57
- model.eval()
58
- model = model.fuse(verbose=False)
59
- for m in model.modules():
60
- if hasattr(m, "export"): # Detect, RTDETRDecoder (Segment and Pose use Detect base class)
61
- m.export = True
62
- m.format = "torchscript"
63
- model(im) # dry run
64
- WRITER.add_graph(torch.jit.trace(model, im, strict=False), [])
65
- LOGGER.info(f"{PREFIX}model graph visualization added ✅")
66
- except Exception as e:
67
- LOGGER.warning(f"{PREFIX}WARNING ⚠️ TensorBoard graph visualization failure {e}")
53
+ except: # noqa E722
54
+ # Fallback to TorchScript export steps (RTDETR)
55
+ try:
56
+ model = deepcopy(de_parallel(trainer.model))
57
+ model.eval()
58
+ model = model.fuse(verbose=False)
59
+ for m in model.modules():
60
+ if hasattr(m, "export"): # Detect, RTDETRDecoder (Segment and Pose use Detect base class)
61
+ m.export = True
62
+ m.format = "torchscript"
63
+ model(im) # dry run
64
+ WRITER.add_graph(torch.jit.trace(model, im, strict=False), [])
65
+ LOGGER.info(f"{PREFIX}model graph visualization added ✅")
66
+ except Exception as e:
67
+ LOGGER.warning(f"{PREFIX}WARNING ⚠️ TensorBoard graph visualization failure {e}")
68
68
 
69
69
 
70
70
  def on_pretrain_routine_start(trainer):
@@ -1,6 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- import contextlib
4
3
  import glob
5
4
  import inspect
6
5
  import math
@@ -271,11 +270,13 @@ def check_latest_pypi_version(package_name="ultralytics"):
271
270
  Returns:
272
271
  (str): The latest version of the package.
273
272
  """
274
- with contextlib.suppress(Exception):
273
+ try:
275
274
  requests.packages.urllib3.disable_warnings() # Disable the InsecureRequestWarning
276
275
  response = requests.get(f"https://pypi.org/pypi/{package_name}/json", timeout=3)
277
276
  if response.status_code == 200:
278
277
  return response.json()["info"]["version"]
278
+ except: # noqa E722
279
+ return None
279
280
 
280
281
 
281
282
  def check_pip_update_available():
@@ -286,7 +287,7 @@ def check_pip_update_available():
286
287
  (bool): True if an update is available, False otherwise.
287
288
  """
288
289
  if ONLINE and IS_PIP_PACKAGE:
289
- with contextlib.suppress(Exception):
290
+ try:
290
291
  from ultralytics import __version__
291
292
 
292
293
  latest = check_latest_pypi_version()
@@ -296,6 +297,8 @@ def check_pip_update_available():
296
297
  f"Update with 'pip install -U ultralytics'"
297
298
  )
298
299
  return True
300
+ except: # noqa E722
301
+ pass
299
302
  return False
300
303
 
301
304
 
@@ -577,10 +580,12 @@ def check_yolo(verbose=True, device=""):
577
580
  ram = psutil.virtual_memory().total
578
581
  total, used, free = shutil.disk_usage("/")
579
582
  s = f"({os.cpu_count()} CPUs, {ram / gib:.1f} GB RAM, {(total - free) / gib:.1f}/{total / gib:.1f} GB disk)"
580
- with contextlib.suppress(Exception): # clear display if ipython is installed
583
+ try:
581
584
  from IPython import display
582
585
 
583
- display.clear_output()
586
+ display.clear_output() # clear display if notebook
587
+ except ImportError:
588
+ pass
584
589
  else:
585
590
  s = ""
586
591
 
@@ -619,7 +624,7 @@ def collect_system_info():
619
624
  for r in parse_requirements(package="ultralytics"):
620
625
  try:
621
626
  current = metadata.version(r.name)
622
- is_met = "✅ " if check_version(current, str(r.specifier), hard=True) else "❌ "
627
+ is_met = "✅ " if check_version(current, str(r.specifier), name=r.name, hard=True) else "❌ "
623
628
  except metadata.PackageNotFoundError:
624
629
  current = "(not installed)"
625
630
  is_met = "❌ "
@@ -707,9 +712,10 @@ def check_amp(model):
707
712
 
708
713
  def git_describe(path=ROOT): # path must be a directory
709
714
  """Return human-readable git description, i.e. v5.0-5-g3e25f1e https://git-scm.com/docs/git-describe."""
710
- with contextlib.suppress(Exception):
715
+ try:
711
716
  return subprocess.check_output(f"git -C {path} describe --tags --long --always", shell=True).decode()[:-1]
712
- return ""
717
+ except: # noqa E722
718
+ return ""
713
719
 
714
720
 
715
721
  def print_args(args: Optional[dict] = None, show_file=True, show_func=False):
@@ -1,6 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- import contextlib
4
3
  import re
5
4
  import shutil
6
5
  import subprocess
@@ -53,7 +52,7 @@ def is_url(url, check=False):
53
52
  valid = is_url("https://www.example.com")
54
53
  ```
55
54
  """
56
- with contextlib.suppress(Exception):
55
+ try:
57
56
  url = str(url)
58
57
  result = parse.urlparse(url)
59
58
  assert all([result.scheme, result.netloc]) # check if is url
@@ -61,7 +60,8 @@ def is_url(url, check=False):
61
60
  with request.urlopen(url) as response:
62
61
  return response.getcode() == 200 # check if exists online
63
62
  return True
64
- return False
63
+ except: # noqa E722
64
+ return False
65
65
 
66
66
 
67
67
  def delete_dsstore(path, files_to_delete=(".DS_Store", "__MACOSX")):
@@ -1,6 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- import contextlib
4
3
  import math
5
4
  import warnings
6
5
  from pathlib import Path
@@ -13,8 +12,8 @@ import torch
13
12
  from PIL import Image, ImageDraw, ImageFont
14
13
  from PIL import __version__ as pil_version
15
14
 
16
- from ultralytics.utils import IS_JUPYTER, LOGGER, TryExcept, ops, plt_settings, threaded
17
- from ultralytics.utils.checks import check_font, check_requirements, check_version, is_ascii
15
+ from ultralytics.utils import IS_COLAB, IS_KAGGLE, LOGGER, TryExcept, ops, plt_settings, threaded
16
+ from ultralytics.utils.checks import check_font, check_version, is_ascii
18
17
  from ultralytics.utils.files import increment_path
19
18
 
20
19
 
@@ -525,16 +524,12 @@ class Annotator:
525
524
  def show(self, title=None):
526
525
  """Show the annotated image."""
527
526
  im = Image.fromarray(np.asarray(self.im)[..., ::-1]) # Convert numpy array to PIL Image with RGB to BGR
528
- if IS_JUPYTER:
529
- check_requirements("ipython")
527
+ if IS_COLAB or IS_KAGGLE: # can not use IS_JUPYTER as will run for all ipython environments
530
528
  try:
531
- from IPython.display import display
532
-
533
- display(im)
529
+ display(im) # noqa - display() function only available in ipython environments
534
530
  except ImportError as e:
535
531
  LOGGER.warning(f"Unable to display image in Jupyter notebooks: {e}")
536
532
  else:
537
- # Convert numpy array to PIL Image and show
538
533
  im.show(title=title)
539
534
 
540
535
  def save(self, filename="image.jpg"):
@@ -1119,10 +1114,12 @@ def plot_images(
1119
1114
  mask = mask.astype(bool)
1120
1115
  else:
1121
1116
  mask = image_masks[j].astype(bool)
1122
- with contextlib.suppress(Exception):
1117
+ try:
1123
1118
  im[y : y + h, x : x + w, :][mask] = (
1124
1119
  im[y : y + h, x : x + w, :][mask] * 0.4 + np.array(color) * 0.6
1125
1120
  )
1121
+ except: # noqa E722
1122
+ pass
1126
1123
  annotator.fromarray(im)
1127
1124
  if not save:
1128
1125
  return np.asarray(annotator.im)
@@ -1,6 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- import contextlib
4
3
  import gc
5
4
  import math
6
5
  import os
@@ -113,13 +112,15 @@ def get_cpu_info():
113
112
  from ultralytics.utils import PERSISTENT_CACHE # avoid circular import error
114
113
 
115
114
  if "cpu_info" not in PERSISTENT_CACHE:
116
- with contextlib.suppress(Exception):
115
+ try:
117
116
  import cpuinfo # pip install py-cpuinfo
118
117
 
119
118
  k = "brand_raw", "hardware_raw", "arch_string_raw" # keys sorted by preference
120
119
  info = cpuinfo.get_cpu_info() # info dict
121
120
  string = info.get(k[0] if k[0] in info else k[1] if k[1] in info else k[2], "unknown")
122
121
  PERSISTENT_CACHE["cpu_info"] = string.replace("(R)", "").replace("CPU ", "").replace("@ ", "")
122
+ except: # noqa E722
123
+ pass
123
124
  return PERSISTENT_CACHE.get("cpu_info", "unknown")
124
125
 
125
126
 
@@ -643,7 +644,8 @@ def profile(input, ops, n=10, device=None):
643
644
  f"{'Params':>12s}{'GFLOPs':>12s}{'GPU_mem (GB)':>14s}{'forward (ms)':>14s}{'backward (ms)':>14s}"
644
645
  f"{'input':>24s}{'output':>24s}"
645
646
  )
646
-
647
+ gc.collect() # attempt to free unused memory
648
+ torch.cuda.empty_cache()
647
649
  for x in input if isinstance(input, list) else [input]:
648
650
  x = x.to(device)
649
651
  x.requires_grad = True
@@ -677,8 +679,9 @@ def profile(input, ops, n=10, device=None):
677
679
  except Exception as e:
678
680
  LOGGER.info(e)
679
681
  results.append(None)
680
- gc.collect() # attempt to free unused memory
681
- torch.cuda.empty_cache()
682
+ finally:
683
+ gc.collect() # attempt to free unused memory
684
+ torch.cuda.empty_cache()
682
685
  return results
683
686
 
684
687
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ultralytics
3
- Version: 8.3.6
3
+ Version: 8.3.8
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,11 +7,11 @@ tests/test_explorer.py,sha256=9EeMtt4-K3-MeGnAc7NemTg3uTo-Xr6AYJlTJZJJeF8,2572
7
7
  tests/test_exports.py,sha256=fpTKEVBUGLF3WiZPNKRs-IEcIY4cfxgvgKjUNfodjww,8042
8
8
  tests/test_integrations.py,sha256=f5-QCUk1SU_-qn4mBCZwS3GN3tXEBIIXo4z2EhExbHw,6126
9
9
  tests/test_python.py,sha256=I1RRdCwLdrc3jX06huVxct8HX8ccQOmQgVpuEflRl0U,23560
10
- tests/test_solutions.py,sha256=GYOjUXor2pHGPFwvZrmqrxNjs9wYz4r3_XWt8DMAVaM,3132
11
- ultralytics/__init__.py,sha256=WlkyTS3L-3ozTAF5fT2vLMSf4tQNvOaCxGsICIQf7mA,693
10
+ tests/test_solutions.py,sha256=kJzvUiOTmFVeM_90_7vwvhrREGrN2aGwcBi-F-a13NU,3126
11
+ ultralytics/__init__.py,sha256=xqr6W7SxucuDpDIAK7_hCzACbw8DLZQHjSo-7vDqXBo,752
12
12
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
13
13
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
14
- ultralytics/cfg/__init__.py,sha256=62PSSAa0W4-gAEcRNKoKbcxUWBeFNs0ss2O4XJQhOPY,33145
14
+ ultralytics/cfg/__init__.py,sha256=N-XONBXwmD3vzoE4icBXznkV8LOLmf6ak6mRdGPucvw,33146
15
15
  ultralytics/cfg/default.yaml,sha256=ul49zgSzTegMmc8CFeu9tXkWNvQhETdZMa9EgDNSnY4,8319
16
16
  ultralytics/cfg/datasets/Argoverse.yaml,sha256=FyeuJT5CHq_9d4hlfAf0kpZlnbUMO0S--UJ1yIqcdKk,3134
17
17
  ultralytics/cfg/datasets/DOTAv1.5.yaml,sha256=QVfp_Qp-4rukuicaB4qx86NxSHM8Mrzym8l_fIDo8gw,1195
@@ -94,19 +94,19 @@ ultralytics/data/annotator.py,sha256=PniOxH2MScWKp539vuufk69uG1JsltDB5OMCUhxn2QY
94
94
  ultralytics/data/augment.py,sha256=YCLrwx1mRGeidggo_7GeINay8KdxACqREHJofZeaTHA,120430
95
95
  ultralytics/data/base.py,sha256=ZCIhAyFfxXVp5fVnYD8mwbksNALJTayBKIR5FKGV7ZM,15168
96
96
  ultralytics/data/build.py,sha256=AfMmz0sHIYmwry_90tEJFRk_kz0S3SolScVXqYHiT08,7261
97
- ultralytics/data/converter.py,sha256=DjJ0atku2aKW0iS1PZPNX8V6WTrZ-CHZT6hopE1HSjI,21385
98
- ultralytics/data/dataset.py,sha256=IS07ulk7rXPZ-SW_rjYF9mS-TxPXOY9bbo5jqfcwPqM,22874
97
+ ultralytics/data/converter.py,sha256=QCtrcbNz9kid8nvHfGIWt02nH1wwMKv6HI-8s927CR8,24251
98
+ ultralytics/data/dataset.py,sha256=D556AW0ZEsW3V8c5zJiHM_prc_YfZqymIkDKPw3k9Io,22936
99
99
  ultralytics/data/loaders.py,sha256=JF2Z_ESK6RweavOuYWejYSGJwmqINb5hNwwCb3AAf0M,24094
100
100
  ultralytics/data/split_dota.py,sha256=yOtypHoY5HvIVBKZgFXdfj2tuCLLEBnMwNfAeG94Eik,10680
101
- ultralytics/data/utils.py,sha256=FQhceOiQOuhyDKCeX-ovEBBr2fO7cFbcVaAUp-nk3CM,31072
101
+ ultralytics/data/utils.py,sha256=BK4Z87fDHfNCd6RYVYVWdTVWc8-tCqNJ-VfeN8ZG8l0,31068
102
102
  ultralytics/data/explorer/__init__.py,sha256=-Y3m1ZedepOQUv_KW82zaGxvU_PSHcuwUTFqG9BhAr4,113
103
103
  ultralytics/data/explorer/explorer.py,sha256=JWmLHHhp68h2q3vx4poBou5RYoAX3R89yihR50YLDb0,18881
104
104
  ultralytics/data/explorer/utils.py,sha256=EvvukQiQUTBrsZznmMnyEX2EqTuwZo_Geyc8yfi8NIA,7085
105
105
  ultralytics/data/explorer/gui/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7JI8grmQDTs,42
106
- ultralytics/data/explorer/gui/dash.py,sha256=vZ476NaUH4FKU08rAJ1K9WNyKtg0soMyJJxqg176yWc,10498
106
+ ultralytics/data/explorer/gui/dash.py,sha256=6XOZy9NrkPEXREJPbi0EBkGgu78TAdHpdhSB2HuBOAo,10222
107
107
  ultralytics/engine/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7JI8grmQDTs,42
108
108
  ultralytics/engine/exporter.py,sha256=DeHW_T_Zd3A21BLQYV1-FnS5EcmepMOy9nrussYNieU,57505
109
- ultralytics/engine/model.py,sha256=TDuy9JzzyvOaq5aKVljL_MFRKBDMCFwaLo3JD_d45CU,51462
109
+ ultralytics/engine/model.py,sha256=Vtkza7cQrxvowb0PqGFhp7eC3cXRIKj6OUaR5d9w1-U,51464
110
110
  ultralytics/engine/predictor.py,sha256=MgMWHUJdRcVCaVmOyvdy2Gjk_EyRHv-ar0SSGxQe8F4,17471
111
111
  ultralytics/engine/results.py,sha256=8RJlN8J-_9w-mrDZm9wC-DZJTPBS7v1c_r_R173QyRM,75043
112
112
  ultralytics/engine/trainer.py,sha256=ZCEXUPbJG_8Hzn2mLergk3WV-41ei0LT84Tspk0le30,37147
@@ -158,7 +158,7 @@ ultralytics/models/yolo/classify/val.py,sha256=Tzizhp3ebzPvwJejrE8tb-TuXw4MdkEI9
158
158
  ultralytics/models/yolo/detect/__init__.py,sha256=JR8gZJWn7wMBbh-0j_073nxJVZTMFZVWTOG5Wnvk6w0,229
159
159
  ultralytics/models/yolo/detect/predict.py,sha256=_kY6-_wsPCt9ZOf-iwusceikAM5TV_KnjYdv2koE45A,1471
160
160
  ultralytics/models/yolo/detect/train.py,sha256=cHlCTj39Tr6butQOQRreCFnVODK2IqaogBpTAQuGAPE,6363
161
- ultralytics/models/yolo/detect/val.py,sha256=Na1y94GLfF72-9Jj6uNtPk_CCpLpNPmoMVgukRPVmuk,15154
161
+ ultralytics/models/yolo/detect/val.py,sha256=qZDP1ETpZE1e7avZyOuBe3U8zuLpsBdKHUuN3YL-tQI,15152
162
162
  ultralytics/models/yolo/obb/__init__.py,sha256=txWbPGLY1_M7ZwlLQjrwGjTBOlsv9P3yk5ZEgysTinU,193
163
163
  ultralytics/models/yolo/obb/predict.py,sha256=VxpKCKV5dWnOr0GyV1rJGH5SzzRouCYW_8T26xJ8MU8,2037
164
164
  ultralytics/models/yolo/obb/train.py,sha256=_FVYCvHJ5ECi2aN8k7AmVLxRUuun7acSqwWtCBRuL6Q,1473
@@ -175,8 +175,8 @@ ultralytics/models/yolo/world/__init__.py,sha256=3VTH0q4NOt2EWRom15yCymvmvm0Etp2
175
175
  ultralytics/models/yolo/world/train.py,sha256=gaDrAmLJpg9qDtmL5evA5HsV2yb4RTRSfk2EDYrHdRg,3686
176
176
  ultralytics/models/yolo/world/train_world.py,sha256=IsnCEVt6DcM9lUskCKmIN-M8MM79xLpwTRqRoAHUnZ4,4857
177
177
  ultralytics/nn/__init__.py,sha256=4BPLHY89xEM_al5uK0aOmFgiML6CMGEZbezxOvTjOEs,587
178
- ultralytics/nn/autobackend.py,sha256=95FVDv_l5fax5f8gmhYAIIS2e_8u6HYxNd4Saxh7E10,31573
179
- ultralytics/nn/tasks.py,sha256=mJmuJncAK2iQm-lCFjIrFrtgsT5t3DoOetRRpfLREPk,48342
178
+ ultralytics/nn/autobackend.py,sha256=lyOXfZC4jgSebv52YpHlrfUNKp_kVBmIvydb9k0OKFQ,31607
179
+ ultralytics/nn/tasks.py,sha256=O4i5JywqZZ2llESZ39PbojhsQcbFV5Yc1G5moiS80bM,48397
180
180
  ultralytics/nn/modules/__init__.py,sha256=xhW2BennT9U_VaMXVpRu-bdLgp1BXt9L8mkIUBE3idU,2625
181
181
  ultralytics/nn/modules/activation.py,sha256=chhn469wnRHEs5BMGNBYXwPYZc_7-urspTT8fnBd-xA,895
182
182
  ultralytics/nn/modules/block.py,sha256=thcIPcnGRRxDDDswywJsfzbewr9XfTrzl_UvSl-bJ3c,41832
@@ -189,10 +189,10 @@ ultralytics/solutions/ai_gym.py,sha256=lBAkWV8vrEdKAXcBFVbugPeZZ08MOjGYTdnFlG22v
189
189
  ultralytics/solutions/analytics.py,sha256=bGuZes11D7DNiTsHdwu6PJ0QA0vCiqMMAtZ7NyEkshY,11568
190
190
  ultralytics/solutions/distance_calculation.py,sha256=o_DAHk4JX8n2Vt7E68MX67mREOBZuy5skbXtVZ6iu_4,5228
191
191
  ultralytics/solutions/heatmap.py,sha256=2C4s_rVFcOc5oSWxb0pNxNoCawe4lxajpTDNFd4tVL8,3850
192
- ultralytics/solutions/object_counter.py,sha256=uuA7B-v9u-ElyEg1xCuNRgcnxpRpEfBWCdLs2ppjzzk,5497
192
+ ultralytics/solutions/object_counter.py,sha256=1Nsivk-cyGBM1G6eWe11_vdDWTdbJwaUFMJ1A7OK-Qg,5495
193
193
  ultralytics/solutions/parking_management.py,sha256=VgYyhoSEo7fnPegIhNUqnFL0jlMEevALx0QQbzJ3vGI,9049
194
- ultralytics/solutions/queue_management.py,sha256=yKPGc2-fN-lMpNddkxjN7xYGIJwMdoU-VIDRxQ1KPow,4869
195
- ultralytics/solutions/solutions.py,sha256=y6A2ZelsUj9RgN0GZNFBc_01UakoByT_jLG8-FiiLyI,3461
194
+ ultralytics/solutions/queue_management.py,sha256=5d1RURQiqffAoET8S66gHimK0l3gKNAfuPO5U6_08jc,2716
195
+ ultralytics/solutions/solutions.py,sha256=qWKGlwlH9858GfAdZkcu_QXbrzjTFStDvg16Eky0oyo,3541
196
196
  ultralytics/solutions/speed_estimation.py,sha256=c9OPGpDU9x6Dj4SobNc-sO90EZTPTGeKkW5u6C6Zj7g,4623
197
197
  ultralytics/solutions/streamlit_inference.py,sha256=qA2EtwUC7ADOQ8P-zs3VPyrIoRArhcZz9CxkFbH63bw,5699
198
198
  ultralytics/trackers/__init__.py,sha256=j72IgH2dZHQArMPK4YwcV5ieIw94fYvlGdQjB9cOQKw,227
@@ -204,12 +204,12 @@ ultralytics/trackers/utils/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7J
204
204
  ultralytics/trackers/utils/gmc.py,sha256=VcURuY041qGCeWUGMxHZBr10T16LtcMqyv7AmTfE1MY,14557
205
205
  ultralytics/trackers/utils/kalman_filter.py,sha256=cH9zD3fwkuezP97H9mw8cSBN7a8hHKx_Sx1j7t3oYGs,21349
206
206
  ultralytics/trackers/utils/matching.py,sha256=3Ie1WNNRZ4_q3365F03XD7Nr9juZB_08mw4yUKC3w74,7162
207
- ultralytics/utils/__init__.py,sha256=XAfItx7avPCi7fpT7rRyQQqgjh2OwoSEkvkp01BbtYc,48760
208
- ultralytics/utils/autobatch.py,sha256=AXboYfNSnTGsYj5FmgGYPQd0crfkeleyms6QXQfZGQ4,4194
207
+ ultralytics/utils/__init__.py,sha256=du1Y1LMU0jQn_zWWnAIx9U8wn6Vh7ce-k7qMwi6y0po,48698
208
+ ultralytics/utils/autobatch.py,sha256=1ZDy3vvUDKkxROHnxT3_vI4MJ52l9ap7SiuQvG4B-8k,4290
209
209
  ultralytics/utils/benchmarks.py,sha256=8FYp5WPzcxcDaeg8ol2sgzRBHVGYatEO7f3MrmPF6nI,25097
210
- ultralytics/utils/checks.py,sha256=7peQ6Ra7mgcu5Xt1XbYiMEJkO-8aYPHco7CBVRQ_oR4,29559
210
+ ultralytics/utils/checks.py,sha256=7oWc91HqQdH9EHuHysxk_ZltiRrGt6eq-pUf0TkA3gU,29579
211
211
  ultralytics/utils/dist.py,sha256=NDFga-uKxkBX2zLxFHSene_cCiGQJoyOeCXcN9JIOIk,2358
212
- ultralytics/utils/downloads.py,sha256=97JitihZqvIMS6_TX5rJAG7BI8eYHlu5g8YXlI0RkR4,21998
212
+ ultralytics/utils/downloads.py,sha256=o8RY9f0KrzWfueLs8DuJ5w8OWQ-ll4ZS9lX6MEFDi70,21977
213
213
  ultralytics/utils/errors.py,sha256=GqP_Jgj_n0paxn8OMhn3DTCgoNkB2WjUcUaqs-M6SQk,816
214
214
  ultralytics/utils/files.py,sha256=YjfzbBDAq-nD3LKjtuMVwggnnv1dROMuVoo3Edm_tjU,8224
215
215
  ultralytics/utils/instance.py,sha256=QSms7mPHZ5e8JGuJYLohLWltzI0aBE8dob2rOUK4RtM,16249
@@ -217,9 +217,9 @@ ultralytics/utils/loss.py,sha256=SW3FVFFp8Ki_LCT8wIdFbm6KmyPcQn3RmKNcvVAhMQI,341
217
217
  ultralytics/utils/metrics.py,sha256=UgLGudWp57uXDMlMUJy4gsz6cfVjcq7tYmHeto3TqvM,53927
218
218
  ultralytics/utils/ops.py,sha256=dsXNdyrYx_p6io6zezig9p84dxS7U-10vceHNVu2IL0,32888
219
219
  ultralytics/utils/patches.py,sha256=J-iOwIRbfUs-inBZerhnXby5tUKjYcOIyvhLTS352JE,3270
220
- ultralytics/utils/plotting.py,sha256=UQMgubdCKkIcKLLIXkE6uM9dhL7NlFRka6xXgfCMFn8,61153
220
+ ultralytics/utils/plotting.py,sha256=aozAEwcbc447ume9bQrEBTU04AzyiZZrnzcTzA2S6j0,61165
221
221
  ultralytics/utils/tal.py,sha256=ECsu95xEqOItmxMDN4YTD3FsUiIsQNWy0pZC3TfvFfk,16877
222
- ultralytics/utils/torch_utils.py,sha256=Dji6ELzywm4yq1D4AbUhOsanmoo9-pwxx5GBlYdIgqU,29956
222
+ ultralytics/utils/torch_utils.py,sha256=gVN-KSrAzJC1rW3woQd4FsTT693GD8rXiccToL2m4kM,30059
223
223
  ultralytics/utils/triton.py,sha256=gg1finxno_tY2Ge9PMhmu7PI9wvoFZoiicdT4Bhqv3w,3936
224
224
  ultralytics/utils/tuner.py,sha256=AtEtK6pOt9xVTyx864OpNRVxNdAxz5aKHzveiXwkD1A,6250
225
225
  ultralytics/utils/callbacks/__init__.py,sha256=YrWqC3BVVaTLob4iCPR6I36mUxIUOpPJW7B_LjT78Qw,214
@@ -231,11 +231,11 @@ ultralytics/utils/callbacks/hub.py,sha256=EPewsLigFQc9ucTX2exKSlKBiaBNhYYyGC_nR2
231
231
  ultralytics/utils/callbacks/mlflow.py,sha256=_bUzHyPb0npne0WFlGzlGCy-X5sxGQhC_xA3dZbF08I,5391
232
232
  ultralytics/utils/callbacks/neptune.py,sha256=5Z3ua5YBTUS56FH8VQKQG1aaIo9fH8GEyzC5q7p4ipQ,3756
233
233
  ultralytics/utils/callbacks/raytune.py,sha256=ODVYzy-CoM4Uge0zjkh3Hnh9nF2M0vhDrSenXnvcizw,705
234
- ultralytics/utils/callbacks/tensorboard.py,sha256=0kn4IR10no99UCIheojWRujgybmUHSx5fPI6Vsq6l_g,4135
234
+ ultralytics/utils/callbacks/tensorboard.py,sha256=bv4fkkesdgmZv_E2MU6wuaMBwEV5iI2G53RHPyD9quw,4170
235
235
  ultralytics/utils/callbacks/wb.py,sha256=9-fjQIdLjr3b73DTE3rHO171KvbH1VweJ-bmbv-rqTw,6747
236
- ultralytics-8.3.6.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
237
- ultralytics-8.3.6.dist-info/METADATA,sha256=8c1KpR7WhT8HlvpimiFOS4G3vd8KtQ8YxBUHYnQ_dDc,34699
238
- ultralytics-8.3.6.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
239
- ultralytics-8.3.6.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
240
- ultralytics-8.3.6.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
241
- ultralytics-8.3.6.dist-info/RECORD,,
236
+ ultralytics-8.3.8.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
237
+ ultralytics-8.3.8.dist-info/METADATA,sha256=omBKv11I1DidGjRCYOu07_VBN1yVEDB8Ccx2jNIw5Rk,34699
238
+ ultralytics-8.3.8.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
239
+ ultralytics-8.3.8.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
240
+ ultralytics-8.3.8.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
241
+ ultralytics-8.3.8.dist-info/RECORD,,