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

Files changed (38) hide show
  1. ultralytics/__init__.py +1 -1
  2. ultralytics/cfg/__init__.py +3 -2
  3. ultralytics/cfg/datasets/carparts-seg.yaml +43 -0
  4. ultralytics/cfg/datasets/crack-seg.yaml +21 -0
  5. ultralytics/cfg/datasets/package-seg.yaml +21 -0
  6. ultralytics/data/build.py +5 -6
  7. ultralytics/data/converter.py +2 -0
  8. ultralytics/data/dataset.py +9 -4
  9. ultralytics/data/explorer/explorer.py +5 -2
  10. ultralytics/data/explorer/gui/dash.py +23 -3
  11. ultralytics/data/loaders.py +4 -12
  12. ultralytics/engine/model.py +2 -2
  13. ultralytics/engine/predictor.py +1 -1
  14. ultralytics/engine/results.py +5 -2
  15. ultralytics/engine/trainer.py +6 -2
  16. ultralytics/hub/__init__.py +6 -3
  17. ultralytics/hub/auth.py +2 -2
  18. ultralytics/hub/session.py +2 -2
  19. ultralytics/models/sam/amg.py +4 -2
  20. ultralytics/models/yolo/segment/val.py +6 -2
  21. ultralytics/nn/autobackend.py +6 -6
  22. ultralytics/solutions/distance_calculation.py +5 -17
  23. ultralytics/solutions/object_counter.py +0 -1
  24. ultralytics/utils/__init__.py +78 -7
  25. ultralytics/utils/benchmarks.py +7 -4
  26. ultralytics/utils/checks.py +2 -2
  27. ultralytics/utils/loss.py +7 -2
  28. ultralytics/utils/metrics.py +1 -1
  29. ultralytics/utils/ops.py +4 -5
  30. ultralytics/utils/plotting.py +46 -0
  31. ultralytics/utils/triton.py +1 -1
  32. ultralytics/utils/tuner.py +1 -1
  33. {ultralytics-8.1.5.dist-info → ultralytics-8.1.7.dist-info}/METADATA +2 -2
  34. {ultralytics-8.1.5.dist-info → ultralytics-8.1.7.dist-info}/RECORD +38 -35
  35. {ultralytics-8.1.5.dist-info → ultralytics-8.1.7.dist-info}/LICENSE +0 -0
  36. {ultralytics-8.1.5.dist-info → ultralytics-8.1.7.dist-info}/WHEEL +0 -0
  37. {ultralytics-8.1.5.dist-info → ultralytics-8.1.7.dist-info}/entry_points.txt +0 -0
  38. {ultralytics-8.1.5.dist-info → ultralytics-8.1.7.dist-info}/top_level.txt +0 -0
ultralytics/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- __version__ = "8.1.5"
3
+ __version__ = "8.1.7"
4
4
 
5
5
  from ultralytics.data.explorer.explorer import Explorer
6
6
  from ultralytics.models import RTDETR, SAM, YOLO
@@ -51,7 +51,7 @@ TASK2METRIC = {
51
51
  "segment": "metrics/mAP50-95(M)",
52
52
  "classify": "metrics/accuracy_top1",
53
53
  "pose": "metrics/mAP50-95(P)",
54
- "obb": "metrics/mAP50-95(OBB)",
54
+ "obb": "metrics/mAP50-95(B)",
55
55
  }
56
56
 
57
57
  CLI_HELP_MSG = f"""
@@ -317,7 +317,7 @@ def merge_equals_args(args: List[str]) -> List[str]:
317
317
  args (List[str]): A list of strings where each element is an argument.
318
318
 
319
319
  Returns:
320
- List[str]: A list of strings where the arguments around isolated '=' are merged.
320
+ (List[str]): A list of strings where the arguments around isolated '=' are merged.
321
321
  """
322
322
  new_args = []
323
323
  for i, arg in enumerate(args):
@@ -396,6 +396,7 @@ def handle_yolo_settings(args: List[str]) -> None:
396
396
  def handle_explorer():
397
397
  """Open the Ultralytics Explorer GUI."""
398
398
  checks.check_requirements("streamlit")
399
+ LOGGER.info(f"💡 Loading Explorer dashboard...")
399
400
  subprocess.run(["streamlit", "run", ROOT / "data/explorer/gui/dash.py", "--server.maxMessageSize", "2048"])
400
401
 
401
402
 
@@ -0,0 +1,43 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+ # Carparts-seg dataset by Ultralytics
3
+ # Documentation: https://docs.ultralytics.com/datasets/segment/carparts-seg/
4
+ # Example usage: yolo train data=carparts-seg.yaml
5
+ # parent
6
+ # ├── ultralytics
7
+ # └── datasets
8
+ # └── carparts-seg ← downloads here (132 MB)
9
+
10
+ # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
11
+ path: ../datasets/carparts-seg # dataset root dir
12
+ train: train/images # train images (relative to 'path') 3516 images
13
+ val: valid/images # val images (relative to 'path') 276 images
14
+ test: test/images # test images (relative to 'path') 401 images
15
+
16
+ # Classes
17
+ names:
18
+ 0: back_bumper
19
+ 1: back_door
20
+ 2: back_glass
21
+ 3: back_left_door
22
+ 4: back_left_light
23
+ 5: back_light
24
+ 6: back_right_door
25
+ 7: back_right_light
26
+ 8: front_bumper
27
+ 9: front_door
28
+ 10: front_glass
29
+ 11: front_left_door
30
+ 12: front_left_light
31
+ 13: front_light
32
+ 14: front_right_door
33
+ 15: front_right_light
34
+ 16: hood
35
+ 17: left_mirror
36
+ 18: object
37
+ 19: right_mirror
38
+ 20: tailgate
39
+ 21: trunk
40
+ 22: wheel
41
+
42
+ # Download script/URL (optional)
43
+ download: https://ultralytics.com/assets/carparts-seg.zip
@@ -0,0 +1,21 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+ # Crack-seg dataset by Ultralytics
3
+ # Documentation: https://docs.ultralytics.com/datasets/segment/crack-seg/
4
+ # Example usage: yolo train data=crack-seg.yaml
5
+ # parent
6
+ # ├── ultralytics
7
+ # └── datasets
8
+ # └── crack-seg ← downloads here (91.2 MB)
9
+
10
+ # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
11
+ path: ../datasets/crack-seg # dataset root dir
12
+ train: train/images # train images (relative to 'path') 3717 images
13
+ val: valid/images # val images (relative to 'path') 112 images
14
+ test: test/images # test images (relative to 'path') 200 images
15
+
16
+ # Classes
17
+ names:
18
+ 0: crack
19
+
20
+ # Download script/URL (optional)
21
+ download: https://ultralytics.com/assets/crack-seg.zip
@@ -0,0 +1,21 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+ # Package-seg dataset by Ultralytics
3
+ # Documentation: https://docs.ultralytics.com/datasets/segment/package-seg/
4
+ # Example usage: yolo train data=package-seg.yaml
5
+ # parent
6
+ # ├── ultralytics
7
+ # └── datasets
8
+ # └── package-seg ← downloads here (102 MB)
9
+
10
+ # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
11
+ path: ../datasets/package-seg # dataset root dir
12
+ train: images/train # train images (relative to 'path') 1920 images
13
+ val: images/val # val images (relative to 'path') 89 images
14
+ test: test/images # test images (relative to 'path') 188 images
15
+
16
+ # Classes
17
+ names:
18
+ 0: package
19
+
20
+ # Download script/URL (optional)
21
+ download: https://ultralytics.com/assets/package-seg.zip
ultralytics/data/build.py CHANGED
@@ -150,13 +150,12 @@ def check_source(source):
150
150
  return source, webcam, screenshot, from_img, in_memory, tensor
151
151
 
152
152
 
153
- def load_inference_source(source=None, imgsz=640, vid_stride=1, buffer=False):
153
+ def load_inference_source(source=None, vid_stride=1, buffer=False):
154
154
  """
155
155
  Loads an inference source for object detection and applies necessary transformations.
156
156
 
157
157
  Args:
158
158
  source (str, Path, Tensor, PIL.Image, np.ndarray): The input source for inference.
159
- imgsz (int, optional): The size of the image for inference. Default is 640.
160
159
  vid_stride (int, optional): The frame interval for video sources. Default is 1.
161
160
  buffer (bool, optional): Determined whether stream frames will be buffered. Default is False.
162
161
 
@@ -172,13 +171,13 @@ def load_inference_source(source=None, imgsz=640, vid_stride=1, buffer=False):
172
171
  elif in_memory:
173
172
  dataset = source
174
173
  elif webcam:
175
- dataset = LoadStreams(source, imgsz=imgsz, vid_stride=vid_stride, buffer=buffer)
174
+ dataset = LoadStreams(source, vid_stride=vid_stride, buffer=buffer)
176
175
  elif screenshot:
177
- dataset = LoadScreenshots(source, imgsz=imgsz)
176
+ dataset = LoadScreenshots(source)
178
177
  elif from_img:
179
- dataset = LoadPilAndNumpy(source, imgsz=imgsz)
178
+ dataset = LoadPilAndNumpy(source)
180
179
  else:
181
- dataset = LoadImages(source, imgsz=imgsz, vid_stride=vid_stride)
180
+ dataset = LoadImages(source, vid_stride=vid_stride)
182
181
 
183
182
  # Attach source types to the dataset
184
183
  setattr(dataset, "source_type", source_type)
@@ -515,6 +515,8 @@ def yolo_bbox2segment(im_dir, save_dir=None, sam_model="sam_b.pt"):
515
515
  for l in tqdm(dataset.labels, total=len(dataset.labels), desc="Generating segment labels"):
516
516
  h, w = l["shape"]
517
517
  boxes = l["bboxes"]
518
+ if len(boxes) == 0: # skip empty labels
519
+ continue
518
520
  boxes[:, [0, 2]] *= w
519
521
  boxes[:, [1, 3]] *= h
520
522
  im = cv2.imread(l["im_file"])
@@ -46,7 +46,8 @@ class YOLODataset(BaseDataset):
46
46
  Cache dataset labels, check images and read shapes.
47
47
 
48
48
  Args:
49
- path (Path): path where to save the cache file (default: Path('./labels.cache')).
49
+ path (Path): Path where to save the cache file. Default is Path('./labels.cache').
50
+
50
51
  Returns:
51
52
  (dict): labels.
52
53
  """
