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

ultralytics/__init__.py CHANGED
@@ -1,11 +1,12 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- __version__ = '8.0.114'
3
+ __version__ = '8.0.116'
4
4
 
5
5
  from ultralytics.hub import start
6
6
  from ultralytics.vit.rtdetr import RTDETR
7
7
  from ultralytics.vit.sam import SAM
8
8
  from ultralytics.yolo.engine.model import YOLO
9
+ from ultralytics.yolo.nas import NAS
9
10
  from ultralytics.yolo.utils.checks import check_yolo as checks
10
11
 
11
- __all__ = '__version__', 'YOLO', 'SAM', 'RTDETR', 'checks', 'start' # allow simpler import
12
+ __all__ = '__version__', 'YOLO', 'NAS', 'SAM', 'RTDETR', 'checks', 'start' # allow simpler import
@@ -110,3 +110,12 @@ class RTDETR:
110
110
  if args.batch == DEFAULT_CFG.batch:
111
111
  args.batch = 1 # default to 1 if not modified
112
112
  return Exporter(overrides=args)(model=self.model)
113
+
114
+ def __call__(self, source=None, stream=False, **kwargs):
115
+ """Calls the 'predict' function with given arguments to perform object detection."""
116
+ return self.predict(source, stream, **kwargs)
117
+
118
+ def __getattr__(self, attr):
119
+ """Raises error if object has no requested attribute."""
120
+ name = self.__class__.__name__
121
+ raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
@@ -35,6 +35,15 @@ class SAM:
35
35
  """Run validation given dataset."""
36
36
  raise NotImplementedError("SAM models don't support validation")
37
37
 
38
+ def __call__(self, source=None, stream=False, **kwargs):
39
+ """Calls the 'predict' function with given arguments to perform object detection."""
40
+ return self.predict(source, stream, **kwargs)
41
+
42
+ def __getattr__(self, attr):
43
+ """Raises error if object has no requested attribute."""
44
+ name = self.__class__.__name__
45
+ raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
46
+
38
47
  def info(self, detailed=False, verbose=True):
39
48
  """
40
49
  Logs model info.
@@ -138,7 +138,7 @@ def polygon2mask(imgsz, polygons, color=1, downsample_ratio=1):
138
138
  """
139
139
  Args:
140
140
  imgsz (tuple): The image size.
141
- polygons (np.ndarray): [N, M], N is the number of polygons, M is the number of points(Be divided by 2).
141
+ polygons (list[np.ndarray]): [N, M], N is the number of polygons, M is the number of points(Be divided by 2).
142
142
  color (int): color
143
143
  downsample_ratio (int): downsample ratio
144
144
  """
@@ -9,8 +9,8 @@ from ultralytics.nn.tasks import (ClassificationModel, DetectionModel, PoseModel
9
9
  attempt_load_one_weight, guess_model_task, nn, yaml_model_load)
10
10
  from ultralytics.yolo.cfg import get_cfg
11
11
  from ultralytics.yolo.engine.exporter import Exporter
12
- from ultralytics.yolo.utils import (DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, RANK, ROOT, callbacks,
13
- is_git_dir, yaml_load)
12
+ from ultralytics.yolo.utils import (DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, NUM_THREADS, RANK, ROOT,
13
+ callbacks, is_git_dir, yaml_load)
14
14
  from ultralytics.yolo.utils.checks import check_file, check_imgsz, check_pip_update_available, check_yaml
15
15
  from ultralytics.yolo.utils.downloads import GITHUB_ASSET_STEMS
16
16
  from ultralytics.yolo.utils.torch_utils import smart_inference_mode
@@ -119,7 +119,7 @@ class YOLO:
119
119
  def is_hub_model(model):
120
120
  """Check if the provided model is a HUB model."""
121
121
  return any((
122
- model.startswith('https://hub.ultra'), # i.e. https://hub.ultralytics.com/models/MODEL_ID
122
+ model.startswith('https://hub.ultralytics.com/models/'), # i.e. https://hub.ultralytics.com/models/MODEL_ID
123
123
  [len(x) for x in model.split('_')] == [42, 20], # APIKEY_MODELID
124
124
  len(model) == 20 and not Path(model).exists() and all(x not in model for x in './\\'))) # MODELID
125
125
 
@@ -391,7 +391,7 @@ class YOLO:
391
391
  grace_period: int = 10,
392
392
  gpu_per_trial: int = None,
393
393
  max_samples: int = 10,
394
- train_args: dict = {}):
394
+ train_args: dict = None):
395
395
  """
396
396
  Runs hyperparameter tuning using Ray Tune.
397
397
 
@@ -409,6 +409,8 @@ class YOLO:
409
409
  Raises:
410
410
  ModuleNotFoundError: If Ray Tune is not installed.
