ultralytics 8.2.80__py3-none-any.whl → 8.2.82__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 (97) hide show
  1. tests/test_solutions.py +0 -4
  2. ultralytics/__init__.py +1 -1
  3. ultralytics/cfg/__init__.py +14 -16
  4. ultralytics/data/annotator.py +1 -1
  5. ultralytics/data/augment.py +58 -58
  6. ultralytics/data/base.py +3 -3
  7. ultralytics/data/converter.py +7 -8
  8. ultralytics/data/explorer/explorer.py +7 -23
  9. ultralytics/data/loaders.py +1 -1
  10. ultralytics/data/split_dota.py +11 -3
  11. ultralytics/data/utils.py +6 -10
  12. ultralytics/engine/exporter.py +2 -4
  13. ultralytics/engine/model.py +47 -47
  14. ultralytics/engine/predictor.py +1 -1
  15. ultralytics/engine/results.py +30 -30
  16. ultralytics/engine/trainer.py +11 -8
  17. ultralytics/engine/tuner.py +7 -8
  18. ultralytics/engine/validator.py +3 -5
  19. ultralytics/hub/__init__.py +5 -5
  20. ultralytics/hub/auth.py +6 -2
  21. ultralytics/hub/session.py +30 -20
  22. ultralytics/models/fastsam/model.py +13 -10
  23. ultralytics/models/fastsam/predict.py +2 -2
  24. ultralytics/models/fastsam/utils.py +0 -1
  25. ultralytics/models/nas/model.py +4 -4
  26. ultralytics/models/nas/predict.py +1 -2
  27. ultralytics/models/nas/val.py +1 -1
  28. ultralytics/models/rtdetr/predict.py +1 -1
  29. ultralytics/models/rtdetr/train.py +1 -1
  30. ultralytics/models/rtdetr/val.py +1 -1
  31. ultralytics/models/sam/model.py +11 -11
  32. ultralytics/models/sam/modules/decoders.py +7 -4
  33. ultralytics/models/sam/modules/sam.py +9 -1
  34. ultralytics/models/sam/modules/tiny_encoder.py +1 -1
  35. ultralytics/models/sam/modules/transformer.py +0 -2
  36. ultralytics/models/sam/modules/utils.py +1 -1
  37. ultralytics/models/sam/predict.py +10 -10
  38. ultralytics/models/utils/loss.py +29 -17
  39. ultralytics/models/utils/ops.py +1 -5
  40. ultralytics/models/yolo/classify/predict.py +1 -1
  41. ultralytics/models/yolo/classify/train.py +1 -1
  42. ultralytics/models/yolo/classify/val.py +1 -1
  43. ultralytics/models/yolo/detect/predict.py +1 -1
  44. ultralytics/models/yolo/detect/train.py +1 -1
  45. ultralytics/models/yolo/detect/val.py +1 -1
  46. ultralytics/models/yolo/model.py +6 -2
  47. ultralytics/models/yolo/obb/predict.py +1 -1
  48. ultralytics/models/yolo/obb/train.py +1 -1
  49. ultralytics/models/yolo/obb/val.py +2 -2
  50. ultralytics/models/yolo/pose/predict.py +1 -1
  51. ultralytics/models/yolo/pose/train.py +1 -1
  52. ultralytics/models/yolo/pose/val.py +1 -1
  53. ultralytics/models/yolo/segment/predict.py +1 -1
  54. ultralytics/models/yolo/segment/train.py +1 -1
  55. ultralytics/models/yolo/segment/val.py +1 -1
  56. ultralytics/models/yolo/world/train.py +1 -1
  57. ultralytics/nn/autobackend.py +2 -2
  58. ultralytics/nn/modules/__init__.py +2 -2
  59. ultralytics/nn/modules/block.py +8 -20
  60. ultralytics/nn/modules/conv.py +1 -3
  61. ultralytics/nn/modules/head.py +16 -31
  62. ultralytics/nn/modules/transformer.py +0 -1
  63. ultralytics/nn/modules/utils.py +0 -1
  64. ultralytics/nn/tasks.py +11 -9
  65. ultralytics/solutions/__init__.py +1 -0
  66. ultralytics/solutions/ai_gym.py +0 -2
  67. ultralytics/solutions/analytics.py +1 -6
  68. ultralytics/solutions/heatmap.py +0 -1
  69. ultralytics/solutions/object_counter.py +0 -2
  70. ultralytics/solutions/queue_management.py +0 -2
  71. ultralytics/trackers/basetrack.py +1 -1
  72. ultralytics/trackers/byte_tracker.py +2 -2
  73. ultralytics/trackers/utils/gmc.py +5 -5
  74. ultralytics/trackers/utils/kalman_filter.py +1 -1
  75. ultralytics/trackers/utils/matching.py +1 -5
  76. ultralytics/utils/__init__.py +132 -30
  77. ultralytics/utils/autobatch.py +7 -4
  78. ultralytics/utils/benchmarks.py +6 -14
  79. ultralytics/utils/callbacks/base.py +0 -1
  80. ultralytics/utils/callbacks/comet.py +0 -1
  81. ultralytics/utils/callbacks/tensorboard.py +0 -1
  82. ultralytics/utils/checks.py +15 -18
  83. ultralytics/utils/downloads.py +6 -7
  84. ultralytics/utils/files.py +3 -4
  85. ultralytics/utils/instance.py +17 -7
  86. ultralytics/utils/metrics.py +15 -15
  87. ultralytics/utils/ops.py +8 -8
  88. ultralytics/utils/plotting.py +25 -35
  89. ultralytics/utils/tal.py +27 -18
  90. ultralytics/utils/torch_utils.py +12 -13
  91. ultralytics/utils/tuner.py +2 -3
  92. {ultralytics-8.2.80.dist-info → ultralytics-8.2.82.dist-info}/METADATA +1 -1
  93. {ultralytics-8.2.80.dist-info → ultralytics-8.2.82.dist-info}/RECORD +97 -97
  94. {ultralytics-8.2.80.dist-info → ultralytics-8.2.82.dist-info}/LICENSE +0 -0
  95. {ultralytics-8.2.80.dist-info → ultralytics-8.2.82.dist-info}/WHEEL +0 -0
  96. {ultralytics-8.2.80.dist-info → ultralytics-8.2.82.dist-info}/entry_points.txt +0 -0
  97. {ultralytics-8.2.80.dist-info → ultralytics-8.2.82.dist-info}/top_level.txt +0 -0