@@ -178,9 +179,13 @@ class YOLODataset(BaseDataset):
178
179
  self.transforms = self.build_transforms(hyp)
179
180
 
180
181
  def update_labels_info(self, label):
181
- """Custom your label format here."""
182
- # NOTE: cls is not with bboxes now, classification and semantic segmentation need an independent cls label
183
- # We can make it also support classification and semantic segmentation by add or remove some dict keys there.
182
+ """
183
+ Custom your label format here.
184
+
185
+ Note:
186
+ cls is not with bboxes now, classification and semantic segmentation need an independent cls label
187
+ Can also support classification and semantic segmentation by adding or removing dict keys there.
188
+ """
184
189
  bboxes = label.pop("bboxes")
185
190
  segments = label.pop("segments", [])
186
191
  keypoints = label.pop("keypoints", None)
@@ -16,7 +16,7 @@ from ultralytics.data.augment import Format
16
16
  from ultralytics.data.dataset import YOLODataset
17
17
  from ultralytics.data.utils import check_det_dataset
18
18
  from ultralytics.models.yolo.model import YOLO
19
- from ultralytics.utils import LOGGER, IterableSimpleNamespace, checks
19
+ from ultralytics.utils import LOGGER, IterableSimpleNamespace, checks, USER_CONFIG_DIR
20
20
  from .utils import get_sim_index_schema, get_table_schema, plot_query_result, prompt_sql_query, sanitize_batch
21
21
 
22
22
 
@@ -54,7 +54,10 @@ class ExplorerDataset(YOLODataset):
54
54
 
55
55
  class Explorer:
56
56
  def __init__(
57
- self, data: Union[str, Path] = "coco128.yaml", model: str = "yolov8n.pt", uri: str = "~/ultralytics/explorer"
57
+ self,
58
+ data: Union[str, Path] = "coco128.yaml",
59
+ model: str = "yolov8n.pt",
60
+ uri: str = USER_CONFIG_DIR / "explorer",
58
61
  ) -> None:
59
62
  checks.check_requirements(["lancedb>=0.4.3", "duckdb"])
60
63
  import lancedb
@@ -9,7 +9,7 @@ from ultralytics import Explorer
9
9
  from ultralytics.utils import ROOT, SETTINGS
10
10
  from ultralytics.utils.checks import check_requirements
11
11
 
12
- check_requirements(("streamlit>=1.29.0", "streamlit-select>=0.2"))
12
+ check_requirements(("streamlit>=1.29.0", "streamlit-select>=0.3"))
13
13
 
14
14
  import streamlit as st
15
15
  from streamlit_select import image_select
@@ -94,6 +94,7 @@ def find_similar_imgs(imgs):
94
94
  similar = exp.get_similar(img=imgs, limit=st.session_state.get("limit"), return_type="arrow")
95
95
  paths = similar.to_pydict()["im_file"]
96
96
  st.session_state["imgs"] = paths
97
+ st.session_state["res"] = similar
97
98
 
98
99
 
99
100
  def similarity_form(selected_imgs):
@@ -137,6 +138,7 @@ def run_sql_query():
137
138
  exp = st.session_state["explorer"]
138
139
  res = exp.sql_query(query, return_type="arrow")
139
140
  st.session_state["imgs"] = res.to_pydict()["im_file"]
141
+ st.session_state["res"] = res
140
142
 
141
143
 
142
144
  def run_ai_query():
@@ -155,6 +157,7 @@ def run_ai_query():
155
157
  st.session_state["error"] = "No results found using AI generated query. Try another query or rerun it."
156
158
  return
157
159
  st.session_state["imgs"] = res["im_file"].to_list()
160
+ st.session_state["res"] = res
158
161
 
159
162
 
160
163
  def reset_explorer():
@@ -195,7 +198,11 @@ def layout():
195
198
  if st.session_state.get("error"):
196
199
  st.error(st.session_state["error"])
197
200
  else:
198
- imgs = st.session_state.get("imgs") or exp.table.to_lance().to_table(columns=["im_file"]).to_pydict()["im_file"]
201
+ if st.session_state.get("imgs"):
202
+ imgs = st.session_state.get("imgs")
203
+ else:
204
+ imgs = exp.table.to_lance().to_table(columns=["im_file"]).to_pydict()["im_file"]
205
+ st.session_state["res"] = exp.table.to_arrow()
199
206
  total_imgs, selected_imgs = len(imgs), []
200
207
  with col1:
201
208
  subcol1, subcol2, subcol3, subcol4, subcol5 = st.columns(5)
@@ -230,17 +237,30 @@ def layout():
230
237
  query_form()
231
238
  ai_query_form()
232
239
  if total_imgs:
240
+ labels, boxes, masks, kpts, classes = None, None, None, None, None
241
+ task = exp.model.task
242
+ if st.session_state.get("display_labels"):
243
+ labels = st.session_state.get("res").to_pydict()["labels"][start_idx : start_idx + num]
244
+ boxes = st.session_state.get("res").to_pydict()["bboxes"][start_idx : start_idx + num]
245
+ masks = st.session_state.get("res").to_pydict()["masks"][start_idx : start_idx + num]
246
+ kpts = st.session_state.get("res").to_pydict()["keypoints"][start_idx : start_idx + num]
247
+ classes = st.session_state.get("res").to_pydict()["cls"][start_idx : start_idx + num]
233
248
  imgs_displayed = imgs[start_idx : start_idx + num]
234
249
  selected_imgs = image_select(
235
250
  f"Total samples: {total_imgs}",
236
251
  images=imgs_displayed,
237
252
  use_container_width=False,
238
253
  # indices=[i for i in range(num)] if select_all else None,
254
+ labels=labels,
255
+ classes=classes,
256
+ bboxes=boxes,
257
+ masks=masks if task == "segment" else None,
258
+ kpts=kpts if task == "pose" else None,
239
259
  )
240
260
 
241
261
  with col2:
242
262
  similarity_form(selected_imgs)
243
- # display_labels = st.checkbox("Labels", value=False, key="display_labels")
263
+ display_labels = st.checkbox("Labels", value=False, key="display_labels")
244
264
  utralytics_explorer_docs_callback()
245
265
 
246
266
 
@@ -38,7 +38,6 @@ class LoadStreams:
38
38
 
39
39
  Attributes:
40
40
  sources (str): The source input paths or URLs for the video streams.
41
- imgsz (int): The image size for processing, defaults to 640.
42
41
  vid_stride (int): Video frame-rate stride, defaults to 1.
43
42
  buffer (bool): Whether to buffer input streams, defaults to False.
44
43
  running (bool): Flag to indicate if the streaming thread is running.
@@ -60,13 +59,12 @@ class LoadStreams:
60
59
  __len__: Return the length of the sources object.
61
60
  """
62
61
 
63
- def __init__(self, sources="file.streams", imgsz=640, vid_stride=1, buffer=False):
62
+ def __init__(self, sources="file.streams", vid_stride=1, buffer=False):
64
63
  """Initialize instance variables and check for consistent input stream shapes."""
65
64
  torch.backends.cudnn.benchmark = True # faster for fixed-size inference
66
65
  self.buffer = buffer # buffer input streams
67
66
  self.running = True # running flag for Thread
68
67
  self.mode = "stream"
69
- self.imgsz = imgsz
70
68
  self.vid_stride = vid_stride # video frame-rate stride
71
69
 
72
70
  sources = Path(sources).read_text().rsplit() if os.path.isfile(sources) else [sources]
@@ -193,7 +191,6 @@ class LoadScreenshots:
193
191
 
194
192
  Attributes:
195
193
  source (str): The source input indicating which screen to capture.
196
- imgsz (int): The image size for processing, defaults to 640.
197
194
  screen (int): The screen number to capture.
198
195
  left (int): The left coordinate for screen capture area.
199
196
  top (int): The top coordinate for screen capture area.
@@ -210,7 +207,7 @@ class LoadScreenshots:
210
207
  __next__: Captures the next screenshot and returns it.
211
208
  """
212
209
 
213
- def __init__(self, source, imgsz=640):
210
+ def __init__(self, source):
214
211
  """Source = [screen_number left top width height] (pixels)."""