411
411
  """
412
+ if train_args is None:
413
+ train_args = {}
412
414
 
413
415
  try:
414
416
  from ultralytics.yolo.utils.tuner import (ASHAScheduler, RunConfig, WandbLoggerCallback, default_space,
@@ -443,7 +445,7 @@ class YOLO:
443
445
  space['data'] = data
444
446
 
445
447
  # Define the trainable function with allocated resources
446
- trainable_with_resources = tune.with_resources(_tune, {'cpu': 8, 'gpu': gpu_per_trial if gpu_per_trial else 0})
448
+ trainable_with_resources = tune.with_resources(_tune, {'cpu': NUM_THREADS, 'gpu': gpu_per_trial or 0})
447
449
 
448
450
  # Define the ASHA scheduler for hyperparameter search
449
451
  asha_scheduler = ASHAScheduler(time_attr='epoch',
@@ -454,7 +456,7 @@ class YOLO:
454
456
  reduction_factor=3)
455
457
 
456
458
  # Define the callbacks for the hyperparameter search
457
- tuner_callbacks = [WandbLoggerCallback(project='yolov8_tune')] if wandb else []
459
+ tuner_callbacks = [WandbLoggerCallback(project='YOLOv8-tune')] if wandb else []
458
460
 
459
461
  # Create the Ray Tune hyperparameter search tuner
460
462
  tuner = tune.Tuner(trainable_with_resources,
@@ -0,0 +1,7 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+
3
+ from .model import NAS
4
+ from .predict import NASPredictor
5
+ from .val import NASValidator
6
+
7
+ __all__ = 'NASPredictor', 'NASValidator', 'NAS'
@@ -0,0 +1,125 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+ """
3
+ # NAS model interface
4
+ """
5
+
6
+ from pathlib import Path
7
+
8
+ import torch
9
+
10
+ from ultralytics.yolo.cfg import get_cfg
11
+ from ultralytics.yolo.engine.exporter import Exporter
12
+ from ultralytics.yolo.utils import DEFAULT_CFG, DEFAULT_CFG_DICT, LOGGER, ROOT, is_git_dir
13
+ from ultralytics.yolo.utils.checks import check_imgsz
14
+
15
+ from ...yolo.utils.torch_utils import model_info, smart_inference_mode
16
+ from .predict import NASPredictor
17
+ from .val import NASValidator
18
+
19
+
20
+ class NAS:
21
+
22
+ def __init__(self, model='yolo_nas_s.pt') -> None:
23
+ # Load or create new NAS model
24
+ import super_gradients
25
+
26
+ self.predictor = None
27
+ suffix = Path(model).suffix
28
+ if suffix == '.pt':
29
+ self._load(model)
30
+ elif suffix == '':
31
+ self.model = super_gradients.training.models.get(model, pretrained_weights='coco')
32
+ self.task = 'detect'
33
+ self.model.args = DEFAULT_CFG_DICT # attach args to model
34
+
35
+ # Standardize model
36
+ self.model.fuse = lambda verbose: self.model
37
+ self.model.stride = torch.tensor([32])
38
+ self.model.names = dict(enumerate(self.model._class_names))
39
+ self.model.is_fused = lambda: False # for info()
40
+ self.model.yaml = {} # for info()
41
+ self.info()
42
+
43
+ @smart_inference_mode()
44
+ def _load(self, weights: str):
45
+ self.model = torch.load(weights)
46
+
47
+ @smart_inference_mode()
48
+ def predict(self, source=None, stream=False, **kwargs):
49
+ """
50
+ Perform prediction using the YOLO model.
51
+
52
+ Args:
53
+ source (str | int | PIL | np.ndarray): The source of the image to make predictions on.
54
+ Accepts all source types accepted by the YOLO model.
55
+ stream (bool): Whether to stream the predictions or not. Defaults to False.
56
+ **kwargs : Additional keyword arguments passed to the predictor.
57
+ Check the 'configuration' section in the documentation for all available options.
58
+
59
+ Returns:
60
+ (List[ultralytics.yolo.engine.results.Results]): The prediction results.
61
+ """
62
+ if source is None:
63
+ source = ROOT / 'assets' if is_git_dir() else 'https://ultralytics.com/images/bus.jpg'
64
+ LOGGER.warning(f"WARNING ⚠️ 'source' is missing. Using 'source={source}'.")
65
+ overrides = dict(conf=0.25, task='detect', mode='predict')
66
+ overrides.update(kwargs) # prefer kwargs
67
+ if not self.predictor:
68
+ self.predictor = NASPredictor(overrides=overrides)
69
+ self.predictor.setup_model(model=self.model)
70
+ else: # only update args if predictor is already setup
71
+ self.predictor.args = get_cfg(self.predictor.args, overrides)
72
+ return self.predictor(source, stream=stream)
73
+
74
+ def train(self, **kwargs):
75
+ """Function trains models but raises an error as NAS models do not support training."""
76
+ raise NotImplementedError("NAS models don't support training")
77
+
78
+ def val(self, **kwargs):
79
+ """Run validation given dataset."""
80
+ overrides = dict(task='detect', mode='val')
81
+ overrides.update(kwargs) # prefer kwargs
82
+ args = get_cfg(cfg=DEFAULT_CFG, overrides=overrides)
83
+ args.imgsz = check_imgsz(args.imgsz, max_dim=1)
84
+ validator = NASValidator(args=args)
85
+ validator(model=self.model)
86
+ self.metrics = validator.metrics
87
+ return validator.metrics
88
+
89
+ @smart_inference_mode()
90
+ def export(self, **kwargs):
91
+ """
92
+ Export model.
93
+
94
+ Args:
95
+ **kwargs : Any other args accepted by the predictors. To see all args check 'configuration' section in docs
96
+ """
97
+ overrides = dict(task='detect')
98
+ overrides.update(kwargs)
99
+ overrides['mode'] = 'export'
100
+ args = get_cfg(cfg=DEFAULT_CFG, overrides=overrides)
101
+ args.task = self.task
102
+ if args.imgsz == DEFAULT_CFG.imgsz:
103
+ args.imgsz = self.model.args['imgsz'] # use trained imgsz unless custom value is passed
104
+ if args.batch == DEFAULT_CFG.batch:
105
+ args.batch = 1 # default to 1 if not modified
106
+ return Exporter(overrides=args)(model=self.model)
107
+
108
+ def info(self, detailed=False, verbose=True):
109
+ """
110
+ Logs model info.
111
+
112
+ Args:
113
+ detailed (bool): Show detailed information about model.
114
+ verbose (bool): Controls verbosity.
115
+ """
116
+ return model_info(self.model, detailed=detailed, verbose=verbose, imgsz=640)
117
+
118
+ def __call__(self, source=None, stream=False, **kwargs):
119
+ """Calls the 'predict' function with given arguments to perform object detection."""
120
+ return self.predict(source, stream, **kwargs)
121
+
122
+ def __getattr__(self, attr):
123
+ """Raises error if object has no requested attribute."""
124
+ name = self.__class__.__name__
125
+ raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
@@ -0,0 +1,35 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+
3
+ import torch
4
+
5
+ from ultralytics.yolo.engine.predictor import BasePredictor
6
+ from ultralytics.yolo.engine.results import Results
7
+ from ultralytics.yolo.utils import ops
8
+ from ultralytics.yolo.utils.ops import xyxy2xywh
9
+
10
+
11
+ class NASPredictor(BasePredictor):
12
+
13
+ def postprocess(self, preds_in, img, orig_imgs):
14
+ """Postprocesses predictions and returns a list of Results objects."""
15
+
16
+ # Cat boxes and class scores
17
+ boxes = xyxy2xywh(preds_in[0][0])
18
+ preds = torch.cat((boxes, preds_in[0][1]), -1).permute(0, 2, 1)
19
+
20
+ preds = ops.non_max_suppression(preds,
21
+ self.args.conf,
22
+ self.args.iou,
23
+ agnostic=self.args.agnostic_nms,
24
+ max_det=self.args.max_det,
25
+ classes=self.args.classes)
26
+
27
+ results = []
28
+ for i, pred in enumerate(preds):
29
+ orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs
30
+ if not isinstance(orig_imgs, torch.Tensor):
31
+ pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape)
32
+ path = self.batch[0]
33
+ img_path = path[i] if isinstance(path, list) else path
34
+ results.append(Results(orig_img=orig_img, path=img_path, names=self.model.names, boxes=pred))
35
+ return results
@@ -0,0 +1,25 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+
3
+ import torch
4
+
5
+ from ultralytics.yolo.utils import ops
6
+ from ultralytics.yolo.utils.ops import xyxy2xywh
7
+ from ultralytics.yolo.v8.detect import DetectionValidator
8
+
9
+ __all__ = ['NASValidator']
10
+
11
+
12
+ class NASValidator(DetectionValidator):
13
+
14
+ def postprocess(self, preds_in):
15
+ """Apply Non-maximum suppression to prediction outputs."""
16
+ boxes = xyxy2xywh(preds_in[0][0])
17
+ preds = torch.cat((boxes, preds_in[0][1]), -1).permute(0, 2, 1)
18
+ return ops.non_max_suppression(preds,
19
+ self.args.conf,
20
+ self.args.iou,
21
+ labels=self.lb,
22
+ multi_label=False,
23
+ agnostic=self.args.single_cls,
24
+ max_det=self.args.max_det,
25
+ max_time_img=0.5)
@@ -37,7 +37,7 @@ AUTOINSTALL = str(os.getenv('YOLO_AUTOINSTALL', True)).lower() == 'true' # glob
37
37
  VERBOSE = str(os.getenv('YOLO_VERBOSE', True)).lower() == 'true' # global verbose mode
38
38
  TQDM_BAR_FORMAT = '{l_bar}{bar:10}{r_bar}' # tqdm bar format
39
39
  LOGGING_NAME = 'ultralytics'
40
- MACOS, LINUX, WINDOWS = (platform.system() == x for x in ['Darwin', 'Linux', 'Windows']) # environment booleans
40
+ MACOS, LINUX, WINDOWS = (platform.system() == x for x in {'Darwin', 'Linux', 'Windows'}) # environment booleans
41
41
  HELP_MSG = \
42
42
  """