tests/test_solutions.py CHANGED
@@ -13,7 +13,6 @@ WORKOUTS_SOLUTION_DEMO = "https://github.com/ultralytics/assets/releases/downloa
13
13
  @pytest.mark.slow
14
14
  def test_major_solutions():
15
15
  """Test the object counting, heatmap, speed estimation and queue management solution."""
16
-
17
16
  safe_download(url=MAJOR_SOLUTIONS_DEMO)
18
17
  model = YOLO("yolov8n.pt")
19
18
  names = model.names
@@ -41,7 +40,6 @@ def test_major_solutions():
41
40
  @pytest.mark.slow
42
41
  def test_aigym():
43
42
  """Test the workouts monitoring solution."""
44
-
45
43
  safe_download(url=WORKOUTS_SOLUTION_DEMO)
46
44
  model = YOLO("yolov8n-pose.pt")
47
45
  cap = cv2.VideoCapture("solution_ci_pose_demo.mp4")
@@ -60,7 +58,6 @@ def test_aigym():
60
58
  @pytest.mark.slow
61
59
  def test_instance_segmentation():
62
60
  """Test the instance segmentation solution."""
63
-
64
61
  from ultralytics.utils.plotting import Annotator, colors
65
62
 
66
63
  model = YOLO("yolov8n-seg.pt")
@@ -86,5 +83,4 @@ def test_instance_segmentation():
86
83
  @pytest.mark.slow
87
84
  def test_streamlit_predict():
88
85
  """Test streamlit predict live inference solution."""
89
-
90
86
  solutions.inference()
ultralytics/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- __version__ = "8.2.80"
3
+ __version__ = "8.2.82"
4
4
 
5
5
  import os
6
6
 
@@ -198,15 +198,15 @@ def cfg2dict(cfg):
198
198
 
199
199
  Examples:
200
200
  Convert a YAML file path to a dictionary:
201
- >>> config_dict = cfg2dict('config.yaml')
201
+ >>> config_dict = cfg2dict("config.yaml")
202
202
 
203
203
  Convert a SimpleNamespace to a dictionary:
204
204
  >>> from types import SimpleNamespace
205
- >>> config_sn = SimpleNamespace(param1='value1', param2='value2')
205
+ >>> config_sn = SimpleNamespace(param1="value1", param2="value2")
206
206
  >>> config_dict = cfg2dict(config_sn)
207
207
 
208
208
  Pass through an already existing dictionary:
209
- >>> config_dict = cfg2dict({'param1': 'value1', 'param2': 'value2'})
209
+ >>> config_dict = cfg2dict({"param1": "value1", "param2": "value2"})
210
210
 
211
211
  Notes:
212
212
  - If cfg is a path or string, it's loaded as YAML and converted to a dictionary.
@@ -235,7 +235,7 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, ove
235
235
  Examples:
236
236
  >>> from ultralytics.cfg import get_cfg
237
237
  >>> config = get_cfg() # Load default configuration
238
- >>> config = get_cfg('path/to/config.yaml', overrides={'epochs': 50, 'batch_size': 16})
238
+ >>> config = get_cfg("path/to/config.yaml", overrides={"epochs": 50, "batch_size": 16})
239
239
 
240
240
  Notes:
241
241
  - If both `cfg` and `overrides` are provided, the values in `overrides` will take precedence.
@@ -282,10 +282,10 @@ def check_cfg(cfg, hard=True):
282
282
 
283
283
  Examples:
284
284
  >>> config = {
285
- ... 'epochs': 50, # valid integer
286
- ... 'lr0': 0.01, # valid float
287
- ... 'momentum': 1.2, # invalid float (out of 0.0-1.0 range)
288
- ... 'save': 'true', # invalid bool
285
+ ... "epochs": 50, # valid integer
286
+ ... "lr0": 0.01, # valid float
287
+ ... "momentum": 1.2, # invalid float (out of 0.0-1.0 range)
288
+ ... "save": "true", # invalid bool
289
289
  ... }