215
212
  check_requirements("mss")
216
213
  import mss # noqa
@@ -223,7 +220,6 @@ class LoadScreenshots:
223
220
  left, top, width, height = (int(x) for x in params)
224
221
  elif len(params) == 5:
225
222
  self.screen, left, top, width, height = (int(x) for x in params)
226
- self.imgsz = imgsz
227
223
  self.mode = "stream"
228
224
  self.frame = 0
229
225
  self.sct = mss.mss()
@@ -258,7 +254,6 @@ class LoadImages:
258
254
  various formats, including single image files, video files, and lists of image and video paths.
259
255
 
260
256
  Attributes:
261
- imgsz (int): Image size, defaults to 640.
262
257
  files (list): List of image and video file paths.
263
258
  nf (int): Total number of files (images and videos).
264
259
  video_flag (list): Flags indicating whether a file is a video (True) or an image (False).
@@ -274,7 +269,7 @@ class LoadImages:
274
269
  _new_video(path): Create a new cv2.VideoCapture object for a given video path.
275
270
  """
276
271
 
277
- def __init__(self, path, imgsz=640, vid_stride=1):
272
+ def __init__(self, path, vid_stride=1):
278
273
  """Initialize the Dataloader and raise FileNotFoundError if file not found."""
279
274
  parent = None
280
275
  if isinstance(path, str) and Path(path).suffix == ".txt": # *.txt file with img/vid/dir on each line
@@ -298,7 +293,6 @@ class LoadImages:
298
293
  videos = [x for x in files if x.split(".")[-1].lower() in VID_FORMATS]
299
294
  ni, nv = len(images), len(videos)
300
295
 
301
- self.imgsz = imgsz
302
296
  self.files = images + videos
303
297
  self.nf = ni + nv # number of files
304
298
  self.video_flag = [False] * ni + [True] * nv
@@ -377,7 +371,6 @@ class LoadPilAndNumpy:
377
371
  Attributes:
378
372
  paths (list): List of image paths or autogenerated filenames.
379
373
  im0 (list): List of images stored as Numpy arrays.
380
- imgsz (int): Image size, defaults to 640.
381
374
  mode (str): Type of data being processed, defaults to 'image'.
382
375
  bs (int): Batch size, equivalent to the length of `im0`.
383
376
  count (int): Counter for iteration, initialized at 0 during `__iter__()`.
@@ -386,13 +379,12 @@ class LoadPilAndNumpy:
386
379
  _single_check(im): Validate and format a single image to a Numpy array.
387
380
  """
388
381
 
389
- def __init__(self, im0, imgsz=640):
382
+ def __init__(self, im0):
390
383
  """Initialize PIL and Numpy Dataloader."""
391
384
  if not isinstance(im0, list):
392
385
  im0 = [im0]
393
386
  self.paths = [getattr(im, "filename", f"image{i}.jpg") for i, im in enumerate(im0)]
394
387
  self.im0 = [self._single_check(im) for im in im0]
395
- self.imgsz = imgsz
396
388
  self.mode = "image"
397
389
  # Generate fake paths
398
390
  self.bs = len(self.im0)
@@ -259,8 +259,8 @@ class Model(nn.Module):
259
259
  x in sys.argv for x in ("predict", "track", "mode=predict", "mode=track")
260
260
  )
261
261
 
262
- custom = {"conf": 0.25, "save": is_cli} # method defaults
263
- args = {**self.overrides, **custom, **kwargs, "mode": "predict"} # highest priority args on the right
262
+ custom = {"conf": 0.25, "save": is_cli, "mode": "predict"} # method defaults
263
+ args = {**self.overrides, **custom, **kwargs} # highest priority args on the right
264
264
  prompts = args.pop("prompts", None) # for SAM-type models
265
265
 
266
266
  if not self.predictor:
@@ -226,7 +226,7 @@ class BasePredictor:
226
226
  else None
227
227
  )
228
228
  self.dataset = load_inference_source(
229
- source=source, imgsz=self.imgsz, vid_stride=self.args.vid_stride, buffer=self.args.stream_buffer
229
+ source=source, vid_stride=self.args.vid_stride, buffer=self.args.stream_buffer
230
230
  )
231
231
  self.source_type = self.dataset.source_type