43
43
  Usage examples for running YOLOv8:
@@ -224,6 +224,11 @@ def set_logging(name=LOGGING_NAME, verbose=True):
224
224
  'propagate': False}}})
225
225
 
226
226
 
227
+ def emojis(string=''):
228
+ """Return platform-dependent emoji-safe version of string."""
229
+ return string.encode().decode('ascii', 'ignore') if WINDOWS else string
230
+
231
+
227
232
  class EmojiFilter(logging.Filter):
228
233
  """
229
234
  A custom logging filter class for removing emojis in log messages.
@@ -533,6 +538,7 @@ def get_user_config_dir(sub_dir='Ultralytics'):
533
538
  # GCP and AWS lambda fix, only /tmp is writeable
534
539
  if not is_dir_writeable(str(path.parent)):
535
540
  path = Path('/tmp') / sub_dir
541
+ LOGGER.warning(f"WARNING ⚠️ user config directory is not writeable, defaulting to '{path}'.")
536
542
 
537
543
  # Create the subdirectory if it does not exist
538
544
  path.mkdir(parents=True, exist_ok=True)
@@ -544,11 +550,6 @@ USER_CONFIG_DIR = Path(os.getenv('YOLO_CONFIG_DIR', get_user_config_dir())) # U
544
550
  SETTINGS_YAML = USER_CONFIG_DIR / 'settings.yaml'
545
551
 
546
552
 
547
- def emojis(string=''):
548
- """Return platform-dependent emoji-safe version of string."""
549
- return string.encode().decode('ascii', 'ignore') if WINDOWS else string
550
-
551
-
552
553
  def colorstr(*input):
553
554
  """Colors a string https://en.wikipedia.org/wiki/ANSI_escape_code, i.e. colorstr('blue', 'hello world')."""
554
555
  *args, string = input if len(input) > 1 else ('blue', 'bold', input[0]) # color arguments, string