290
290
  >>> check_cfg(config, hard=False)
291
291
  >>> print(config)
@@ -345,12 +345,11 @@ def get_save_dir(args, name=None):
345
345
 
346
346
  Examples:
347
347
  >>> from types import SimpleNamespace
348
- >>> args = SimpleNamespace(project='my_project', task='detect', mode='train', exist_ok=True)
348
+ >>> args = SimpleNamespace(project="my_project", task="detect", mode="train", exist_ok=True)
349
349
  >>> save_dir = get_save_dir(args)
350
350
  >>> print(save_dir)
351
351
  my_project/detect/train
352
352
  """
353
-
354
353
  if getattr(args, "save_dir", None):
355
354
  save_dir = args.save_dir
356
355
  else:
@@ -381,7 +380,6 @@ def _handle_deprecation(custom):
381
380
  equivalents. It also handles value conversions where necessary, such as inverting boolean values for
382
381
  'hide_labels' and 'hide_conf'.
383
382
  """
384
-
385
383
  for key in custom.copy().keys():
386
384
  if key == "boxes":
387
385
  deprecation_warn(key, "show_boxes")
@@ -413,8 +411,8 @@ def check_dict_alignment(base: Dict, custom: Dict, e=None):
413
411
  SystemExit: If mismatched keys are found between the custom and base dictionaries.
414
412
 
415
413
  Examples:
416
- >>> base_cfg = {'epochs': 50, 'lr0': 0.01, 'batch_size': 16}
417
- >>> custom_cfg = {'epoch': 100, 'lr': 0.02, 'batch_size': 32}
414
+ >>> base_cfg = {"epochs": 50, "lr0": 0.01, "batch_size": 16}
415
+ >>> custom_cfg = {"epoch": 100, "lr": 0.02, "batch_size": 32}
418
416
  >>> try:
419
417
  ... check_dict_alignment(base_cfg, custom_cfg)
420
418
  ... except SystemExit:
@@ -548,9 +546,9 @@ def handle_yolo_settings(args: List[str]) -> None:
548
546
 
549
547
  def handle_explorer(args: List[str]):
550
548
  """
551
- This function launches a graphical user interface that provides tools for interacting with and analyzing datasets
552
- using the Ultralytics Explorer API. It checks for the required 'streamlit' package and informs the user that the
553
- Explorer dashboard is loading.
549
+ Launches a graphical user interface that provides tools for interacting with and analyzing datasets using the
550
+ Ultralytics Explorer API. It checks for the required 'streamlit' package and informs the user that the Explorer
551
+ dashboard is loading.
554
552
 
555
553
  Args:
556
554
  args (List[str]): A list of optional command line arguments.
@@ -21,7 +21,7 @@ def auto_annotate(data, det_model="yolov8x.pt", sam_model="sam_b.pt", device="",
21
21
 
22
22
  Examples:
23
23
  >>> from ultralytics.data.annotator import auto_annotate
24
- >>> auto_annotate(data='ultralytics/assets', det_model='yolov8n.pt', sam_model='mobile_sam.pt')
24
+ >>> auto_annotate(data="ultralytics/assets", det_model="yolov8n.pt", sam_model="mobile_sam.pt")
25
25
 
26
26
  Notes:
27
27
  - The function creates a new directory for output if not specified.
@@ -38,7 +38,7 @@ class BaseTransform:
38
38
 
39
39
  Examples:
40
40
  >>> transform = BaseTransform()
41
- >>> labels = {'image': np.array(...), 'instances': [...], 'semantic': np.array(...)}
41
+ >>> labels = {"image": np.array(...), "instances": [...], "semantic": np.array(...)}
42
42
  >>> transformed_labels = transform(labels)
43
43
  """
44
44
 
@@ -93,7 +93,7 @@ class BaseTransform:
93
93
 
94
94
  Examples:
95
95
  >>> transform = BaseTransform()
96
- >>> labels = {'instances': Instances(xyxy=torch.rand(5, 4), cls=torch.randint(0, 80, (5,)))}
96
+ >>> labels = {"instances": Instances(xyxy=torch.rand(5, 4), cls=torch.randint(0, 80, (5,)))}
97
97
  >>> transformed_labels = transform.apply_instances(labels)
98
98
  """
99
99
  pass
@@ -135,7 +135,7 @@ class BaseTransform:
135
135
 
136
136
  Examples:
137
137
  >>> transform = BaseTransform()
138
- >>> labels = {'img': np.random.rand(640, 640, 3), 'instances': []}
138
+ >>> labels = {"img": np.random.rand(640, 640, 3), "instances": []}
139
139
  >>> transformed_labels = transform(labels)
140
140
  """
141
141
  self.apply_image(labels)
@@ -338,6 +338,7 @@ class BaseMixTransform:
338
338
  ... def _mix_transform(self, labels):
339
339
  ... # Implement custom mix logic here
340
340
  ... return labels
341
+ ...
341
342
  ... def get_indexes(self):
342
343
  ... return [random.randint(0, len(self.dataset) - 1) for _ in range(3)]
343
344
  >>> dataset = YourDataset()
@@ -421,7 +422,7 @@ class BaseMixTransform:
421
422
 
422
423
  Examples:
423
424
  >>> transform = BaseMixTransform(dataset)
424
- >>> labels = {'image': img, 'bboxes': boxes, 'mix_labels': [{'image': img2, 'bboxes': boxes2}]}
425
+ >>> labels = {"image": img, "bboxes": boxes, "mix_labels": [{"image": img2, "bboxes": boxes2}]}
425
426
  >>> augmented_labels = transform._mix_transform(labels)
426
427
  """
427
428
  raise NotImplementedError
@@ -456,20 +457,17 @@ class BaseMixTransform:
456
457
 
457
458
  Examples:
458
459
  >>> labels = {
459
- ... 'texts': [['cat'], ['dog']],
460
- ... 'cls': torch.tensor([[0], [1]]),
461
- ... 'mix_labels': [{
462
- ... 'texts': [['bird'], ['fish']],
463
- ... 'cls': torch.tensor([[0], [1]])
464
- ... }]
460
+ ... "texts": [["cat"], ["dog"]],
461
+ ... "cls": torch.tensor([[0], [1]]),
462
+ ... "mix_labels": [{"texts": [["bird"], ["fish"]], "cls": torch.tensor([[0], [1]])}],
465
463
  ... }
466
464
  >>> updated_labels = self._update_label_text(labels)
467
- >>> print(updated_labels['texts'])
465
+ >>> print(updated_labels["texts"])
468
466
  [['cat'], ['dog'], ['bird'], ['fish']]
469
- >>> print(updated_labels['cls'])
467
+ >>> print(updated_labels["cls"])
470
468
  tensor([[0],
471
469
  [1]])
472
- >>> print(updated_labels['mix_labels'][0]['cls'])
470
+ >>> print(updated_labels["mix_labels"][0]["cls"])
473
471
  tensor([[2],
474
472
  [3]])
475
473
  """
@@ -616,9 +614,12 @@ class Mosaic(BaseMixTransform):
616
614
 
617
615
  Examples:
618
616
  >>> mosaic = Mosaic(dataset, imgsz=640, p=1.0, n=3)
619
- >>> labels = {'img': np.random.rand(480, 640, 3), 'mix_labels': [{'img': np.random.rand(480, 640, 3)} for _ in range(2)]}
617
+ >>> labels = {
618
+ ... "img": np.random.rand(480, 640, 3),
619
+ ... "mix_labels": [{"img": np.random.rand(480, 640, 3)} for _ in range(2)],
620
+ ... }
620
621
  >>> result = mosaic._mosaic3(labels)
621
- >>> print(result['img'].shape)
622
+ >>> print(result["img"].shape)
622
623
  (640, 640, 3)
623
624
  """
624
625
  mosaic_labels = []
@@ -670,9 +671,10 @@ class Mosaic(BaseMixTransform):
670
671
 
671
672
  Examples:
672
673
  >>> mosaic = Mosaic(dataset, imgsz=640, p=1.0, n=4)
673
- >>> labels = {"img": np.random.rand(480, 640, 3), "mix_labels": [
674
- ... {"img": np.random.rand(480, 640, 3)} for _ in range(3)
675
- ... ]}
674
+ >>> labels = {
675
+ ... "img": np.random.rand(480, 640, 3),
676
+ ... "mix_labels": [{"img": np.random.rand(480, 640, 3)} for _ in range(3)],
677
+ ... }
676
678
  >>> result = mosaic._mosaic4(labels)
677
679
  >>> assert result["img"].shape == (1280, 1280, 3)
678
680
  """
@@ -734,7 +736,7 @@ class Mosaic(BaseMixTransform):
734
736
  >>> mosaic = Mosaic(dataset, imgsz=640, p=1.0, n=9)
735
737
  >>> input_labels = dataset[0]
736
738
  >>> mosaic_result = mosaic._mosaic9(input_labels)
737
- >>> mosaic_image = mosaic_result['img']
739
+ >>> mosaic_image = mosaic_result["img"]
738
740
  """
739
741
  mosaic_labels = []
740
742
  s = self.imgsz
@@ -898,7 +900,7 @@ class MixUp(BaseMixTransform):
898
900
 
899
901
  Examples:
900
902
  >>> from ultralytics.data.dataset import YOLODataset
901
- >>> dataset = YOLODataset('path/to/data.yaml')
903
+ >>> dataset = YOLODataset("path/to/data.yaml")
902
904
  >>> mixup = MixUp(dataset, pre_transform=None, p=0.5)
903
905
  """
904
906
  super().__init__(dataset=dataset, pre_transform=pre_transform, p=p)
@@ -974,10 +976,10 @@ class RandomPerspective:
974
976
  Examples:
975
977
  >>> transform = RandomPerspective(degrees=10, translate=0.1, scale=0.1, shear=10)
976
978
  >>> image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
977
- >>> labels = {'img': image, 'cls': np.array([0, 1]), 'instances': Instances(...)}
979
+ >>> labels = {"img": image, "cls": np.array([0, 1]), "instances": Instances(...)}
978
980
  >>> result = transform(labels)