232
232
  if not getattr(self, "stream", True) and (
@@ -667,8 +667,11 @@ class OBB(BaseTensor):
667
667
  @property
668
668
  @lru_cache(maxsize=2)
669
669
  def xyxy(self):
670
- """Return the horizontal boxes in xyxy format, (N, 4)."""
671
- # This way to fit both torch and numpy version
670
+ """
671
+ Return the horizontal boxes in xyxy format, (N, 4).
672
+
673
+ Accepts both torch and numpy boxes.
674
+ """
672
675
  x1 = self.xyxyxyxy[..., 0].min(1).values
673
676
  x2 = self.xyxyxyxy[..., 0].max(1).values
674
677
  y1 = self.xyxyxyxy[..., 1].min(1).values
@@ -563,8 +563,12 @@ class BaseTrainer:
563
563
  raise NotImplementedError("build_dataset function not implemented in trainer")
564
564
 
565
565
  def label_loss_items(self, loss_items=None, prefix="train"):
566
- """Returns a loss dict with labelled training loss items tensor."""
567
- # Not needed for classification but necessary for segmentation & detection
566
+ """
567
+ Returns a loss dict with labelled training loss items tensor.
568
+
569
+ Note:
570
+ This is not needed for classification but necessary for segmentation & detection
571
+ """
568
572
  return {"loss": loss_items} if loss_items is not None else ["loss"]
569
573
 
570
574
  def set_model_attributes(self):
@@ -12,13 +12,16 @@ def login(api_key: str = None, save=True) -> bool:
12
12
  """
13
13
  Log in to the Ultralytics HUB API using the provided API key.
14
14
 
15
- The session is not stored; a new session is created when needed using the saved SETTINGS or the HUB_API_KEY environment variable if successfully authenticated.
15
+ The session is not stored; a new session is created when needed using the saved SETTINGS or the HUB_API_KEY
16
+ environment variable if successfully authenticated.
16
17
 
17
18
  Args:
18
- api_key (str, optional): The API key to use for authentication. If not provided, it will be retrieved from SETTINGS or HUB_API_KEY environment variable.
19
+ api_key (str, optional): API key to use for authentication.
20
+ If not provided, it will be retrieved from SETTINGS or HUB_API_KEY environment variable.
19
21
  save (bool, optional): Whether to save the API key to SETTINGS if authentication is successful.
22
+
20
23
  Returns:
21
- bool: True if authentication is successful, False otherwise.
24
+ (bool): True if authentication is successful, False otherwise.
22
25
  """
23
26
  checks.check_requirements("hub-sdk>=0.0.2")
24
27
  from hub_sdk import HUBClient
ultralytics/hub/auth.py CHANGED
@@ -87,7 +87,7 @@ class Auth:
87
87
  Attempt to authenticate with the server using either id_token or API key.
88
88
 
89
89
  Returns:
90
- bool: True if authentication is successful, False otherwise.
90
+ (bool): True if authentication is successful, False otherwise.
91
91
  """
92
92
  try:
93
93
  if header := self.get_auth_header():
@@ -107,7 +107,7 @@ class Auth:
107
107
  supported browser.
108
108
 
109
109
  Returns:
110
- bool: True if authentication is successful, False otherwise.
110
+ (bool): True if authentication is successful, False otherwise.
111
111
  """
112
112
  if not is_colab():
113
113
  return False # Currently only works with Colab
@@ -277,7 +277,7 @@ class HUBTrainingSession:
277
277
  timeout: The maximum timeout duration.
278
278
 
279
279
  Returns:
280
- str: The retry message.
280
+ (str): The retry message.
281
281
  """
282
282
  if self._should_retry(response.status_code):
283
283
  return f"Retrying {retry}x for {timeout}s." if retry else ""
@@ -341,7 +341,7 @@ class HUBTrainingSession:
341
341
  response (requests.Response): The response object from the file download request.
342
342
 
343
343
  Returns:
344
- (None)
344
+ None
345
345
  """
346
346
  with TQDM(total=content_length, unit="B", unit_scale=True, unit_divisor=1024) as pbar:
347
347
  for data in response.iter_content(chunk_size=1024):
@@ -35,9 +35,11 @@ def calculate_stability_score(masks: torch.Tensor, mask_threshold: float, thresh
35
35
 
36
36
  The stability score is the IoU between the binary masks obtained by thresholding the predicted mask logits at high
37
37
  and low values.
38
+
39
+ Notes:
40
+ - One mask is always contained inside the other.
41
+ - Save memory by preventing unnecessary cast to torch.int64
38
42
  """
39
- # One mask is always contained inside the other.
40
- # Save memory by preventing unnecessary cast to torch.int64
41
43
  intersections = (masks > (mask_threshold + threshold_offset)).sum(-1, dtype=torch.int16).sum(-1, dtype=torch.int32)
42
44
  unions = (masks > (mask_threshold - threshold_offset)).sum(-1, dtype=torch.int16).sum(-1, dtype=torch.int32)
43
45
  return intersections / unions
@@ -215,8 +215,12 @@ class SegmentationValidator(DetectionValidator):
215
215
  self.plot_masks.clear()
216
216
 
217
217
  def pred_to_json(self, predn, filename, pred_masks):
218
- """Save one JSON result."""
219
- # Example result = {"image_id": 42, "category_id": 18, "bbox": [258.15, 41.29, 348.26, 243.78], "score": 0.236}
218
+ """
219
+ Save one JSON result.
220
+
221
+ Examples:
222
+ >>> result = {"image_id": 42, "category_id": 18, "bbox": [258.15, 41.29, 348.26, 243.78], "score": 0.236}
223
+ """
220
224
  from pycocotools.mask import encode # noqa
221
225
 
222
226
  def single_encode(x):
@@ -508,9 +508,6 @@ class AutoBackend(nn.Module):
508
508
 
509
509
  Args:
510
510
  imgsz (tuple): The shape of the dummy input tensor in the format (batch_size, channels, height, width)
511
-
512
- Returns:
513
- (None): This method runs the forward pass and don't return any value
514
511
  """
515
512
  warmup_types = self.pt, self.jit, self.onnx, self.engine, self.saved_model, self.pb, self.triton, self.nn_module
516
513
  if any(warmup_types) and (self.device.type != "cpu" or self.triton):
@@ -521,13 +518,16 @@ class AutoBackend(nn.Module):
521
518
  @staticmethod
522
519
  def _model_type(p="path/to/model.pt"):
523
520
  """
524
- This function takes a path to a model file and returns the model type.
521
+ This function takes a path to a model file and returns the model type. Possibles types are pt, jit, onnx, xml,
522
+ engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, ncnn or paddle.
525
523
 
526
524
  Args:
527
525
  p: path to the model file. Defaults to path/to/model.pt
526
+
527
+ Examples:
528
+ >>> model = AutoBackend(weights="path/to/model.onnx")
529
+ >>> model_type = model._model_type() # returns "onnx"
528
530
  """
529
- # Return model type from model path, i.e. path='path/to/model.onnx' -> type=onnx
530
- # types = [pt, jit, onnx, xml, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle]
531
531
  from ultralytics.engine.exporter import export_formats
532
532
 
533
533
  sf = list(export_formats().Suffix) # export suffixes
@@ -121,21 +121,7 @@ class DistanceCalculation:
121
121
  centroid2 (point): Second bounding box data
122
122
  """
123
123
  pixel_distance = math.sqrt((centroid1[0] - centroid2[0]) ** 2 + (centroid1[1] - centroid2[1]) ** 2)
124
- return pixel_distance / self.pixel_per_meter
125
-
126
- def plot_distance_and_line(self, distance):
127
- """
128
- Plot the distance and line on frame
129
- Args:
130
- distance (float): Distance between two centroids
131
- """
132
- cv2.rectangle(self.im0, (15, 25), (280, 70), (255, 255, 255), -1)
133
- cv2.putText(
134
- self.im0, f"Distance : {distance:.2f}m", (20, 55), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2, cv2.LINE_AA
135
- )
136
- cv2.line(self.im0, self.centroids[0], self.centroids[1], self.line_color, 3)
137
- cv2.circle(self.im0, self.centroids[0], 6, self.centroid_color, -1)
138
- cv2.circle(self.im0, self.centroids[1], 6, self.centroid_color, -1)
124
+ return pixel_distance / self.pixel_per_meter, (pixel_distance / self.pixel_per_meter) * 1000
139
125
 
140
126
  def start_process(self, im0, tracks):
141
127
  """
@@ -166,8 +152,10 @@ class DistanceCalculation:
166
152
  centroid = self.calculate_centroid(self.selected_boxes[trk_id])
167
153
  self.centroids.append(centroid)
168
154
 
169
- distance = self.calculate_distance(self.centroids[0], self.centroids[1])
170
- self.plot_distance_and_line(distance)
155
+ distance_m, distance_mm = self.calculate_distance(self.centroids[0], self.centroids[1])
156
+ self.annotator.plot_distance_and_line(
157
+ distance_m, distance_mm, self.centroids, self.line_color, self.centroid_color
158
+ )
171
159
 
172
160
  self.centroids = []
173
161
 
@@ -136,7 +136,6 @@ class ObjectCounter:
136
136
  cv2.EVENT_FLAG_SHIFTKEY, etc.).
137
137
  params (dict): Additional parameters you may want to pass to the function.
138
138
  """
139
- # global is_drawing, selected_point
140
139
  if event == cv2.EVENT_LBUTTONDOWN:
141
140
  for i, point in enumerate(self.reg_pts):
142
141
  if (
@@ -9,6 +9,7 @@ import re
9
9
  import subprocess
10
10
  import sys
11
11
  import threading
12
+ import time
12
13
  import urllib
13
14
  import uuid
14
15
  from pathlib import Path
@@ -116,8 +117,11 @@ class TQDM(tqdm_original):
116
117
  """
117
118
 
118
119
  def __init__(self, *args, **kwargs):
119
- """Initialize custom Ultralytics tqdm class with different default arguments."""
120
- # Set new default values (these can still be overridden when calling TQDM)
120
+ """
121
+ Initialize custom Ultralytics tqdm class with different default arguments.
122
+
123
+ Note these can still be overridden when calling TQDM.
124
+ """
121
125
  kwargs["disable"] = not VERBOSE or kwargs.get("disable", False) # logical 'and' with default value if passed
122
126
  kwargs.setdefault("bar_format", TQDM_BAR_FORMAT) # override default value if passed
123
127
  super().__init__(*args, **kwargs)
@@ -377,7 +381,7 @@ def yaml_print(yaml_file: Union[str, Path, dict]) -> None:
377
381
  yaml_file: The file path of the YAML file or a YAML-formatted dictionary.
378
382
 
379
383
  Returns:
380
- None
384
+ (None)
381
385
  """
382
386
  yaml_dict = yaml_load(yaml_file) if isinstance(yaml_file, (str, Path)) else yaml_file
383
387
  dump = yaml.dump(yaml_dict, sort_keys=False, allow_unicode=True)
@@ -610,7 +614,7 @@ def get_ubuntu_version():
610
614
 
611
615
  def get_user_config_dir(sub_dir="Ultralytics"):
612
616
  """
613
- Get the user config directory.
617
+ Return the appropriate config directory based on the environment operating system.
614
618
 
615
619
  Args:
616
620
  sub_dir (str): The name of the subdirectory to create.
@@ -618,7 +622,6 @@ def get_user_config_dir(sub_dir="Ultralytics"):
618
622
  Returns:
619
623
  (Path): The path to the user config directory.
620
624
  """
621
- # Return the appropriate config directory for each operating system
622
625
  if WINDOWS:
623
626
  path = Path.home() / "AppData" / "Roaming" / sub_dir
624
627
  elif MACOS: # macOS
@@ -719,9 +722,19 @@ def remove_colorstr(input_string):
719
722
 
720
723
  class TryExcept(contextlib.ContextDecorator):
721
724
  """
722
- YOLOv8 TryExcept class.
725
+ Ultralytics TryExcept class. Use as @TryExcept() decorator or 'with TryExcept():' context manager.
723
726
 
724
- Use as @TryExcept() decorator or 'with TryExcept():' context manager.
727
+ Examples:
728
+ As a decorator:
729
+ >>> @TryExcept(msg="Error occurred in func", verbose=True)
730
+ >>> def func():
731
+ >>> # Function logic here
732
+ >>> pass
733
+
734
+ As a context manager:
735
+ >>> with TryExcept(msg="Error occurred in block", verbose=True):
736
+ >>> # Code block here
737
+ >>> pass
725
738
  """
726
739
 
727
740
  def __init__(self, msg="", verbose=True):
@@ -740,6 +753,64 @@ class TryExcept(contextlib.ContextDecorator):
740
753
  return True
741
754
 
742
755
 
756
+ class Retry(contextlib.ContextDecorator):
757
+ """
758
+ Retry class for function execution with exponential backoff.
759
+
760
+ Can be used as a decorator or a context manager to retry a function or block of code on exceptions, up to a
761
+ specified number of times with an exponentially increasing delay between retries.
762
+
763
+ Examples:
764
+ Example usage as a decorator:
765
+ >>> @Retry(times=3, delay=2)
766
+ >>> def test_func():
767
+ >>> # Replace with function logic that may raise exceptions
768
+ >>> return True
769
+
770
+ Example usage as a context manager:
771
+ >>> with Retry(times=3, delay=2):
772
+ >>> # Replace with code block that may raise exceptions
773
+ >>> pass
774
+ """
775
+
776
+ def __init__(self, times=3, delay=2):
777
+ """Initialize Retry class with specified number of retries and delay."""
778
+ self.times = times
779
+ self.delay = delay
780
+ self._attempts = 0
781
+
782
+ def __call__(self, func):
783
+ """Decorator implementation for Retry with exponential backoff."""
784
+
785
+ def wrapped_func(*args, **kwargs):
786
+ self._attempts = 0
787
+ while self._attempts < self.times:
788
+ try:
789
+ return func(*args, **kwargs)
790
+ except Exception as e:
791
+ self._attempts += 1
792
+ print(f"Retry {self._attempts}/{self.times} failed: {e}")
793
+ if self._attempts >= self.times:
794
+ raise e
795
+ time.sleep(self.delay * (2**self._attempts)) # exponential backoff delay
796
+
797
+ return wrapped_func
798
+
799
+ def __enter__(self):
800
+ """Enter the runtime context related to this object."""
801
+ self._attempts = 0
802
+
803
+ def __exit__(self, exc_type, exc_value, traceback):
804
+ """Exit the runtime context related to this object with exponential backoff."""
805
+ if exc_type is not None:
806
+ self._attempts += 1
807
+ if self._attempts < self.times:
808
+ print(f"Retry {self._attempts}/{self.times} failed: {exc_value}")
809
+ time.sleep(self.delay * (2**self._attempts)) # exponential backoff delay
810
+ return True # Suppresses the exception and retries
811
+ return False # Re-raises the exception if retries are exhausted
812
+
813
+
743
814
  def threaded(func):
744
815
  """
745
816
  Multi-threads a target function by default and returns the thread or function result.
@@ -83,8 +83,12 @@ def benchmark(
83
83
  for i, (name, format, suffix, cpu, gpu) in export_formats().iterrows(): # index, (name, format, suffix, CPU, GPU)
84
84
  emoji, filename = "❌", None # export defaults
85
85
  try:
86
- assert i != 9 or LINUX, "Edge TPU export only supported on Linux"
87
- if i in {5, 10}: # CoreML and TF.js
86
+ # Checks
87
+ if i == 9:
88
+ assert LINUX, "Edge TPU export only supported on Linux"
89
+ elif i == 7:
90
+ assert model.task != "obb", "TensorFlow GraphDef not supported for OBB task"
91
+ elif i in {5, 10}: # CoreML and TF.js
88
92
  assert MACOS or LINUX, "export only supported on macOS and Linux"
89
93
  if "cpu" in device.type:
90
94
  assert cpu, "inference not supported on CPU"
@@ -254,8 +258,7 @@ class ProfileModels:
254
258
  """Retrieves the information including number of layers, parameters, gradients and FLOPs for an ONNX model
255
259
  file.
256
260
  """
257
- # return (num_layers, num_params, num_gradients, num_flops)
258
- return 0.0, 0.0, 0.0, 0.0
261
+ return 0.0, 0.0, 0.0, 0.0 # return (num_layers, num_params, num_gradients, num_flops)
259
262
 
260
263
  def iterative_sigma_clipping(self, data, sigma=2, max_iters=3):
261
264
  """Applies an iterative sigma clipping algorithm to the given data times number of iterations."""
@@ -109,7 +109,7 @@ def is_ascii(s) -> bool:
109
109
  s (str): String to be checked.
110
110
 
111
111
  Returns:
112
- bool: True if the string is composed only of ASCII characters, False otherwise.
112
+ (bool): True if the string is composed only of ASCII characters, False otherwise.
113
113
  """
114
114
  # Convert list, tuple, None, etc. to string
115
115
  s = str(s)
@@ -327,7 +327,7 @@ def check_python(minimum: str = "3.8.0") -> bool:
327
327
  minimum (str): Required minimum version of python.
328
328
 
329
329
  Returns:
330
- None
330
+ (bool): Whether the installed Python version meets the minimum constraints.
331
331
  """
332
332
  return check_version(platform.python_version(), minimum, name="Python ", hard=True)
333
333
 
ultralytics/utils/loss.py CHANGED
@@ -87,8 +87,12 @@ class BboxLoss(nn.Module):
87
87
 
88
88
  @staticmethod
89
89
  def _df_loss(pred_dist, target):
90
- """Return sum of left and right DFL losses."""
91
- # Distribution Focal Loss (DFL) proposed in Generalized Focal Loss https://ieeexplore.ieee.org/document/9792391
90
+ """
91
+ Return sum of left and right DFL losses.
92
+
93
+ Distribution Focal Loss (DFL) proposed in Generalized Focal Loss
94
+ https://ieeexplore.ieee.org/document/9792391
95
+ """
92
96
  tl = target.long() # target left
93
97
  tr = tl + 1 # target right
94
98
  wl = tr - target # weight left
@@ -696,6 +700,7 @@ class v8OBBLoss(v8DetectionLoss):
696
700
  anchor_points (torch.Tensor): Anchor points, (h*w, 2).
697
701
  pred_dist (torch.Tensor): Predicted rotated distance, (bs, h*w, 4).
698
702
  pred_angle (torch.Tensor): Predicted angle, (bs, h*w, 1).
703
+
699
704
  Returns:
700
705
  (torch.Tensor): Predicted rotated bounding boxes with angles, (bs, h*w, 5).
701
706
  """
@@ -180,7 +180,7 @@ def _get_covariance_matrix(boxes):
180
180
  Returns:
181
181
  (torch.Tensor): Covariance metrixs corresponding to original rotated bounding boxes.
182
182
  """
183
- # Gaussian bounding boxes, ignored the center points(the first two columns) cause it's not needed here.
183
+ # Gaussian bounding boxes, ignore the center points (the first two columns) because they are not needed here.
184
184
  gbbs = torch.cat((torch.pow(boxes[:, 2:4], 2) / 12, boxes[:, 4:]), dim=-1)
185
185
  a, b, c = gbbs.split(1, dim=-1)
186
186
  return (
ultralytics/utils/ops.py CHANGED
@@ -75,7 +75,6 @@ def segment2box(segment, width=640, height=640):
75
75
  Returns:
76
76
  (np.ndarray): the minimum and maximum x and y values of the segment.
77
77
  """
78
- # Convert 1 segment label to 1 box label, applying inside-image constraint, i.e. (xy1, xy2, ...) to (xyxy)
79
78
  x, y = segment.T # segment xy
80
79
  inside = (x >= 0) & (y >= 0) & (x <= width) & (y <= height)
81
80
  x = x[inside]
@@ -362,8 +361,8 @@ def scale_image(masks, im0_shape, ratio_pad=None):
362
361
  else:
363
362
  # gain = ratio_pad[0][0]
364
363
  pad = ratio_pad[1]
365
- top, left = (int(round(pad[1] - 0.1)), int(round(pad[0] - 0.1))) # y, x
366
- bottom, right = (int(round(im1_shape[0] - pad[1] + 0.1)), int(round(im1_shape[1] - pad[0] + 0.1)))
364
+ top, left = int(pad[1]), int(pad[0]) # y, x
365
+ bottom, right = int(im1_shape[0] - pad[1]), int(im1_shape[1] - pad[0])
367
366
 
368
367
  if len(masks.shape) < 2:
369
368
  raise ValueError(f'"len of masks shape" should be 2 or 3, but got {len(masks.shape)}')
@@ -731,8 +730,8 @@ def scale_masks(masks, shape, padding=True):
731
730
  if padding:
732
731
  pad[0] /= 2
733
732
  pad[1] /= 2
734
- top, left = (int(round(pad[1] - 0.1)), int(round(pad[0] - 0.1))) if padding else (0, 0) # y, x
735
- bottom, right = (int(round(mh - pad[1] + 0.1)), int(round(mw - pad[0] + 0.1)))
733
+ top, left = (int(pad[1]), int(pad[0])) if padding else (0, 0) # y, x
734
+ bottom, right = (int(mh - pad[1]), int(mw - pad[0]))
736
735
  masks = masks[..., top:bottom, left:right]
737
736
 
738
737
  masks = F.interpolate(masks, shape, mode="bilinear", align_corners=False) # NCHW
@@ -388,6 +388,7 @@ class Annotator:
388
388
  a (float) : The value of pose point a
389
389
  b (float): The value of pose point b
390
390
  c (float): The value o pose point c
391
+
391
392
  Returns:
392
393
  angle (degree): Degree value of angle between three points
393
394
  """
@@ -518,6 +519,51 @@ class Annotator:
518
519
  self.im, label, (int(mask[0][0]) - text_size[0] // 2, int(mask[0][1]) - 5), 0, 0.7, (255, 255, 255), 2
519
520
  )
520
521
 
522
+ def plot_distance_and_line(self, distance_m, distance_mm, centroids, line_color, centroid_color):
523
+ """
524
+ Plot the distance and line on frame.
525
+
526
+ Args:
527
+ distance_m (float): Distance between two bbox centroids in meters.
528
+ distance_mm (float): Distance between two bbox centroids in millimeters.
529
+ centroids (list): Bounding box centroids data.
530
+ line_color (RGB): Distance line color.
531
+ centroid_color (RGB): Bounding box centroid color.
532
+ """
533
+ (text_width_m, text_height_m), _ = cv2.getTextSize(
534
+ f"Distance M: {distance_m:.2f}m", cv2.FONT_HERSHEY_SIMPLEX, 0.8, 2
535
+ )
536
+ cv2.rectangle(self.im, (15, 25), (15 + text_width_m + 10, 25 + text_height_m + 20), (255, 255, 255), -1)
537
+ cv2.putText(
538
+ self.im,
539
+ f"Distance M: {distance_m:.2f}m",
540
+ (20, 50),
541
+ cv2.FONT_HERSHEY_SIMPLEX,
542
+ 0.8,
543
+ (0, 0, 0),
544
+ 2,
545
+ cv2.LINE_AA,
546
+ )
547
+
548
+ (text_width_mm, text_height_mm), _ = cv2.getTextSize(
549
+ f"Distance MM: {distance_mm:.2f}mm", cv2.FONT_HERSHEY_SIMPLEX, 0.8, 2
550
+ )
551
+ cv2.rectangle(self.im, (15, 75), (15 + text_width_mm + 10, 75 + text_height_mm + 20), (255, 255, 255), -1)
552
+ cv2.putText(
553
+ self.im,
554
+ f"Distance MM: {distance_mm:.2f}mm",
555
+ (20, 100),
556
+ cv2.FONT_HERSHEY_SIMPLEX,
557
+ 0.8,
558
+ (0, 0, 0),
559
+ 2,
560
+ cv2.LINE_AA,
561
+ )
562
+
563
+ cv2.line(self.im, centroids[0], centroids[1], line_color, 3)
564
+ cv2.circle(self.im, centroids[0], 6, centroid_color, -1)
565
+ cv2.circle(self.im, centroids[1], 6, centroid_color, -1)
566
+
521
567
  def visioneye(self, box, center_point, color=(235, 219, 11), pin_color=(255, 0, 255), thickness=2, pins_radius=10):
522
568
  """
523
569
  Function for pinpoint human-vision eye mapping and plotting.
@@ -75,7 +75,7 @@ class TritonRemoteModel:
75
75
  *inputs (List[np.ndarray]): Input data to the model.
76
76
 
77
77
  Returns:
78
- List[np.ndarray]: Model outputs.
78
+ (List[np.ndarray]): Model outputs.
79
79
  """
80
80
  infer_inputs = []
81
81
  input_format = inputs[0].dtype
@@ -94,7 +94,7 @@ def run_ray_tune(
94
94
  config (dict): A dictionary of hyperparameters to use for training.
95
95
 
96
96
  Returns:
97
- None.
97
+ None
98
98
  """
99
99
  model_to_train = ray.get(model_in_store) # get the model from ray store for tuning
100
100
  model_to_train.reset_callbacks()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ultralytics
3
- Version: 8.1.5
3
+ Version: 8.1.7
4
4
  Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
5
5
  Author: Glenn Jocher, Ayush Chaurasia, Jing Qiu
6
6
  Maintainer: Glenn Jocher, Ayush Chaurasia, Jing Qiu
@@ -55,7 +55,7 @@ Requires-Dist: mkdocs-material ; extra == 'dev'
55
55
  Requires-Dist: mkdocstrings[python] ; extra == 'dev'
56
56
  Requires-Dist: mkdocs-jupyter ; extra == 'dev'
57
57
  Requires-Dist: mkdocs-redirects ; extra == 'dev'
58
- Requires-Dist: mkdocs-ultralytics-plugin >=0.0.38 ; extra == 'dev'
58
+ Requires-Dist: mkdocs-ultralytics-plugin >=0.0.42 ; extra == 'dev'
59
59
  Provides-Extra: explorer
60
60
  Requires-Dist: lancedb ; extra == 'explorer'
61
61
  Requires-Dist: duckdb ; extra == 'explorer'
@@ -1,7 +1,7 @@
1
- ultralytics/__init__.py,sha256=-Wi9TSgENzcFGMOr9NsSSP95Ypr6Dc-fTnvR07oUzTM,596
1
+ ultralytics/__init__.py,sha256=Bo-hRR18A9FBGJrLtJ952ghKsprlIUlH4Vm2Y0t_SWI,596
2
2
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
3
3
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
4
- ultralytics/cfg/__init__.py,sha256=7VOr93XpIpRcVfCtwJYcCsIszbBooBAHJ9y8Msio_jw,20713
4
+ ultralytics/cfg/__init__.py,sha256=OZe3OfyNAeT1lRI7uJVM_Lla91mxGYgJMxrwyT7VP6o,20768
5
5
  ultralytics/cfg/default.yaml,sha256=Ihuy6Dziu-qm9dZ1qRSu7lrJB8sF3U8yTXPiZ9aKXlM,8091
6
6
  ultralytics/cfg/datasets/Argoverse.yaml,sha256=FyeuJT5CHq_9d4hlfAf0kpZlnbUMO0S--UJ1yIqcdKk,3134
7
7
  ultralytics/cfg/datasets/DOTAv1.5.yaml,sha256=YDsyFPI6F6-OQXLBM3hOXo3vADYREwZzmMQfJNdpWyM,1193
@@ -12,6 +12,7 @@ ultralytics/cfg/datasets/Objects365.yaml,sha256=kiiV4KLMH2mcPPRrg6cQGygnbiTrHxwt
12
12
  ultralytics/cfg/datasets/SKU-110K.yaml,sha256=geRkccBRl2eKgfNYTOPYwD9mTfqktTBGiMJoE3PZEnA,2493
13
13
  ultralytics/cfg/datasets/VOC.yaml,sha256=3-CDpjIq_s5pkbsJ9TjrYIeV24rYGuJGu4Qg6uktEZE,3655
14
14
  ultralytics/cfg/datasets/VisDrone.yaml,sha256=NfrbjVnE48E7TPbxtF7rtQHvVBO0DchFJFEuGrG1VRU,3073
15
+ ultralytics/cfg/datasets/carparts-seg.yaml,sha256=pvTi3EH2j6UuG0LHoQJ7JjQv_cJoO8UKSXPptUTnl8U,1207
15
16
  ultralytics/cfg/datasets/coco-pose.yaml,sha256=w7H-J2e87GIV_PZdRDgqEFa75ObScpBK_l85U4ZMsMo,1603
16
17
  ultralytics/cfg/datasets/coco.yaml,sha256=xbim-GcWpvF_uwlStjbPjxXFhVfL0U_WNQI99b5gjdY,2584
17
18
  ultralytics/cfg/datasets/coco128-seg.yaml,sha256=6wRjT1C6eXblXzzSvCjXfVSYF12pjZl7DKVDkFbdUQ0,1925
@@ -19,8 +20,10 @@ ultralytics/cfg/datasets/coco128.yaml,sha256=vPraVMUKvhJY2dnhPbsCzwAPEOw1J8P6Wyq
19
20
  ultralytics/cfg/datasets/coco8-pose.yaml,sha256=MErskGM63ED7bJUNPd6Rv5nTPHR77GaqB3pgSzJ3heA,961
20
21
  ultralytics/cfg/datasets/coco8-seg.yaml,sha256=hH0sEb_ZdtjziVg9PNNjdZADuYIbvYLD9-B2J7s7rlc,1865
21
22
  ultralytics/cfg/datasets/coco8.yaml,sha256=yGDMRSehDIsT1h36JA-FTWZrtJRertD3tfoBLsS2Ydc,1840
23
+ ultralytics/cfg/datasets/crack-seg.yaml,sha256=asdmbm4UXsUDovHvsMZdhbAa97vtd3bN72EqEjfnP-0,791
22
24
  ultralytics/cfg/datasets/dota8.yaml,sha256=HlwU4tpnUCCn7DQBXYRBGbfARNcALfCCRJnqycmHprg,1042
23
25
  ultralytics/cfg/datasets/open-images-v7.yaml,sha256=gsN0JXLSdQglio024p6NEegNbX06kJUNuj0bh9oEi-U,12493
26
+ ultralytics/cfg/datasets/package-seg.yaml,sha256=t6iu8MwulLxLVT2QdeOXz2fcCRcqufGpKOXUjTg2gMA,801
24
27
  ultralytics/cfg/datasets/tiger-pose.yaml,sha256=v2pOOrijTqdFA82nd2Jt-ZOWKNQl_qYgEqSgl4d0xWs,864
25
28
  ultralytics/cfg/datasets/xView.yaml,sha256=rjQPRNk--jlYN9wcVTu1KbopgZIkWXhr_s1UkSdcERs,5217
26
29
  ultralytics/cfg/models/rt-detr/rtdetr-l.yaml,sha256=Nbzi93tAJhBw69hUNBkzXaeMMWwW6tWeAsdN8ynryuU,1934
@@ -54,28 +57,28 @@ ultralytics/data/__init__.py,sha256=A3i0n-2MnNzSdYqhM8xynBO2HJNKGSXWhPvRyO0_u1I,
54
57
  ultralytics/data/annotator.py,sha256=evXQzARVerc0hb9ol-n_GrrHf-dlXO4lCMMWEZoJ2UM,2117
55
58
  ultralytics/data/augment.py,sha256=ORotqUN-qulkHxzoW5hFF_CZDlBhuaqGgAsiPUVIf4I,52000
56
59
  ultralytics/data/base.py,sha256=XcgBVEr-9wl58Ka-5gJUMg43LXsBQ6PiCKdHWZTdvEI,13216
57
- ultralytics/data/build.py,sha256=dVP0PKuaiWk5ndpHca-xAOdRx5EIcmULKyRgqO5E_tQ,6440
58
- ultralytics/data/converter.py,sha256=0IvmqQ_eesfPF_4x_lSn_z9apYLCY2IkoJQuUcrdeoc,16426
59
- ultralytics/data/dataset.py,sha256=waqG4WiQ8hSVo5IMydq1NvMNQ5IM2du_m0bCv1q140U,16504
60
- ultralytics/data/loaders.py,sha256=loSxGXzfzxrxuL3pPqTcCXoqhI3BP5RrvjIjBnaK7Dk,22300
60
+ ultralytics/data/build.py,sha256=GuWEGrBr7sYtVOMD00TcJoooq3DYhqOKRvYUKGrGK9w,6293
61
+ ultralytics/data/converter.py,sha256=I2rY7uxPAFJtNQ8ApajSBTripisZhuSqQHaVeBR5pX4,16496
62
+ ultralytics/data/dataset.py,sha256=f_rF53K_4GLpQDPxT1hvbKHFkBs0HBbEurJyn5wpIsE,16526
63
+ ultralytics/data/loaders.py,sha256=8nFTCTZ9fSn2TX1ALq0BE0CmmqHvKte_CscxsnAVWEQ,21910
61
64
  ultralytics/data/split_dota.py,sha256=1q2FZC0SE4deRpXUSbKTbUAjX9VeejUIFM2DBLF8Cco,9961
62
65
  ultralytics/data/utils.py,sha256=DHP14WwUF7uFPOpdUkH-gEC8Dgzl1E0Z_DXiLHx-gPE,29509
63
66
  ultralytics/data/explorer/__init__.py,sha256=-Y3m1ZedepOQUv_KW82zaGxvU_PSHcuwUTFqG9BhAr4,113
64
- ultralytics/data/explorer/explorer.py,sha256=VObECm8IUBaClQoQS_W9ctN1xKGKQVSNR0yhWiAnFeY,18642
67
+ ultralytics/data/explorer/explorer.py,sha256=JnYFZWCqotKGm4dTIT-r8QKNkK9RPNrWcBJoglQN_AE,18688
65
68
  ultralytics/data/explorer/utils.py,sha256=a6ugY8rKpFM8dIRcUwRyjRkRJ-zXEwe-NiJr6CLVlus,7041
66
69
  ultralytics/data/explorer/gui/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7JI8grmQDTs,42
67
- ultralytics/data/explorer/gui/dash.py,sha256=O6TGD3y0DWZuwaRUkSKpB5mXf-tSw7p-O_KE8kiZP2k,8903
70
+ ultralytics/data/explorer/gui/dash.py,sha256=3Vi-k2LpUis-WHZ81Qnzlj71wpTCr4A8YxjUl0-v8T4,10042
68
71
  ultralytics/engine/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7JI8grmQDTs,42
69
72
  ultralytics/engine/exporter.py,sha256=tT3Egg-56KwmvgokQUNIXVpgkXj1uxuEaw6w_wpuUu8,52004
70
- ultralytics/engine/model.py,sha256=nUvlHYaj0m_O8rx-TdGSc3GWHsthM36JKEK2cV7KZgo,21505
71
- ultralytics/engine/predictor.py,sha256=CbZUppzq2gT6zcas6jtKQ9-IbH_Lh3Az5z9zCcIl5f0,17850
72
- ultralytics/engine/results.py,sha256=TWpQOBbrvJ77FPY7a9-vcSO9jxIyVCfC6s-65ZKKuAk,27614
73
- ultralytics/engine/trainer.py,sha256=xCBpfBT4YUqfW7F1sjPY0bmjOWBEnfmE3LQ1BiXPTrA,34264
73
+ ultralytics/engine/model.py,sha256=TdO-V81N-921SSjULFIS0Ry9TIqN6RJKQoNfMQlRwRw,21505
74
+ ultralytics/engine/predictor.py,sha256=95ujaUYbDtui-s4hloGmJ0yVm9IC05Ck5dyoyNTk0BU,17832
75
+ ultralytics/engine/results.py,sha256=RIOSzGYBsPYvFNeqtoAw5u-fqgbzI6kNpg1FRQ3QVbI,27622
76
+ ultralytics/engine/trainer.py,sha256=9uUIQwpZPEc5au2bo26ky9dLmOUiGaNtl_s0IUfDxEA,34307
74
77
  ultralytics/engine/tuner.py,sha256=yJTecrgsZbeE4XC8iJWoUA_DKACUnDSt8N1V_PTeCcc,11758
75
78
  ultralytics/engine/validator.py,sha256=znVY4997-pMzx23FP_JpQczIEvWT5jp-sIEovYXI6RQ,14576
76
- ultralytics/hub/__init__.py,sha256=yH_bbIOUwZsDgoxnrvv_8a96DuPNzaZaK5jejzy8r_4,5020
77
- ultralytics/hub/auth.py,sha256=92vY72MsvXdubj_CCHwsGI2UVVZxIG_MEDvIBMkxm5o,5366
78
- ultralytics/hub/session.py,sha256=nGCCueIPRQbI9EwuoJc8QcLBYYOuEFklKeY4Ix0VB0w,14226
79
+ ultralytics/hub/__init__.py,sha256=e-pUvDu3PUDcrWfWfBUbcUTm0DTbVLagFHsjmrum9Xs,5035
80
+ ultralytics/hub/auth.py,sha256=TnNNy685THzmFji3yDo2s3QIAjSEQySglZoX5LI30do,5370
81
+ ultralytics/hub/session.py,sha256=J5IVdjVbsWf5tm_RM4dtW7wel3xwkS5SCVBBt1knjwM,14226
79
82
  ultralytics/hub/utils.py,sha256=rfUfr1gI_gN2hq6A8AzCejep6DBvsElBIqz-BFzZoRc,9736
80
83
  ultralytics/models/__init__.py,sha256=-i1eeXMAglo0zMRGG3phmdoJNO7OJQZgyj8j0t7eiDE,173
81
84
  ultralytics/models/fastsam/__init__.py,sha256=0dt65jZ_5b7Q-mdXN8MSEkgnFRA0FIwlel_LS2RaOlU,254
@@ -94,7 +97,7 @@ ultralytics/models/rtdetr/predict.py,sha256=pmjUlcUTqxoBNa5tW_EuFjh7ldXSm99Qnk5M
94
97
  ultralytics/models/rtdetr/train.py,sha256=HdSC2x22Rks6qKNI7EGa6nWMZPhi_7VdQrbcayxk0ec,3684
95
98
  ultralytics/models/rtdetr/val.py,sha256=sE99MGrq5rSyIN8dNBpJVTe9b__Ax9NyS8MYccQGDPs,5401
96
99
  ultralytics/models/sam/__init__.py,sha256=9A1iyfPN_ncqq3TMExe_-uPoARjEX3psoHEI1xMG2VE,144
97
- ultralytics/models/sam/amg.py,sha256=w7mLxojmI50t6yPzx034WdQJUipMpEtHyvhXxFBo46A,7915
100
+ ultralytics/models/sam/amg.py,sha256=MsKSRS2SieZK_n-m2ICk1QpcYogl5mofcsVa-4FXYvo,7935
98
101
  ultralytics/models/sam/build.py,sha256=jJvloRbPwHvSnVWwM3pEdzpM5MdIcEHbRaqQk_S9lG8,4943
99
102
  ultralytics/models/sam/model.py,sha256=yLIjB00UZ6WDkcRBXtUmwmu8gTIsKyTdKsLAxI1SeoM,4706
100
103
  ultralytics/models/sam/predict.py,sha256=C8dErpMefMwQvReJSvxRMaTala6OJbAckrGO3m508kI,23632
@@ -128,9 +131,9 @@ ultralytics/models/yolo/pose/val.py,sha256=w_VIKzGcj_0CRNObPqk0NnDOfRN-xl2C6uwpF
128
131
  ultralytics/models/yolo/segment/__init__.py,sha256=mSbKOE8BnHL7PL2nCOVG7dRM7CI6hJezFPPwZFjEmy8,247
129
132
  ultralytics/models/yolo/segment/predict.py,sha256=ycT8Z6U8N-4x94YQxM1nZc6rBWbF2-ErGmO7akMNtXM,2491
130
133
  ultralytics/models/yolo/segment/train.py,sha256=aOQpDIptZfKSl9mFa6B-3W3QccMRlmBINBkI9K8-3sQ,2298
131
- ultralytics/models/yolo/segment/val.py,sha256=OPLzdhD5VFuIVjQObExwEdjR7OxDrj0hqNailh3XnkI,11709
134
+ ultralytics/models/yolo/segment/val.py,sha256=njiF6RWddS-HOWxVvlk5PXRw6UOgEt_HEOZVPF7rruQ,11745
132
135
  ultralytics/nn/__init__.py,sha256=4BPLHY89xEM_al5uK0aOmFgiML6CMGEZbezxOvTjOEs,587
133
- ultralytics/nn/autobackend.py,sha256=42BYn6nKan5TaOjYa3sKg24RbaEWdSUVljRtqD7pyGA,27088
136
+ ultralytics/nn/autobackend.py,sha256=xxCZ0xBoXOJh8ajbhpi8I4jwF1B-7NcVtMXCuhOIoG0,27069
134
137
  ultralytics/nn/tasks.py,sha256=vbaN_C0BHoHnoebi74ODsR-oC-4YG3K1OAduDEcM9Z8,38370
135
138
  ultralytics/nn/modules/__init__.py,sha256=ejmeNK9L-yGUX3pGr_1-HlPcCdrf7XPLFVZ3OR0mmno,1954
136
139
  ultralytics/nn/modules/block.py,sha256=1bi5rRzHNTg10VlRdpRP_xjTJHEIfMQ1FY2nIgHKmws,14488
@@ -140,9 +143,9 @@ ultralytics/nn/modules/transformer.py,sha256=TgDpTjSkk1_-9IrIjm8bebcG5fSO9GVb5On
140
143
  ultralytics/nn/modules/utils.py,sha256=6CCeDy6GGkDM7XjGm4FCtVpXoEuICIPCsruI8etNS3g,3197
141
144
  ultralytics/solutions/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7JI8grmQDTs,42
142
145
  ultralytics/solutions/ai_gym.py,sha256=d3XRr-u0vIp1Bi9mAwDzGkxBztnhWU_ak5e8XR2J31s,6006
143
- ultralytics/solutions/distance_calculation.py,sha256=4YWM94Y5-LedFHocT9qc-CREx6GaXiLy0YlCxZRSjFs,6810
146
+ ultralytics/solutions/distance_calculation.py,sha256=EQ5QIXuSLm5KcRtMD-wB3MbRwPo55vhrEmt3Rf49PPs,6328
144
147
  ultralytics/solutions/heatmap.py,sha256=tAuLoFi3_iQZUw7qjCRu3w03eRL5Hx79-7TvksvzZwo,10838
145
- ultralytics/solutions/object_counter.py,sha256=kSurxRDScaaXL6J-5rocsT2ethGVcGYHcuiIk-VOYe0,10514
148
+ ultralytics/solutions/object_counter.py,sha256=7x-tokfq_OTas2i8ZT6SKXTDSoguh_g141Csl8DnKGw,10470
146
149
  ultralytics/solutions/speed_estimation.py,sha256=7zskVZzbzX5kabmGD_pw0cJrb4pucGMJQ7GW1PVF2WM,6610
147
150
  ultralytics/trackers/__init__.py,sha256=j72IgH2dZHQArMPK4YwcV5ieIw94fYvlGdQjB9cOQKw,227
148
151
  ultralytics/trackers/basetrack.py,sha256=-vBDD-Q9lsxfTMK2w9kuqWGrYbRMmaBCCEbGGyR53gE,3675
@@ -153,24 +156,24 @@ ultralytics/trackers/utils/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7J
153
156
  ultralytics/trackers/utils/gmc.py,sha256=dnCv90urvqQiVG6qsVnFQRBbu1rDQbqmJU7MucOWYyY,13949
154
157
  ultralytics/trackers/utils/kalman_filter.py,sha256=JN1sAcfJZy8fTZxc8w3jUJnGQDKtgAL__p4nTR6RM2I,15168
155
158
  ultralytics/trackers/utils/matching.py,sha256=c_pthBfu9sWeMVYe-dSecdWcQxUey-mQT2yMVsFH3VQ,5404
156
- ultralytics/utils/__init__.py,sha256=WphOGqOoNGBGh5QBL6yQxS3eQIKahKkMPaUszvGXack,34272
159
+ ultralytics/utils/__init__.py,sha256=iCP2iY1J4ZQ15fT6_uMOIWvAf19F1ZWBWlEKXGqSSBA,36882
157
160
  ultralytics/utils/autobatch.py,sha256=ygZ3f2ByIkcujB89ENcTnGWWnAQw5Pbg6nBuShg-5t4,3863
158
- ultralytics/utils/benchmarks.py,sha256=gqZaIih9bcpMbFnm65taWnWSKCN1EGzTruZeMDQkQA4,17405
159
- ultralytics/utils/checks.py,sha256=OfIxd2_qufJpjOWOHt3NrRquGCr5GyEUHOMvjT-PhIs,27592
161
+ ultralytics/utils/benchmarks.py,sha256=D_Lu03WkIv5c7B7BOz8_jsWRK5dLoxkae6LaNDbmI18,17556
162
+ ultralytics/utils/checks.py,sha256=oouDmoCYCho0GTYgJHA9pg73Lk-z_hQ7-rK8tO-bydM,27665
160
163
  ultralytics/utils/dist.py,sha256=3HeNbY2gp7vYhcvVhsrvTrQXpQmgT8tpmnzApf3eQRA,2267
161
164
  ultralytics/utils/downloads.py,sha256=S4b_DUjZcSKWXWSVoGuSOYXt9aS_NzFz0NtkFOTHHoM,21189
162
165
  ultralytics/utils/errors.py,sha256=GqP_Jgj_n0paxn8OMhn3DTCgoNkB2WjUcUaqs-M6SQk,816
163
166
  ultralytics/utils/files.py,sha256=V1cD9sC3hGd5uNVdOa4uZGySGjnsXC6Lh7mjqI_UDxo,5275
164
167
  ultralytics/utils/instance.py,sha256=fPClvPPtTk8VeXWiRv90DrFk1j1lTUKdYJtpZKUDDtA,15575
165
- ultralytics/utils/loss.py,sha256=erpbpLbt_VNOO-FItADFOjKTfwuf2A3ozECuCJiSqHM,32555
166
- ultralytics/utils/metrics.py,sha256=srIy4mfWQ9ATHYdmIfAROnDQHsKmCmBnR3mDTnYezAY,53355
167
- ultralytics/utils/ops.py,sha256=iNNYnToxFnAyYt--Pn43FuGM6Au_AjLzh3vxwJ1EpEc,33155
168
+ ultralytics/utils/loss.py,sha256=af2_eFPSR8S2t7dIh3H24WFkMYkN6mvreDEnOiYeAQc,32581
169
+ ultralytics/utils/metrics.py,sha256=_1-7bbMlyeObnVXmHV3mBQoktnYNN4xpWaaaX1x7gdY,53361
170
+ ultralytics/utils/ops.py,sha256=RxnsheSa_mDWaCm0gCKNTRz7baTKIMQfy38Z2FP4e-o,32936
168
171
  ultralytics/utils/patches.py,sha256=2iMWzwBpAjTt0UzaPzFO5JPVoKklUhftuo_3H7xBoDc,2659
169
- ultralytics/utils/plotting.py,sha256=nl3GZsWe4-pBNwY7V8hOtT1GKAxdmwN_kCaNb8Kk9Hc,42710
172
+ ultralytics/utils/plotting.py,sha256=GbF0jgnb2TgiIy40jU6nO5H_hGjCM3OYJ9kR3HnjjiY,44447
170
173
  ultralytics/utils/tal.py,sha256=fQ6dPFEJTVtFBFeTS_rtZMx_UsJyi80s3YfT8joCC6M,16015
171
174
  ultralytics/utils/torch_utils.py,sha256=Byij6JEKJeQE_G00wWpRJi0eorSo0xwXbwHJKzt_Jsk,25141
172
- ultralytics/utils/triton.py,sha256=tX3iEHFVBLJctnn9gybVk7PHk5kMkkLxwwAyfeWiT8s,3934
173
- ultralytics/utils/tuner.py,sha256=S5xet_s0K8T2pP71YVEFVGJnm0YoGDqJP0Ycr9PDlfY,6004
175
+ ultralytics/utils/triton.py,sha256=gg1finxno_tY2Ge9PMhmu7PI9wvoFZoiicdT4Bhqv3w,3936
176
+ ultralytics/utils/tuner.py,sha256=mMa3PT5zvpHsTfKgOvFlRhDpogdCD1qSdNBVmU5Xop4,6003
174
177
  ultralytics/utils/callbacks/__init__.py,sha256=YrWqC3BVVaTLob4iCPR6I36mUxIUOpPJW7B_LjT78Qw,214
175
178
  ultralytics/utils/callbacks/base.py,sha256=sOe3JvyBFmRwVZ8_Q03u7JwTeOOm9CI4s9-UEhnG0xA,5777
176
179
  ultralytics/utils/callbacks/clearml.py,sha256=K7bDf5tS8xL4KeFMkoVDL2kKkil3f4qoKy8KfZkD854,5897
@@ -182,9 +185,9 @@ ultralytics/utils/callbacks/neptune.py,sha256=5Z3ua5YBTUS56FH8VQKQG1aaIo9fH8GEyz
182
185
  ultralytics/utils/callbacks/raytune.py,sha256=6OgGNuC35F29lw8Dl_d0lue4-iBR6dqrBVQnIRQDx4E,632
183
186
  ultralytics/utils/callbacks/tensorboard.py,sha256=fyhgBgcTmEIifBqxBJkoMZ6yQNBGhSLQBAsy770-RtA,4038
184
187
  ultralytics/utils/callbacks/wb.py,sha256=03ACY2YwpTRigD0ZQH7_zlpwMdGw0lt23zX4d5Zaz28,6650
185
- ultralytics-8.1.5.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
186
- ultralytics-8.1.5.dist-info/METADATA,sha256=ysLEvgMTBG5k0nSep9hlF-k51tPoMWY2qSIKWOTsHpQ,40204
187
- ultralytics-8.1.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
188
- ultralytics-8.1.5.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
189
- ultralytics-8.1.5.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
190
- ultralytics-8.1.5.dist-info/RECORD,,
188
+ ultralytics-8.1.7.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
189
+ ultralytics-8.1.7.dist-info/METADATA,sha256=wAvY_WKTLrQV21HtS1swiqJy5YIXIRRat97umNUDKvI,40204
190
+ ultralytics-8.1.7.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
191
+ ultralytics-8.1.7.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
192
+ ultralytics-8.1.7.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
193
+ ultralytics-8.1.7.dist-info/RECORD,,