@@ -90,7 +90,7 @@ def benchmark(model=Path(SETTINGS['weights_dir']) / 'yolov8n.pt',
90
90
  filename = model.ckpt_path or model.cfg
91
91
  export = model # PyTorch format
92
92
  else:
93
- filename = model.export(imgsz=imgsz, format=format, half=half, int8=int8, device=device) # all others
93
+ filename = model.export(imgsz=imgsz, format=format, half=half, int8=int8, device=device, verbose=False)
94
94
  export = YOLO(filename, task=model.task)
95
95
  assert suffix in str(filename), 'export failed'
96
96
  emoji = '❎' # indicates export succeeded
@@ -196,8 +196,17 @@ class ProfileModels:
196
196
  model.fuse() # to report correct params and GFLOPs in model.info()
197
197
  model_info = model.info()
198
198
  if self.trt and self.device.type != 'cpu' and not engine_file.is_file():
199
- engine_file = model.export(format='engine', half=True, imgsz=self.imgsz, device=self.device)
200
- onnx_file = model.export(format='onnx', half=True, imgsz=self.imgsz, simplify=True, device=self.device)
199
+ engine_file = model.export(format='engine',
200
+ half=True,
201
+ imgsz=self.imgsz,
202
+ device=self.device,
203
+ verbose=False)
204
+ onnx_file = model.export(format='onnx',
205
+ half=True,
206
+ imgsz=self.imgsz,
207
+ simplify=True,
208
+ device=self.device,
209
+ verbose=False)
201
210
  elif file.suffix == '.onnx':
202
211
  model_info = self.get_onnx_model_info(file)
203
212
  onnx_file = file
@@ -254,7 +263,7 @@ class ProfileModels:
254
263
  for _ in range(3):
255
264
  start_time = time.time()
256
265
  for _ in range(self.num_warmup_runs):
257
- model(input_data, verbose=False)
266
+ model(input_data, imgsz=self.imgsz, verbose=False)
258
267
  elapsed = time.time() - start_time
259
268
 
260
269
  # Compute number of runs as higher of min_time or num_timed_runs
@@ -263,7 +272,7 @@ class ProfileModels:
263
272
  # Timed runs
264
273
  run_times = []
265
274
  for _ in tqdm(range(num_runs), desc=engine_file):
266
- results = model(input_data, verbose=False)
275
+ results = model(input_data, imgsz=self.imgsz, verbose=False)
267
276
  run_times.append(results[0].speed['inference']) # Convert to milliseconds
268
277
 
269
278
  run_times = self.iterative_sigma_clipping(np.array(run_times), sigma=2, max_iters=3) # sigma clipping
@@ -1,8 +1,10 @@
1
1
  # Ultralytics YOLO 🚀, GPL-3.0 license
2
2
  import os
3
3
 
4
+ import pkg_resources as pkg
5
+
4
6
  from ultralytics.yolo.utils import LOGGER, TESTS_RUNNING
5
- from ultralytics.yolo.utils.torch_utils import get_flops, get_num_params
7
+ from ultralytics.yolo.utils.torch_utils import model_info_for_loggers
6
8
 
7
9
  try:
8
10
  from importlib.metadata import version
@@ -10,8 +12,12 @@ try:
10
12
  import dvclive
11
13
 
12
14
  assert not TESTS_RUNNING # do not log pytest
13
- assert version('dvclive')
14
- except (ImportError, AssertionError):
15
+
16
+ ver = version('dvclive')
17
+ if pkg.parse_version(ver) < pkg.parse_version('2.11.0'):
18
+ LOGGER.debug(f'DVCLive is detected but version {ver} is incompatible (>=2.11 required).')
19
+ dvclive = None # noqa: F811
20
+ except (ImportError, AssertionError, TypeError):
15
21
  dvclive = None
16
22
 
17
23
  # DVCLive logger instance
@@ -36,7 +42,7 @@ def _log_images(image_path, prefix=''):
36
42
  def _log_plots(plots, prefix=''):
37
43
  for name, params in plots.items():
38
44
  timestamp = params['timestamp']
39
- if _processed_plots.get(name, None) != timestamp:
45
+ if _processed_plots.get(name) != timestamp:
40
46
  _log_images(name, prefix)
41
47
  _processed_plots[name] = timestamp
42
48
 
@@ -94,12 +100,7 @@ def on_fit_epoch_end(trainer):
94
100
  live.log_metric(metric, value)
95
101
 
96
102
  if trainer.epoch == 0:
97
- model_info = {
98
- 'model/parameters': get_num_params(trainer.model),
99
- 'model/GFLOPs': round(get_flops(trainer.model), 3),
100
- 'model/speed(ms)': round(trainer.validator.speed['inference'], 3)}
101
-
102
- for metric, value in model_info.items():
103
+ for metric, value in model_info_for_loggers(trainer).items():
103
104
  live.log_metric(metric, value, plot=False)
104
105
 
105
106
  _log_plots(trainer.plots, 'train')
@@ -93,7 +93,6 @@ def on_train_end(trainer):
93
93
  # Log the final model
94
94
  run[f'weights/{trainer.args.name or trainer.args.task}/{str(trainer.best.name)}'].upload(File(str(
95
95
  trainer.best)))
96
- run.stop()
97
96
 
98
97
 
99
98
  callbacks = {
@@ -19,9 +19,9 @@ import requests
19
19
  import torch
20
20
  from matplotlib import font_manager
21
21
 
22
- from ultralytics.yolo.utils import (AUTOINSTALL, LOGGER, ONLINE, ROOT, USER_CONFIG_DIR, TryExcept, clean_url, colorstr,
23
- downloads, emojis, is_colab, is_docker, is_kaggle, is_online, is_pip_package,
24
- url2file)
22
+ from ultralytics.yolo.utils import (AUTOINSTALL, LOGGER, ONLINE, RANK, ROOT, USER_CONFIG_DIR, TryExcept, clean_url,
23
+ colorstr, downloads, emojis, is_colab, is_docker, is_kaggle, is_online,
24
+ is_pip_package, url2file)
25
25
 
26
26
 
27
27
  def is_ascii(s) -> bool:
@@ -164,23 +164,26 @@ def check_font(font='Arial.ttf'):
164
164
  Returns:
165
165
  file (Path): Resolved font file path.
166
166
  """
167
- name = Path(font).name
168
-
169
- # Check USER_CONFIG_DIR
170
- file = USER_CONFIG_DIR / name
171
- if file.exists():
172
- return file
173
-
174
- # Check system fonts
175
- matches = [s for s in font_manager.findSystemFonts() if font in s]
176
- if any(matches):
177
- return matches[0]
178
-
179
- # Download to USER_CONFIG_DIR if missing
180
- url = f'https://ultralytics.com/assets/{name}'
181
- if downloads.is_url(url):
182
- downloads.safe_download(url=url, file=file)
183
- return file
167
+ from ultralytics.yolo.utils.torch_utils import torch_distributed_zero_first
168
+
169
+ with torch_distributed_zero_first(RANK):
170
+ name = Path(font).name
171
+
172
+ # Check USER_CONFIG_DIR
173
+ file = USER_CONFIG_DIR / name
174
+ if file.exists():
175
+ return file
176
+
177
+ # Check system fonts
178
+ matches = [s for s in font_manager.findSystemFonts() if font in s]
179
+ if any(matches):
180
+ return matches[0]
181
+
182
+ # Download to USER_CONFIG_DIR if missing
183
+ url = f'https://ultralytics.com/assets/{name}'
184
+ if downloads.is_url(url):
185
+ downloads.safe_download(url=url, file=file)
186
+ return file
184
187
 
185
188
 
186
189
  def check_python(minimum: str = '3.7.0') -> bool:
@@ -209,9 +209,10 @@ class Instances:
209
209
  """Convert bounding box format."""
210
210
  self._bboxes.convert(format=format)
211
211
 
212
+ @property
212
213
  def bbox_areas(self):
213
214
  """Calculate the area of bounding boxes."""
214
- self._bboxes.areas()
215
+ return self._bboxes.areas()
215
216
 
216
217
  def scale(self, scale_w, scale_h, bbox_only=False):
217
218
  """this might be similar with denormalize func but without normalized sign."""
@@ -328,9 +329,9 @@ class Instances:
328
329
 
329
330
  def remove_zero_area_boxes(self):
330
331
  """Remove zero-area boxes, i.e. after clipping some boxes may have zero width or height. This removes them."""
331
- good = self._bboxes.areas() > 0
332
+ good = self.bbox_areas > 0
332
333
  if not all(good):
333
- self._bboxes = Bboxes(self._bboxes.bboxes[good], format=self._bboxes.format)
334
+ self._bboxes = self._bboxes[good]
334
335
  if len(self.segments):
335
336
  self.segments = self.segments[good]
336
337
  if self.keypoints is not None:
@@ -64,6 +64,8 @@ def select_device(device='', batch=0, newline=False, verbose=True):
64
64
  if cpu or mps:
65
65
  os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # force torch.cuda.is_available() = False
66
66
  elif device: # non-cpu device requested
67
+ if device == 'cuda':
68
+ device = '0'
67
69
  visible = os.environ.get('CUDA_VISIBLE_DEVICES', None)
68
70
  os.environ['CUDA_VISIBLE_DEVICES'] = device # set environment variable - must be before assert is_available()
69
71
  if not (torch.cuda.is_available() and torch.cuda.device_count() >= len(device.replace(',', ''))):
@@ -223,7 +223,7 @@ class DetectionValidator(BaseValidator):
223
223
  def plot_predictions(self, batch, preds, ni):
224
224
  """Plots predicted bounding boxes on input images and saves the result."""
225
225
  plot_images(batch['img'],
226
- *output_to_target(preds, max_det=15),
226
+ *output_to_target(preds, max_det=self.args.max_det),
227
227
  paths=batch['im_file'],
228
228
  fname=self.save_dir / f'val_batch{ni}_pred.jpg',
229
229
  names=self.names,
@@ -156,7 +156,7 @@ class PoseValidator(DetectionValidator):
156
156
  """Plots predictions for YOLO model."""
157
157
  pred_kpts = torch.cat([p[:, 6:].view(-1, *self.kpt_shape)[:15] for p in preds], 0)
158
158
  plot_images(batch['img'],
159
- *output_to_target(preds, max_det=15),
159
+ *output_to_target(preds, max_det=self.args.max_det),
160
160
  kpts=pred_kpts,
161
161
  paths=batch['im_file'],
162
162
  fname=self.save_dir / f'val_batch{ni}_pred.jpg',
@@ -179,13 +179,14 @@ class SegmentationValidator(DetectionValidator):
179
179
 
180
180
  def plot_predictions(self, batch, preds, ni):
181
181
  """Plots batch predictions with masks and bounding boxes."""
182
- plot_images(batch['img'],
183
- *output_to_target(preds[0], max_det=15),
184
- torch.cat(self.plot_masks, dim=0) if len(self.plot_masks) else self.plot_masks,
185
- paths=batch['im_file'],
186
- fname=self.save_dir / f'val_batch{ni}_pred.jpg',
187
- names=self.names,
188
- on_plot=self.on_plot) # pred
182
+ plot_images(
183
+ batch['img'],
184
+ *output_to_target(preds[0], max_det=15), # not set to self.args.max_det due to slow plotting speed
185
+ torch.cat(self.plot_masks, dim=0) if len(self.plot_masks) else self.plot_masks,
186
+ paths=batch['im_file'],
187
+ fname=self.save_dir / f'val_batch{ni}_pred.jpg',
188
+ names=self.names,
189
+ on_plot=self.on_plot) # pred
189
190
  self.plot_masks.clear()
190
191
 
191
192
  def pred_to_json(self, predn, filename, pred_masks):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ultralytics
3
- Version: 8.0.114
3
+ Version: 8.0.116
4
4
  Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
5
5
  Home-page: https://github.com/ultralytics/ultralytics
6
6
  Author: Ultralytics
@@ -161,9 +161,11 @@ path = model.export(format="onnx") # export the model to ONNX format
161
161
 
162
162
  ## <div align="center">Models</div>
163
163
 
164
- All YOLOv8 pretrained models are available here. Detect, Segment and Pose models are pretrained on the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify models are pretrained on the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset.
164
+ YOLOv8 [Detect](https://docs.ultralytics.com/tasks/detect), [Segment](https://docs.ultralytics.com/tasks/segment) and [Pose](https://docs.ultralytics.com/tasks/pose) models pretrained on the [COCO](https://docs.ultralytics.com/datasets/detect/coco) dataset are available here, as well as YOLOv8 [Classify](https://docs.ultralytics.com/modes/classify) models pretrained on the [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet) dataset. [Track](https://docs.ultralytics.com/modes/track) mode is available for all Detect, Segment and Pose models.
165
165
 
166
- [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use.
166
+ <img width="1024" src="https://raw.githubusercontent.com/ultralytics/assets/tasks/im/banner-tasks.png">
167
+
168
+ All [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use.
167
169
 
168
170
  <details open><summary>Detection</summary>
169
171
 
@@ -1,4 +1,4 @@
1
- ultralytics/__init__.py,sha256=-5ruX60HT01AHs6Qv3SuMvZDh8fTz0Ln4eYxVQMy0Ck,383
1
+ ultralytics/__init__.py,sha256=kGXynKiWGuj7CVtgwKm1YG31e0E0Ppqx104S-9rSBgk,427
2
2
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
3
3
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
4
4
  ultralytics/datasets/Argoverse.yaml,sha256=Q6hKRtI52JOYt4qmjkeo192mmgSkuCdOnfiUTxtBy5A,2751
@@ -59,14 +59,14 @@ ultralytics/tracker/utils/kalman_filter.py,sha256=gMc4gDKo_dkMiL-Zkt-U7mTxjK_z4A
59
59
  ultralytics/tracker/utils/matching.py,sha256=O_wJb-6ZuucIl2TuLsVe7QmqqxUNP8aoCjaWxnhk_Xg,8699
60
60
  ultralytics/vit/__init__.py,sha256=_lrglMOLuopqBVEAwGFnM8Huc6SJAHcysuGc0dmA8l0,149
61
61
  ultralytics/vit/rtdetr/__init__.py,sha256=1Zpc6ZcizFO0EMhP8X4m3DG27vDBX4aM4RX0rMSeo6E,197
62
- ultralytics/vit/rtdetr/model.py,sha256=1LdCA9IP6GKMA-U3L1amlwMvIQYw8vy042dbO9M8jk4,4610
62
+ ultralytics/vit/rtdetr/model.py,sha256=CVtRbvCTQLFmG5d2CCFfVdnWrv9ClL8vaw4_BPtDrBs,5077
63
63
  ultralytics/vit/rtdetr/predict.py,sha256=zYV0c5lWr79h_J8kBhcFPB5wcDOyGdgR1qr_Z_l6Rj4,1902
64
64
  ultralytics/vit/rtdetr/val.py,sha256=6ERi9xIFOEkoEvWuy9DuOc5u1OaI2jm2Jag9l9zesvw,4790
65
65
  ultralytics/vit/sam/__init__.py,sha256=qAi91Krwqwsu2jruHiJgLabEkWo9yeZ5gDIHIKzX-PE,130
66
66
  ultralytics/vit/sam/amg.py,sha256=tzpbVPiyIwENW0xgtdy08kVGgn69zOk4VGjHmEFTCeE,13304
67
67
  ultralytics/vit/sam/autosize.py,sha256=3lym72tdiJFvbyIOMzxUzumqx82PY3lYEB3ctWNgM4s,3878
68
68
  ultralytics/vit/sam/build.py,sha256=Cp0LhlNcjLl-2OA_06eaeYlA3lK3N0KqUfhmZJ7A8Hw,3781
69
- ultralytics/vit/sam/model.py,sha256=ynJtuLhvhva4-69o2TDtTk7viIuOpJpVGr-u-Rf5D6E,1807
69
+ ultralytics/vit/sam/model.py,sha256=kS-zpGw8wXKkU0yWCH-uGvmMFWB_AnEAa6NMVdsUDEA,2274
70
70
  ultralytics/vit/sam/predict.py,sha256=RcC3uLs3RiqWeW7UxdyjK6LcmqysFqRRfz3f-pV_mPQ,2139
71
71
  ultralytics/vit/sam/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
72
  ultralytics/vit/sam/modules/decoders.py,sha256=MJhFLPA7broz2oiYI5tUi3ROWgPxNshhKFXKUP4CEPc,6351
@@ -86,43 +86,47 @@ ultralytics/yolo/data/build.py,sha256=9eVmHXp79QpTLVB-sbaZSM6Qaet9YbiiiTW4TviAGE
86
86
  ultralytics/yolo/data/converter.py,sha256=D-O9eOcO1qg7ultRv2xLAQR39JjVIUkR--g05zquQDA,9190
87
87
  ultralytics/yolo/data/dataset.py,sha256=jmbIpgMaWhQtLfWC4hP8LBaBG2wpFGpxXDg0478FF58,13372
88
88
  ultralytics/yolo/data/dataset_wrappers.py,sha256=a5uwWLhWDRCG5VFto6I3zknxaElxnrcOHiuTAKmmmYg,1776
89
- ultralytics/yolo/data/utils.py,sha256=aBAp1jBzLOPwxGrelDqCi0J2kl3T1CuzpzwRJlzAviU,24050
89
+ ultralytics/yolo/data/utils.py,sha256=nqo_SJNnlBANLEOzvmJGFxz_Ai0OvAQe-CEmMCgDUBo,24056
90
90
  ultralytics/yolo/data/dataloaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
91
  ultralytics/yolo/data/dataloaders/stream_loaders.py,sha256=0bg7lPloNLml7zO9Qe-fz4Cw7VbbSZjrEUbBe-lfpzc,14905
92
92
  ultralytics/yolo/data/dataloaders/v5augmentations.py,sha256=t39RSuHCDCX4MV9EkIoJWaPOjkYlNbbpi-30fg725rw,17646
93
93
  ultralytics/yolo/data/dataloaders/v5loader.py,sha256=RoBWZljfI7Zme_gqF6nq6-2WkMOF7MuL-YCYUpk0bAU,51260
94
94
  ultralytics/yolo/engine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
95
  ultralytics/yolo/engine/exporter.py,sha256=Cq54zAtkL7Qs7Z4RPoDqi0BNG8-sm43sVpeFWm0R_0E,40922
96
- ultralytics/yolo/engine/model.py,sha256=e0wfnPLq6pdlrOSZ-WS0nrD5r62hgiojI3IIvSGnqSc,22061
96
+ ultralytics/yolo/engine/model.py,sha256=OLzx4v7nijKDUcRrt4iQhkZgSw766LmVG2TUHyWT8jE,22144
97
97
  ultralytics/yolo/engine/predictor.py,sha256=j1F6f6AHs-LNBta4IG45VyLXEs78UaYpjoIE5rco8EM,16204
98
98
  ultralytics/yolo/engine/results.py,sha256=KNiXW_xkSN8qJJl7gqQKCz_6zjU0nyBHKqD3yoIf-2E,24287
99
99
  ultralytics/yolo/engine/trainer.py,sha256=Xie6mlF-jCESk-3tMLMf1nY8bI8_-9Owgg2EAQPfMLI,31199
100
100
  ultralytics/yolo/engine/validator.py,sha256=ZbOde8CClZQgTFXJ68v4DP_etR1prJYrwMayyKUcfTk,11715
101
- ultralytics/yolo/utils/__init__.py,sha256=8XWq2-gOpwnmm5PMkXjlfZVZu1pJLOemyQGS0_VGUdY,27849
101
+ ultralytics/yolo/nas/__init__.py,sha256=O7qvgqJqoLB1NXwjTNHMJHJRhDwNHS2P_oyUV_b1qq8,179
102
+ ultralytics/yolo/nas/model.py,sha256=LU0NaoZjcJEDvKQetavJ7YmVzn-kGO-IJDDw8vKz-S4,4977
103
+ ultralytics/yolo/nas/predict.py,sha256=WbO9fxO2o_WA3nM7KkgHDgr2eJWdYsT725BcJ6_Qtrs,1465
104
+ ultralytics/yolo/nas/val.py,sha256=D9jIFcafuD768X5l9Q56hrXIz-Jl45uEReIsPyrlNgs,953
105
+ ultralytics/yolo/utils/__init__.py,sha256=OJ0x67npaXsLYD5TzKmlMZ-n74Jq0hG43fHglT8SMkE,27955
102
106
  ultralytics/yolo/utils/autobatch.py,sha256=-8eEMRN9KyX9nslL5XAC2gMTFAH5YFA33q6nnQDj1qU,3846
103
- ultralytics/yolo/utils/benchmarks.py,sha256=M2bC3dVTDyBpWMVz4FMTAI9iREp2bvTZBHc7Jre3-3U,15428
104
- ultralytics/yolo/utils/checks.py,sha256=dgD4pO_epK8eUN9LQB_n5cPYDY2azxh3Gj2cWzF10GI,17380
107
+ ultralytics/yolo/utils/benchmarks.py,sha256=lFdnVqrXlI2n8JC-B1UgW2zip-Tsii7HjrJrCQmDV-g,15888
108
+ ultralytics/yolo/utils/checks.py,sha256=3kLYaCCuZpGNKaX9RYDEHfiPgKD-Sc3Ep5kmR-LBQFI,17568
105
109
  ultralytics/yolo/utils/dist.py,sha256=qavAVcOeyLV0z31Spo1G9batXljnYzp1NN8YWFoBTxk,2596
106
110
  ultralytics/yolo/utils/downloads.py,sha256=w_Pnw_0_s6rNno54J1-qIm8Zy_I0jr7B9fSdD-TwX8g,12114
107
111
  ultralytics/yolo/utils/errors.py,sha256=u8NUGZbWVrr4O3ez6UXnabNb_zRwJUPJqDOUSpmX3-k,317
108
112
  ultralytics/yolo/utils/files.py,sha256=7431UxyB9-D2vhkp8JqO_IXApYoWsWfSH3H5JNemKjU,3588
109
- ultralytics/yolo/utils/instance.py,sha256=Eul_ZaDyCCUzllLype5hlfO0r9vuerl8rI5OGRbnne4,14661
113
+ ultralytics/yolo/utils/instance.py,sha256=7pVtdcSR4tfPffhFXaNtZiW2lOYMawtVdSoqz8XU5LQ,14634
110
114
  ultralytics/yolo/utils/loss.py,sha256=iP1YPMRGsHYjIr7jGFdHxhMAgX7ou9V0HE4o7foRVrk,18090
111
115
  ultralytics/yolo/utils/metrics.py,sha256=mPTMcW4vyfzmh8gvdcStuHkMd3AADML3m_crLaal1I4,43799
112
116
  ultralytics/yolo/utils/ops.py,sha256=ne7GC7hOuAS3Lnk7eDx5w8LOMtbb_l7nJcb0wpBVJRQ,28273
113
117
  ultralytics/yolo/utils/patches.py,sha256=lxG_qZlTxiCcKWrVFtvSVA8WULRa483fOJ4ffYyGQ50,1241
114
118
  ultralytics/yolo/utils/plotting.py,sha256=ScX-_AasukwuQpOT8q18YMSKMwJBDKFM8q1o8oY8MqE,24431
115
119
  ultralytics/yolo/utils/tal.py,sha256=BFovrLm0m5_Pv-hFzYMAD3oonS1MvDqdy51f_Cx6Aq8,13645
116
- ultralytics/yolo/utils/torch_utils.py,sha256=S2emgg-VTZZ0pV2YE6VMxaUgaVpA7HVdO_U2RLtvJos,22177
120
+ ultralytics/yolo/utils/torch_utils.py,sha256=mpAdku7PNYFLOFcijSWA3poZ6ShIShOlEHlqvBDzJp4,22231
117
121
  ultralytics/yolo/utils/tuner.py,sha256=yq3nYsnug2LC-iJJwLlXrQwJJT2VanujFFKnY-06CBQ,2300
118
122
  ultralytics/yolo/utils/callbacks/__init__.py,sha256=nhrnMPpPDb5fgqw42w8e7fC5TjEPC-jp04dpQtaQtkU,214
119
123
  ultralytics/yolo/utils/callbacks/base.py,sha256=VpiMIW9qiyncMq9cLRmm5WGr38On0LVTK2XNDmliEbE,5593
120
124
  ultralytics/yolo/utils/callbacks/clearml.py,sha256=VYtuNTlB8M5rIFQupm53uhDEXe8qZrrOjXXHTI0bIUw,5902
121
125
  ultralytics/yolo/utils/callbacks/comet.py,sha256=_Dm-Qbeyi36nSSETsoiObG52gceLw6RE2TodEYW7sUY,12978
122
- ultralytics/yolo/utils/callbacks/dvc.py,sha256=JUjAIQ0SJvAPSbiKwnDiaG7IEEqCy-Nvbtvm0Q-kCWo,4299
126
+ ultralytics/yolo/utils/callbacks/dvc.py,sha256=7xNhDoTQqapOULEVrwxluZGOdKZVK74EPLFu4Rm47Tw,4301
123
127
  ultralytics/yolo/utils/callbacks/hub.py,sha256=Z-F48IcG2PtlJo3mnzp31YdXrS8nyMn6004-Ke6NLyM,3310
124
128
  ultralytics/yolo/utils/callbacks/mlflow.py,sha256=fCp4zNefamIzqZpOkoG2UqKVkeuIX41_em2Uw33iasY,2493
125
- ultralytics/yolo/utils/callbacks/neptune.py,sha256=FO-E5v7udasGkOg8Mg-cNVRKJkZW-1WLfqP_nP4UYvY,3698
129
+ ultralytics/yolo/utils/callbacks/neptune.py,sha256=lBvXuXkgHfiDkdeRAM7TbK7xQBSAKxYQQAwHt7SMNi8,3679
126
130
  ultralytics/yolo/utils/callbacks/raytune.py,sha256=wHdhqCDtK1GbDQTixpxJPzS8NWtEkXpkdIlhQmEZdHg,495
127
131
  ultralytics/yolo/utils/callbacks/tensorboard.py,sha256=05UPBY4sBzh2FaQmWgav0sFgoLlhLqJg-5gfSz7AYpY,1525
128
132
  ultralytics/yolo/utils/callbacks/wb.py,sha256=LfDZhxZyWigN20LWWuG9NEStp55HwBHY7VpXYyb1sm4,2170
@@ -134,18 +138,18 @@ ultralytics/yolo/v8/classify/val.py,sha256=b8VJuuAUDbOwTmg5IEcn_NqTFJ5BCubc9FGdY
134
138
  ultralytics/yolo/v8/detect/__init__.py,sha256=1w44OZNPKQOlDIbxRqFDULl7RphH8KAT6cJawNY2uKU,277
135
139
  ultralytics/yolo/v8/detect/predict.py,sha256=BbsRQpswiBvF88uWuOfwNguRbyXIJO7HZ7WYBblcCvY,1854
136
140
  ultralytics/yolo/v8/detect/train.py,sha256=uorDhWqt1GMjUnc3m4xamnEDROHGWcty3cJFUANbpok,7199
137
- ultralytics/yolo/v8/detect/val.py,sha256=5_tUnvLJeP75M-ofzZfsuYzoCiIQBi4Ta8GEwQXNr4s,14715
141
+ ultralytics/yolo/v8/detect/val.py,sha256=uZGSs7Vgq8UGEgz-oMsVSYarfKz_czW0AS1S1FJvdns,14730
138
142
  ultralytics/yolo/v8/pose/__init__.py,sha256=V9epZgW3BaNv6zouhdeX_MMwWqmzPl6V8F8uBIfsfEE,247
139
143
  ultralytics/yolo/v8/pose/predict.py,sha256=0XTJWgxYZMzNyKHgswQFMSnzHYcfJbbrIQ7eysyCPtI,2375
140
144
  ultralytics/yolo/v8/pose/train.py,sha256=lfim51E8qvUmcuxa-fGVw8nPOr6Z6Nisv5AXLm6qVz8,2790
141
- ultralytics/yolo/v8/pose/val.py,sha256=C7YUht88_OB1fzO7GsQkkSjRem0oEL4IFeaq8uI2Ww0,10917
145
+ ultralytics/yolo/v8/pose/val.py,sha256=v_pyWKhIZWowNzt4ACzdtyJJaRHXMT7rpzhODXVGtlQ,10932
142
146
  ultralytics/yolo/v8/segment/__init__.py,sha256=TOdf3ju-D5hSi-PYMpETFmv-wyhIRKGujdoeGDx7hbs,295
143
147
  ultralytics/yolo/v8/segment/predict.py,sha256=QSwXjC7sq7l7kT0W1UrwGZrUXNqkveRGRIsRnlQlWYM,2839
144
148
  ultralytics/yolo/v8/segment/train.py,sha256=Ag0uHlJp297dljtECqZ5VVfnWj7m86oD1Dy1_s4vIEs,2499
145
- ultralytics/yolo/v8/segment/val.py,sha256=P73flBisvAHh5SRYXes1DzrHGxsOzN2OELV4V1veP8M,12882
146
- ultralytics-8.0.114.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
147
- ultralytics-8.0.114.dist-info/METADATA,sha256=lzNVo3huNDUQIJiTPTSgpT5FLD5MN9cb3NTCHh0BF9Q,26843
148
- ultralytics-8.0.114.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
149
- ultralytics-8.0.114.dist-info/entry_points.txt,sha256=Ck1F6qKNokeHozQD5pmaFgXHL6dKyC2qCdyXao2e6Yg,103
150
- ultralytics-8.0.114.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
151
- ultralytics-8.0.114.dist-info/RECORD,,
149
+ ultralytics/yolo/v8/segment/val.py,sha256=R3D_itui1lU0iXC1aqmZvmwGX77oJt--bQ7MhTErsBY,12906
150
+ ultralytics-8.0.116.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
151
+ ultralytics-8.0.116.dist-info/METADATA,sha256=fhzEqGcUjDMa-o-bqGrtVJHMhLse8F6-KqsHmd5r9Ug,27157
152
+ ultralytics-8.0.116.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
153
+ ultralytics-8.0.116.dist-info/entry_points.txt,sha256=Ck1F6qKNokeHozQD5pmaFgXHL6dKyC2qCdyXao2e6Yg,103
154
+ ultralytics-8.0.116.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
155
+ ultralytics-8.0.116.dist-info/RECORD,,