979
- >>> transformed_image = result['img']
980
- >>> transformed_instances = result['instances']
981
+ >>> transformed_image = result["img"]
982
+ >>> transformed_instances = result["instances"]
981
983
  """
982
984
 
983
985
  def __init__(
@@ -1003,7 +1005,6 @@ class RandomPerspective:
1003
1005
  >>> transform = RandomPerspective(degrees=10.0, translate=0.1, scale=0.5, shear=5.0)
1004
1006
  >>> result = transform(labels) # Apply random perspective to labels
1005
1007
  """
1006
-
1007
1008
  self.degrees = degrees
1008
1009
  self.translate = translate
1009
1010
  self.scale = scale
@@ -1036,7 +1037,6 @@ class RandomPerspective:
1036
1037
  >>> border = (10, 10)
1037
1038
  >>> transformed_img, matrix, scale = affine_transform(img, border)
1038
1039
  """
1039
-
1040
1040
  # Center
1041
1041
  C = np.eye(3, dtype=np.float32)
1042
1042
 
@@ -1209,12 +1209,12 @@ class RandomPerspective:
1209
1209
  >>> transform = RandomPerspective()
1210
1210
  >>> image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
1211
1211
  >>> labels = {
1212
- ... 'img': image,
1213
- ... 'cls': np.array([0, 1, 2]),
1214
- ... 'instances': Instances(bboxes=np.array([[10, 10, 50, 50], [100, 100, 150, 150]]))
1212
+ ... "img": image,
1213
+ ... "cls": np.array([0, 1, 2]),
1214
+ ... "instances": Instances(bboxes=np.array([[10, 10, 50, 50], [100, 100, 150, 150]])),
1215
1215
  ... }
1216
1216
  >>> result = transform(labels)
1217
- >>> assert result['img'].shape[:2] == result['resized_shape']
1217
+ >>> assert result["img"].shape[:2] == result["resized_shape"]
1218
1218
  """
1219
1219
  if self.pre_transform and "mosaic_border" not in labels:
1220
1220
  labels = self.pre_transform(labels)
@@ -1358,9 +1358,9 @@ class RandomHSV:
1358
1358
 
1359
1359
  Examples:
1360
1360
  >>> hsv_augmenter = RandomHSV(hgain=0.5, sgain=0.5, vgain=0.5)
1361
- >>> labels = {'img': np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)}
1361
+ >>> labels = {"img": np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)}
1362
1362
  >>> hsv_augmenter(labels)
1363
- >>> augmented_img = labels['img']
1363
+ >>> augmented_img = labels["img"]
1364
1364
  """
1365
1365
  img = labels["img"]
1366
1366
  if self.hgain or self.sgain or self.vgain:
@@ -1394,7 +1394,7 @@ class RandomFlip:
1394
1394
  __call__: Applies the random flip transformation to an image and its annotations.
1395
1395
 
1396
1396
  Examples:
1397
- >>> transform = RandomFlip(p=0.5, direction='horizontal')
1397
+ >>> transform = RandomFlip(p=0.5, direction="horizontal")
1398
1398
  >>> result = transform({"img": image, "instances": instances})
1399
1399
  >>> flipped_image = result["img"]
1400
1400
  >>> flipped_instances = result["instances"]
@@ -1416,8 +1416,8 @@ class RandomFlip:
1416
1416
  AssertionError: If direction is not 'horizontal' or 'vertical', or if p is not between 0 and 1.
1417
1417
 
1418
1418
  Examples:
1419
- >>> flip = RandomFlip(p=0.5, direction='horizontal')
1420
- >>> flip = RandomFlip(p=0.7, direction='vertical', flip_idx=[1, 0, 3, 2, 5, 4])
1419
+ >>> flip = RandomFlip(p=0.5, direction="horizontal")
1420
+ >>> flip = RandomFlip(p=0.7, direction="vertical", flip_idx=[1, 0, 3, 2, 5, 4])
1421
1421
  """
1422
1422
  assert direction in {"horizontal", "vertical"}, f"Support direction `horizontal` or `vertical`, got {direction}"
1423
1423
  assert 0 <= p <= 1.0, f"The probability should be in range [0, 1], but got {p}."
@@ -1446,8 +1446,8 @@ class RandomFlip:
1446
1446
  'instances' (ultralytics.utils.instance.Instances): Updated instances matching the flipped image.
1447
1447
 
1448
1448
  Examples:
1449
- >>> labels = {'img': np.random.rand(640, 640, 3), 'instances': Instances(...)}
1450
- >>> random_flip = RandomFlip(p=0.5, direction='horizontal')
1449
+ >>> labels = {"img": np.random.rand(640, 640, 3), "instances": Instances(...)}
1450
+ >>> random_flip = RandomFlip(p=0.5, direction="horizontal")
1451
1451
  >>> flipped_labels = random_flip(labels)
1452
1452
  """
1453
1453
  img = labels["img"]
@@ -1493,8 +1493,8 @@ class LetterBox:
1493
1493
  Examples:
1494
1494
  >>> transform = LetterBox(new_shape=(640, 640))
1495
1495
  >>> result = transform(labels)
1496
- >>> resized_img = result['img']
1497
- >>> updated_instances = result['instances']
1496
+ >>> resized_img = result["img"]
1497
+ >>> updated_instances = result["instances"]
1498
1498
  """
1499
1499
 
1500
1500
  def __init__(self, new_shape=(640, 640), auto=False, scaleFill=False, scaleup=True, center=True, stride=32):
@@ -1548,9 +1548,9 @@ class LetterBox:
1548
1548
 
1549
1549
  Examples:
1550
1550
  >>> letterbox = LetterBox(new_shape=(640, 640))
1551
- >>> result = letterbox(labels={'img': np.zeros((480, 640, 3)), 'instances': Instances(...)})
1552
- >>> resized_img = result['img']
1553
- >>> updated_instances = result['instances']
1551
+ >>> result = letterbox(labels={"img": np.zeros((480, 640, 3)), "instances": Instances(...)})
1552
+ >>> resized_img = result["img"]
1553
+ >>> updated_instances = result["instances"]
1554
1554
  """
1555
1555
  if labels is None:
1556
1556
  labels = {}
@@ -1616,7 +1616,7 @@ class LetterBox:
1616
1616
 
1617
1617
  Examples:
1618
1618
  >>> letterbox = LetterBox(new_shape=(640, 640))
1619
- >>> labels = {'instances': Instances(...)}
1619
+ >>> labels = {"instances": Instances(...)}
1620
1620
  >>> ratio = (0.5, 0.5)
1621
1621
  >>> padw, padh = 10, 20
1622
1622
  >>> updated_labels = letterbox._update_labels(labels, ratio, padw, padh)
@@ -1643,7 +1643,7 @@ class CopyPaste:
1643
1643
  Examples:
1644
1644
  >>> copypaste = CopyPaste(p=0.5)
1645
1645
  >>> augmented_labels = copypaste(labels)
1646
- >>> augmented_image = augmented_labels['img']
1646
+ >>> augmented_image = augmented_labels["img"]
1647
1647
  """
1648
1648
 
1649
1649
  def __init__(self, p=0.5) -> None:
@@ -1680,7 +1680,7 @@ class CopyPaste:
1680
1680
  (Dict): Dictionary with augmented image and updated instances under 'img', 'cls', and 'instances' keys.
1681
1681
 
1682
1682
  Examples:
1683
- >>> labels = {'img': np.random.rand(640, 640, 3), 'cls': np.array([0, 1, 2]), 'instances': Instances(...)}
1683
+ >>> labels = {"img": np.random.rand(640, 640, 3), "cls": np.array([0, 1, 2]), "instances": Instances(...)}
1684
1684
  >>> augmenter = CopyPaste(p=0.5)
1685
1685
  >>> augmented_labels = augmenter(labels)
1686
1686
  """
@@ -1765,8 +1765,8 @@ class Albumentations:
1765
1765
  Examples:
1766
1766
  >>> transform = Albumentations(p=0.5)
1767
1767
  >>> augmented = transform(image=image, bboxes=bboxes, class_labels=classes)
1768
- >>> augmented_image = augmented['image']
1769
- >>> augmented_bboxes = augmented['bboxes']
1768
+ >>> augmented_image = augmented["image"]
1769
+ >>> augmented_bboxes = augmented["bboxes"]
1770
1770
 
1771
1771
  Notes:
1772
1772
  - Requires Albumentations version 1.0.3 or higher.
@@ -1871,7 +1871,7 @@ class Albumentations:
1871
1871
  >>> labels = {
1872
1872
  ... "img": np.random.rand(640, 640, 3),
1873
1873
  ... "cls": np.array([0, 1]),
1874
- ... "instances": Instances(bboxes=np.array([[0, 0, 1, 1], [0.5, 0.5, 0.8, 0.8]]))
1874
+ ... "instances": Instances(bboxes=np.array([[0, 0, 1, 1], [0.5, 0.5, 0.8, 0.8]])),
1875
1875
  ... }
1876
1876
  >>> augmented = transform(labels)
1877
1877
  >>> assert augmented["img"].shape == (640, 640, 3)
@@ -1927,11 +1927,11 @@ class Format:
1927
1927
  _format_segments: Converts polygon points to bitmap masks.
1928
1928
 
1929
1929
  Examples:
1930
- >>> formatter = Format(bbox_format='xywh', normalize=True, return_mask=True)
1930
+ >>> formatter = Format(bbox_format="xywh", normalize=True, return_mask=True)
1931
1931
  >>> formatted_labels = formatter(labels)
1932
- >>> img = formatted_labels['img']
1933
- >>> bboxes = formatted_labels['bboxes']
1934
- >>> masks = formatted_labels['masks']
1932
+ >>> img = formatted_labels["img"]
1933
+ >>> bboxes = formatted_labels["bboxes"]
1934
+ >>> masks = formatted_labels["masks"]
1935
1935
  """
1936
1936
 
1937
1937
  def __init__(
@@ -1975,7 +1975,7 @@ class Format:
1975
1975
  bgr (float): The probability to return BGR images.
1976
1976
 
1977
1977
  Examples:
1978
- >>> format = Format(bbox_format='xyxy', return_mask=True, return_keypoint=False)
1978
+ >>> format = Format(bbox_format="xyxy", return_mask=True, return_keypoint=False)
1979
1979
  >>> print(format.bbox_format)
1980
1980
  xyxy
1981
1981
  """
@@ -2013,8 +2013,8 @@ class Format:
2013
2013
  - 'batch_idx': Batch index tensor (if batch_idx is True).
2014
2014
 
2015
2015
  Examples:
2016
- >>> formatter = Format(bbox_format='xywh', normalize=True, return_mask=True)
2017
- >>> labels = {'img': np.random.rand(640, 640, 3), 'cls': np.array([0, 1]), 'instances': Instances(...)}
2016
+ >>> formatter = Format(bbox_format="xywh", normalize=True, return_mask=True)
2017
+ >>> labels = {"img": np.random.rand(640, 640, 3), "cls": np.array([0, 1]), "instances": Instances(...)}
2018
2018
  >>> formatted_labels = formatter(labels)
2019
2019
  >>> print(formatted_labels.keys())
2020
2020
  """
@@ -2275,8 +2275,8 @@ def v8_transforms(dataset, imgsz, hyp, stretch=False):
2275
2275
 
2276
2276
  Examples:
2277
2277
  >>> from ultralytics.data.dataset import YOLODataset
2278
- >>> dataset = YOLODataset(img_path='path/to/images', imgsz=640)
2279
- >>> hyp = {'mosaic': 1.0, 'copy_paste': 0.5, 'degrees': 10.0, 'translate': 0.2, 'scale': 0.9}
2278
+ >>> dataset = YOLODataset(img_path="path/to/images", imgsz=640)
2279
+ >>> hyp = {"mosaic": 1.0, "copy_paste": 0.5, "degrees": 10.0, "translate": 0.2, "scale": 0.9}
2280
2280
  >>> transforms = v8_transforms(dataset, imgsz=640, hyp=hyp)
2281
2281
  >>> augmented_data = transforms(dataset[0])
2282
2282
  """
@@ -2343,7 +2343,7 @@ def classify_transforms(
2343
2343
 
2344
2344
  Examples:
2345
2345
  >>> transforms = classify_transforms(size=224)
2346
- >>> img = Image.open('path/to/image.jpg')
2346
+ >>> img = Image.open("path/to/image.jpg")
2347
2347
  >>> transformed_img = transforms(img)
2348
2348
  """
2349
2349
  import torchvision.transforms as T # scope for faster 'import ultralytics'
@@ -2415,7 +2415,7 @@ def classify_augmentations(
2415
2415
  (torchvision.transforms.Compose): A composition of image augmentation transforms.
2416
2416
 
2417
2417
  Examples:
2418
- >>> transforms = classify_augmentations(size=224, auto_augment='randaugment')
2418
+ >>> transforms = classify_augmentations(size=224, auto_augment="randaugment")
2419
2419
  >>> augmented_image = transforms(original_image)
2420
2420
  """
2421
2421
  # Transforms to apply if Albumentations not installed
ultralytics/data/base.py CHANGED
@@ -298,10 +298,10 @@ class BaseDataset(Dataset):
298
298
  im_file=im_file,
299
299
  shape=shape, # format: (height, width)
300
300
  cls=cls,
301
- bboxes=bboxes, # xywh
301
+ bboxes=bboxes, # xywh
302
302
  segments=segments, # xy
303
- keypoints=keypoints, # xy
304
- normalized=True, # or False
303
+ keypoints=keypoints, # xy
304
+ normalized=True, # or False
305
305
  bbox_format="xyxy", # or xywh, ltwh
306
306
  )
307
307
  ```
@@ -115,7 +115,7 @@ def coco91_to_coco80_class():
115
115
 
116
116
 
117
117
  def coco80_to_coco91_class():
118
- """
118
+ r"""
119
119
  Converts 80-index (val2014) to 91-index (paper).
120
120
  For details see https://tech.amikelive.com/node-718/what-object-categories-labels-are-in-coco-dataset/.
121
121
 
@@ -123,8 +123,8 @@ def coco80_to_coco91_class():
123
123
  ```python
124
124
  import numpy as np
125
125
 
126
- a = np.loadtxt('data/coco.names', dtype='str', delimiter='\n')
127
- b = np.loadtxt('data/coco_paper.names', dtype='str', delimiter='\n')
126
+ a = np.loadtxt("data/coco.names", dtype="str", delimiter="\n")
127
+ b = np.loadtxt("data/coco_paper.names", dtype="str", delimiter="\n")
128
128
  x1 = [list(a[i] == b).index(True) + 1 for i in range(80)] # darknet to coco
129
129
  x2 = [list(b[i] == a).index(True) if any(b[i] == a) else None for i in range(91)] # coco to darknet
130
130
  ```
@@ -236,14 +236,13 @@ def convert_coco(
236
236
  ```python
237
237
  from ultralytics.data.converter import convert_coco
238
238
 
239
- convert_coco('../datasets/coco/annotations/', use_segments=True, use_keypoints=False, cls91to80=True)
240
- convert_coco('../datasets/lvis/annotations/', use_segments=True, use_keypoints=False, cls91to80=False, lvis=True)
239
+ convert_coco("../datasets/coco/annotations/", use_segments=True, use_keypoints=False, cls91to80=True)
240
+ convert_coco("../datasets/lvis/annotations/", use_segments=True, use_keypoints=False, cls91to80=False, lvis=True)
241
241
  ```
242
242
 
243
243
  Output:
244
244
  Generates output files in the specified output directory.
245
245
  """
246
-
247
246
  # Create dataset directory
248
247
  save_dir = increment_path(save_dir) # increment if save directory already exists
249
248
  for p in save_dir / "labels", save_dir / "images":
@@ -351,7 +350,7 @@ def convert_segment_masks_to_yolo_seg(masks_dir, output_dir, classes):
351
350
  from ultralytics.data.converter import convert_segment_masks_to_yolo_seg
352
351
 
353
352
  # The classes here is the total classes in the dataset, for COCO dataset we have 80 classes
354
- convert_segment_masks_to_yolo_seg('path/to/masks_directory', 'path/to/output/directory', classes=80)
353
+ convert_segment_masks_to_yolo_seg("path/to/masks_directory", "path/to/output/directory", classes=80)
355
354
  ```
356
355
 
357
356
  Notes:
@@ -429,7 +428,7 @@ def convert_dota_to_yolo_obb(dota_root_path: str):
429
428
  ```python
430
429
  from ultralytics.data.converter import convert_dota_to_yolo_obb
431
430
 
432
- convert_dota_to_yolo_obb('path/to/DOTA')
431
+ convert_dota_to_yolo_obb("path/to/DOTA")
433
432
  ```
434
433
 
435
434
  Notes:
@@ -163,7 +163,7 @@ class Explorer:
163
163
  ```python
164
164
  exp = Explorer()
165
165
  exp.create_embeddings_table()
166
- similar = exp.query(img='https://ultralytics.com/images/zidane.jpg')
166
+ similar = exp.query(img="https://ultralytics.com/images/zidane.jpg")
167
167
  ```
168
168
  """
169
169
  if self.table is None:
@@ -226,6 +226,7 @@ class Explorer:
226
226
  def plot_sql_query(self, query: str, labels: bool = True) -> Image.Image:
227
227
  """
228
228
  Plot the results of a SQL-Like query on the table.
229
+
229
230
  Args:
230
231
  query (str): SQL query to run.
231
232
  labels (bool): Whether to plot the labels or not.
@@ -271,7 +272,7 @@ class Explorer:
271
272
  ```python
272
273
  exp = Explorer()
273
274
  exp.create_embeddings_table()
274
- similar = exp.get_similar(img='https://ultralytics.com/images/zidane.jpg')
275
+ similar = exp.get_similar(img="https://ultralytics.com/images/zidane.jpg")
275
276
  ```
276
277
  """
277
278
  assert return_type in {"pandas", "arrow"}, f"Return type should be `pandas` or `arrow`, but got {return_type}"
@@ -306,7 +307,7 @@ class Explorer:
306
307
  ```python
307
308
  exp = Explorer()
308
309
  exp.create_embeddings_table()
309
- similar = exp.plot_similar(img='https://ultralytics.com/images/zidane.jpg')
310
+ similar = exp.plot_similar(img="https://ultralytics.com/images/zidane.jpg")
310
311
  ```
311
312
  """
312
313
  similar = self.get_similar(img, idx, limit, return_type="arrow")
@@ -395,8 +396,8 @@ class Explorer:
395
396
  exp.create_embeddings_table()
396
397
 
397
398
  similarity_idx_plot = exp.plot_similarity_index()
398
- similarity_idx_plot.show() # view image preview
399
- similarity_idx_plot.save('path/to/save/similarity_index_plot.png') # save contents to file
399
+ similarity_idx_plot.show() # view image preview
400
+ similarity_idx_plot.save("path/to/save/similarity_index_plot.png") # save contents to file
400
401
  ```
401
402
  """
402
403
  sim_idx = self.similarity_index(max_dist=max_dist, top_k=top_k, force=force)
@@ -447,7 +448,7 @@ class Explorer:
447
448
  ```python
448
449
  exp = Explorer()
449
450
  exp.create_embeddings_table()
450
- answer = exp.ask_ai('Show images with 1 person and 2 dogs')
451
+ answer = exp.ask_ai("Show images with 1 person and 2 dogs")
451
452
  ```
452
453
  """
453
454
  result = prompt_sql_query(query)
@@ -457,20 +458,3 @@ class Explorer:
457
458
  LOGGER.error("AI generated query is not valid. Please try again with a different prompt")
458
459
  LOGGER.error(e)
459
460
  return None
460
-
461
- def visualize(self, result):
462
- """
463
- Visualize the results of a query. TODO.
464
-
465
- Args:
466
- result (pyarrow.Table): Table containing the results of a query.
467
- """
468
- pass
469
-
470
- def generate_report(self, result):
471
- """
472
- Generate a report of the dataset.
473
-
474
- TODO
475
- """
476
- pass
@@ -240,7 +240,7 @@ class LoadScreenshots:
240
240
  return self
241
241
 
242
242
  def __next__(self):
243
- """mss screen capture: get raw pixels from the screen as np array."""
243
+ """Screen capture with 'mss' to get raw pixels from the screen as np array."""
244
244
  im0 = np.asarray(self.sct.grab(self.monitor))[:, :, :3] # BGRA to BGR
245
245
  s = f"screen {self.screen} (LTWH): {self.left},{self.top},{self.width},{self.height}: "
246
246