dgenerate-ultralytics-headless 8.3.236__py3-none-any.whl → 8.3.239__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.
Files changed (117) hide show
  1. {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/METADATA +1 -1
  2. {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/RECORD +117 -105
  3. tests/test_exports.py +3 -1
  4. tests/test_python.py +2 -2
  5. tests/test_solutions.py +6 -6
  6. ultralytics/__init__.py +1 -1
  7. ultralytics/cfg/__init__.py +4 -4
  8. ultralytics/cfg/datasets/Argoverse.yaml +7 -6
  9. ultralytics/cfg/datasets/DOTAv1.5.yaml +1 -1
  10. ultralytics/cfg/datasets/DOTAv1.yaml +1 -1
  11. ultralytics/cfg/datasets/VOC.yaml +15 -16
  12. ultralytics/cfg/datasets/african-wildlife.yaml +1 -1
  13. ultralytics/cfg/datasets/coco128-seg.yaml +1 -1
  14. ultralytics/cfg/datasets/dota8-multispectral.yaml +1 -1
  15. ultralytics/cfg/datasets/dota8.yaml +2 -2
  16. ultralytics/cfg/datasets/kitti.yaml +1 -1
  17. ultralytics/cfg/datasets/xView.yaml +16 -16
  18. ultralytics/cfg/models/11/yolo11-pose.yaml +1 -1
  19. ultralytics/cfg/models/11/yoloe-11-seg.yaml +2 -2
  20. ultralytics/cfg/models/11/yoloe-11.yaml +2 -2
  21. ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +9 -6
  22. ultralytics/cfg/models/v8/yoloe-v8.yaml +9 -6
  23. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +1 -1
  24. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +1 -1
  25. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +2 -2
  26. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +2 -2
  27. ultralytics/cfg/models/v8/yolov8-ghost.yaml +2 -2
  28. ultralytics/cfg/models/v8/yolov8-obb.yaml +1 -1
  29. ultralytics/cfg/models/v8/yolov8-p2.yaml +1 -1
  30. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +1 -1
  31. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +1 -1
  32. ultralytics/cfg/models/v8/yolov8-world.yaml +1 -1
  33. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +6 -6
  34. ultralytics/data/augment.py +1 -1
  35. ultralytics/data/base.py +4 -2
  36. ultralytics/data/build.py +4 -4
  37. ultralytics/data/loaders.py +17 -12
  38. ultralytics/data/utils.py +4 -4
  39. ultralytics/engine/exporter.py +40 -25
  40. ultralytics/engine/predictor.py +8 -6
  41. ultralytics/engine/results.py +12 -13
  42. ultralytics/engine/trainer.py +10 -2
  43. ultralytics/engine/tuner.py +2 -3
  44. ultralytics/engine/validator.py +2 -2
  45. ultralytics/models/fastsam/model.py +2 -2
  46. ultralytics/models/fastsam/predict.py +2 -3
  47. ultralytics/models/fastsam/val.py +4 -4
  48. ultralytics/models/rtdetr/predict.py +2 -3
  49. ultralytics/models/rtdetr/val.py +10 -5
  50. ultralytics/models/sam/__init__.py +14 -1
  51. ultralytics/models/sam/build.py +22 -13
  52. ultralytics/models/sam/build_sam3.py +377 -0
  53. ultralytics/models/sam/model.py +13 -5
  54. ultralytics/models/sam/modules/blocks.py +20 -8
  55. ultralytics/models/sam/modules/decoders.py +2 -3
  56. ultralytics/models/sam/modules/encoders.py +4 -1
  57. ultralytics/models/sam/modules/memory_attention.py +6 -2
  58. ultralytics/models/sam/modules/sam.py +159 -10
  59. ultralytics/models/sam/modules/utils.py +134 -4
  60. ultralytics/models/sam/predict.py +2073 -139
  61. ultralytics/models/sam/sam3/__init__.py +3 -0
  62. ultralytics/models/sam/sam3/decoder.py +546 -0
  63. ultralytics/models/sam/sam3/encoder.py +535 -0
  64. ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
  65. ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
  66. ultralytics/models/sam/sam3/model_misc.py +198 -0
  67. ultralytics/models/sam/sam3/necks.py +129 -0
  68. ultralytics/models/sam/sam3/sam3_image.py +339 -0
  69. ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
  70. ultralytics/models/sam/sam3/vitdet.py +546 -0
  71. ultralytics/models/sam/sam3/vl_combiner.py +160 -0
  72. ultralytics/models/yolo/classify/val.py +1 -1
  73. ultralytics/models/yolo/detect/train.py +1 -1
  74. ultralytics/models/yolo/detect/val.py +7 -7
  75. ultralytics/models/yolo/obb/val.py +19 -8
  76. ultralytics/models/yolo/pose/val.py +1 -1
  77. ultralytics/models/yolo/segment/val.py +1 -1
  78. ultralytics/nn/autobackend.py +9 -9
  79. ultralytics/nn/modules/block.py +1 -1
  80. ultralytics/nn/modules/transformer.py +21 -1
  81. ultralytics/nn/tasks.py +3 -3
  82. ultralytics/nn/text_model.py +2 -7
  83. ultralytics/solutions/ai_gym.py +1 -1
  84. ultralytics/solutions/analytics.py +6 -6
  85. ultralytics/solutions/config.py +1 -1
  86. ultralytics/solutions/distance_calculation.py +1 -1
  87. ultralytics/solutions/object_counter.py +1 -1
  88. ultralytics/solutions/object_cropper.py +3 -6
  89. ultralytics/solutions/parking_management.py +21 -17
  90. ultralytics/solutions/queue_management.py +5 -5
  91. ultralytics/solutions/region_counter.py +2 -2
  92. ultralytics/solutions/security_alarm.py +1 -1
  93. ultralytics/solutions/solutions.py +45 -22
  94. ultralytics/solutions/speed_estimation.py +1 -1
  95. ultralytics/trackers/basetrack.py +1 -1
  96. ultralytics/trackers/bot_sort.py +4 -3
  97. ultralytics/trackers/byte_tracker.py +4 -4
  98. ultralytics/trackers/utils/gmc.py +6 -7
  99. ultralytics/trackers/utils/kalman_filter.py +2 -1
  100. ultralytics/trackers/utils/matching.py +4 -3
  101. ultralytics/utils/__init__.py +12 -3
  102. ultralytics/utils/benchmarks.py +2 -2
  103. ultralytics/utils/callbacks/tensorboard.py +19 -25
  104. ultralytics/utils/checks.py +4 -3
  105. ultralytics/utils/downloads.py +1 -1
  106. ultralytics/utils/export/tensorflow.py +16 -2
  107. ultralytics/utils/files.py +13 -12
  108. ultralytics/utils/logger.py +62 -27
  109. ultralytics/utils/metrics.py +1 -1
  110. ultralytics/utils/ops.py +7 -9
  111. ultralytics/utils/patches.py +3 -3
  112. ultralytics/utils/plotting.py +7 -12
  113. ultralytics/utils/tuner.py +1 -1
  114. {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/WHEEL +0 -0
  115. {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/entry_points.txt +0 -0
  116. {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/licenses/LICENSE +0 -0
  117. {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/top_level.txt +0 -0
@@ -28,15 +28,15 @@ class WorkingDirectory(contextlib.ContextDecorator):
28
28
 
29
29
  Examples:
30
30
  Using as a context manager:
31
- >>> with WorkingDirectory('/path/to/new/dir'):
32
- >>> # Perform operations in the new directory
33
- >>> pass
31
+ >>> with WorkingDirectory("/path/to/new/dir"):
32
+ ... # Perform operations in the new directory
33
+ ... pass
34
34
 
35
35
  Using as a decorator:
36
- >>> @WorkingDirectory('/path/to/new/dir')
37
- >>> def some_function():
38
- >>> # Perform operations in the new directory
39
- >>> pass
36
+ >>> @WorkingDirectory("/path/to/new/dir")
37
+ ... def some_function():
38
+ ... # Perform operations in the new directory
39
+ ... pass
40
40
  """
41
41
 
42
42
  def __init__(self, new_dir: str | Path):
@@ -67,9 +67,9 @@ def spaces_in_path(path: str | Path):
67
67
  (Path | str): Temporary path with any spaces replaced by underscores.
68
68
 
69
69
  Examples:
70
- >>> with spaces_in_path('/path/with spaces') as new_path:
71
- >>> # Your code here
72
- >>> pass
70
+ >>> with spaces_in_path("/path/with spaces") as new_path:
71
+ ... # Your code here
72
+ ... pass
73
73
  """
74
74
  # If path has spaces, replace them with underscores
75
75
  if " " in str(path):
@@ -196,13 +196,14 @@ def update_models(model_names: tuple = ("yolo11n.pt",), source_dir: Path = Path(
196
196
  """
197
197
  from ultralytics import YOLO
198
198
  from ultralytics.nn.autobackend import default_class_names
199
+ from ultralytics.utils import LOGGER
199
200
 
200
201
  target_dir = source_dir / "updated_models"
201
202
  target_dir.mkdir(parents=True, exist_ok=True) # Ensure target directory exists
202
203
 
203
204
  for model_name in model_names:
204
205
  model_path = source_dir / model_name
205
- print(f"Loading model from {model_path}")
206
+ LOGGER.info(f"Loading model from {model_path}")
206
207
 
207
208
  # Load model
208
209
  model = YOLO(model_path)
@@ -214,5 +215,5 @@ def update_models(model_names: tuple = ("yolo11n.pt",), source_dir: Path = Path(
214
215
  save_path = target_dir / model_name
215
216
 
216
217
  # Save model using model.save()
217
- print(f"Re-saving {model_name} model to {save_path}")
218
+ LOGGER.info(f"Re-saving {model_name} model to {save_path}")
218
219
  model.save(save_path)
@@ -267,6 +267,11 @@ class SystemLogger:
267
267
  self.net_start = psutil.net_io_counters()
268
268
  self.disk_start = psutil.disk_io_counters()
269
269
 
270
+ # For rate calculation
271
+ self._prev_net = self.net_start
272
+ self._prev_disk = self.disk_start
273
+ self._prev_time = time.time()
274
+
270
275
  def _init_nvidia(self):
271
276
  """Initialize NVIDIA GPU monitoring with pynvml."""
272
277
  try:
@@ -278,42 +283,49 @@ class SystemLogger:
278
283
  except Exception:
279
284
  return False
280
285
 
281
- def get_metrics(self):
282
- """Get current system metrics.
286
+ def get_metrics(self, rates=False):
287
+ """Get current system metrics including CPU, RAM, disk, network, and GPU usage.
283
288
 
284
289
  Collects comprehensive system metrics including CPU usage, RAM usage, disk I/O statistics, network I/O
285
- statistics, and GPU metrics (if available). Example output:
290
+ statistics, and GPU metrics (if available).
286
291
 
292
+ Example output (rates=False, default):
287
293
  ```python
288
- metrics = {
294
+ {
289
295
  "cpu": 45.2,
290
296
  "ram": 78.9,
291
297
  "disk": {"read_mb": 156.7, "write_mb": 89.3, "used_gb": 256.8},
292
298
  "network": {"recv_mb": 157.2, "sent_mb": 89.1},
293
299
  "gpus": {
294
- 0: {"usage": 95.6, "memory": 85.4, "temp": 72, "power": 285},
295
- 1: {"usage": 94.1, "memory": 82.7, "temp": 70, "power": 278},
300
+ "0": {"usage": 95.6, "memory": 85.4, "temp": 72, "power": 285},
301
+ "1": {"usage": 94.1, "memory": 82.7, "temp": 70, "power": 278},
296
302
  },
297
303
  }
298
304
  ```
299
305
 
300
- - cpu (float): CPU usage percentage (0-100%)
301
- - ram (float): RAM usage percentage (0-100%)
302
- - disk (dict):
303
- - read_mb (float): Cumulative disk read in MB since initialization
304
- - write_mb (float): Cumulative disk write in MB since initialization
305
- - used_gb (float): Total disk space used in GB
306
- - network (dict):
307
- - recv_mb (float): Cumulative network received in MB since initialization
308
- - sent_mb (float): Cumulative network sent in MB since initialization
309
- - gpus (dict): GPU metrics by device index (e.g., 0, 1) containing:
310
- - usage (int): GPU utilization percentage (0-100%)
311
- - memory (float): CUDA memory usage percentage (0-100%)
312
- - temp (int): GPU temperature in degrees Celsius
313
- - power (int): GPU power consumption in watts
306
+ Example output (rates=True):
307
+ ```python
308
+ {
309
+ "cpu": 45.2,
310
+ "ram": 78.9,
311
+ "disk": {"read_mbs": 12.5, "write_mbs": 8.3, "used_gb": 256.8},
312
+ "network": {"recv_mbs": 5.2, "sent_mbs": 1.1},
313
+ "gpus": {
314
+ "0": {"usage": 95.6, "memory": 85.4, "temp": 72, "power": 285},
315
+ },
316
+ }
317
+ ```
318
+
319
+ Args:
320
+ rates (bool): If True, return disk/network as MB/s rates instead of cumulative MB.
314
321
 
315
322
  Returns:
316
- metrics (dict): System metrics containing 'cpu', 'ram', 'disk', 'network', 'gpus' with usage data.
323
+ (dict): Metrics dictionary with cpu, ram, disk, network, and gpus keys.
324
+
325
+ Examples:
326
+ >>> logger = SystemLogger()
327
+ >>> logger.get_metrics()["cpu"] # CPU percentage
328
+ >>> logger.get_metrics(rates=True)["network"]["recv_mbs"] # MB/s download rate
317
329
  """
318
330
  import psutil # scoped as slow import
319
331
 
@@ -321,21 +333,44 @@ class SystemLogger:
321
333
  disk = psutil.disk_io_counters()
322
334
  memory = psutil.virtual_memory()
323
335
  disk_usage = shutil.disk_usage("/")
336
+ now = time.time()
324
337
 
325
338
  metrics = {
326
339
  "cpu": round(psutil.cpu_percent(), 3),
327
340
  "ram": round(memory.percent, 3),
328
- "disk": {
341
+ "gpus": {},
342
+ }
343
+
344
+ # Calculate elapsed time since last call
345
+ elapsed = max(0.1, now - self._prev_time) # Avoid division by zero
346
+
347
+ if rates:
348
+ # Calculate MB/s rates from delta since last call
349
+ metrics["disk"] = {
350
+ "read_mbs": round(max(0, (disk.read_bytes - self._prev_disk.read_bytes) / (1 << 20) / elapsed), 3),
351
+ "write_mbs": round(max(0, (disk.write_bytes - self._prev_disk.write_bytes) / (1 << 20) / elapsed), 3),
352
+ "used_gb": round(disk_usage.used / (1 << 30), 3),
353
+ }
354
+ metrics["network"] = {
355
+ "recv_mbs": round(max(0, (net.bytes_recv - self._prev_net.bytes_recv) / (1 << 20) / elapsed), 3),
356
+ "sent_mbs": round(max(0, (net.bytes_sent - self._prev_net.bytes_sent) / (1 << 20) / elapsed), 3),
357
+ }
358
+ else:
359
+ # Cumulative MB since initialization (original behavior)
360
+ metrics["disk"] = {
329
361
  "read_mb": round((disk.read_bytes - self.disk_start.read_bytes) / (1 << 20), 3),
330
362
  "write_mb": round((disk.write_bytes - self.disk_start.write_bytes) / (1 << 20), 3),
331
363
  "used_gb": round(disk_usage.used / (1 << 30), 3),
332
- },
333
- "network": {
364
+ }
365
+ metrics["network"] = {
334
366
  "recv_mb": round((net.bytes_recv - self.net_start.bytes_recv) / (1 << 20), 3),
335
367
  "sent_mb": round((net.bytes_sent - self.net_start.bytes_sent) / (1 << 20), 3),
336
- },
337
- "gpus": {},
338
- }
368
+ }
369
+
370
+ # Always update previous values for accurate rate calculation on next call
371
+ self._prev_net = net
372
+ self._prev_disk = disk
373
+ self._prev_time = now
339
374
 
340
375
  # Add GPU metrics (NVIDIA only)
341
376
  if self.nvidia_initialized:
@@ -309,7 +309,7 @@ class ConfusionMatrix(DataExportMixin):
309
309
  Attributes:
310
310
  task (str): The type of task, either 'detect' or 'classify'.
311
311
  matrix (np.ndarray): The confusion matrix, with dimensions depending on the task.
312
- nc (int): The number of category.
312
+ nc (int): The number of classes.
313
313
  names (list[str]): The names of the classes, used as labels on the plot.
314
314
  matches (dict): Contains the indices of ground truths and predictions categorized into TP, FP and FN.
315
315
  """
ultralytics/utils/ops.py CHANGED
@@ -298,7 +298,7 @@ def xywh2ltwh(x):
298
298
  x (np.ndarray | torch.Tensor): Input bounding box coordinates in xywh format.
299
299
 
300
300
  Returns:
301
- (np.ndarray | torch.Tensor): Bounding box coordinates in xyltwh format.
301
+ (np.ndarray | torch.Tensor): Bounding box coordinates in ltwh format.
302
302
  """
303
303
  y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
304
304
  y[..., 0] = x[..., 0] - x[..., 2] / 2 # top left x
@@ -313,7 +313,7 @@ def xyxy2ltwh(x):
313
313
  x (np.ndarray | torch.Tensor): Input bounding box coordinates in xyxy format.
314
314
 
315
315
  Returns:
316
- (np.ndarray | torch.Tensor): Bounding box coordinates in xyltwh format.
316
+ (np.ndarray | torch.Tensor): Bounding box coordinates in ltwh format.
317
317
  """
318
318
  y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
319
319
  y[..., 2] = x[..., 2] - x[..., 0] # width
@@ -325,7 +325,7 @@ def ltwh2xywh(x):
325
325
  """Convert bounding boxes from [x1, y1, w, h] to [x, y, w, h] where xy1=top-left, xy=center.
326
326
 
327
327
  Args:
328
- x (torch.Tensor): Input bounding box coordinates.
328
+ x (np.ndarray | torch.Tensor): Input bounding box coordinates.
329
329
 
330
330
  Returns:
331
331
  (np.ndarray | torch.Tensor): Bounding box coordinates in xywh format.
@@ -398,8 +398,8 @@ def ltwh2xyxy(x):
398
398
  (np.ndarray | torch.Tensor): Bounding box coordinates in xyxy format.
399
399
  """
400
400
  y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
401
- y[..., 2] = x[..., 2] + x[..., 0] # width
402
- y[..., 3] = x[..., 3] + x[..., 1] # height
401
+ y[..., 2] = x[..., 2] + x[..., 0] # x2
402
+ y[..., 3] = x[..., 3] + x[..., 1] # y2
403
403
  return y
404
404
 
405
405
 
@@ -655,11 +655,9 @@ def clean_str(s):
655
655
  Returns:
656
656
  (str): A string with special characters replaced by an underscore _.
657
657
  """
658
- return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨´><+]", repl="_", string=s)
658
+ return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨`><+]", repl="_", string=s)
659
659
 
660
660
 
661
661
  def empty_like(x):
662
662
  """Create empty torch.Tensor or np.ndarray with same shape as input and float32 dtype."""
663
- return (
664
- torch.empty_like(x, dtype=torch.float32) if isinstance(x, torch.Tensor) else np.empty_like(x, dtype=np.float32)
665
- )
663
+ return torch.empty_like(x, dtype=x.dtype) if isinstance(x, torch.Tensor) else np.empty_like(x, dtype=x.dtype)
@@ -35,7 +35,7 @@ def imread(filename: str, flags: int = cv2.IMREAD_COLOR) -> np.ndarray | None:
35
35
  if filename.endswith((".tiff", ".tif")):
36
36
  success, frames = cv2.imdecodemulti(file_bytes, cv2.IMREAD_UNCHANGED)
37
37
  if success:
38
- # Handle RGB images in tif/tiff format
38
+ # Handle multi-frame TIFFs and color images
39
39
  return frames[0] if len(frames) == 1 and frames[0].ndim == 3 else np.stack(frames, axis=2)
40
40
  return None
41
41
  else:
@@ -105,8 +105,8 @@ def torch_load(*args, **kwargs):
105
105
  (Any): The loaded PyTorch object.
106
106
 
107
107
  Notes:
108
- For PyTorch versions 2.0 and above, this function automatically sets 'weights_only=False'
109
- if the argument is not provided, to avoid deprecation warnings.
108
+ For PyTorch versions 1.13 and above, this function automatically sets `weights_only=False` if the argument is
109
+ not provided, to avoid deprecation warnings.
110
110
  """
111
111
  from ultralytics.utils.torch_utils import TORCH_1_13
112
112
 
@@ -3,7 +3,6 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import math
6
- import warnings
7
6
  from collections.abc import Callable
8
7
  from pathlib import Path
9
8
  from typing import Any
@@ -511,7 +510,7 @@ class Annotator:
511
510
  cv2.putText(self.im, text, xy, 0, self.sf, txt_color, thickness=self.tf, lineType=cv2.LINE_AA)
512
511
 
513
512
  def fromarray(self, im):
514
- """Update self.im from a numpy array."""
513
+ """Update `self.im` from a NumPy array or PIL image."""
515
514
  self.im = im if isinstance(im, Image.Image) else Image.fromarray(im)
516
515
  self.draw = ImageDraw.Draw(self.im)
517
516
 
@@ -522,8 +521,8 @@ class Annotator:
522
521
 
523
522
  def show(self, title: str | None = None):
524
523
  """Show the annotated image."""
525
- im = Image.fromarray(np.asarray(self.im)[..., ::-1]) # Convert numpy array to PIL Image with RGB to BGR
526
- if IS_COLAB or IS_KAGGLE: # can not use IS_JUPYTER as will run for all ipython environments
524
+ im = Image.fromarray(np.asarray(self.im)[..., ::-1]) # Convert BGR NumPy array to RGB PIL Image
525
+ if IS_COLAB or IS_KAGGLE: # cannot use IS_JUPYTER as it runs for all IPython environments
527
526
  try:
528
527
  display(im) # noqa - display() function only available in ipython environments
529
528
  except ImportError as e:
@@ -536,11 +535,11 @@ class Annotator:
536
535
  cv2.imwrite(filename, np.asarray(self.im))
537
536
 
538
537
  @staticmethod
539
- def get_bbox_dimension(bbox: tuple | None = None):
538
+ def get_bbox_dimension(bbox: tuple | list):
540
539
  """Calculate the dimensions and area of a bounding box.
541
540
 
542
541
  Args:
543
- bbox (tuple): Bounding box coordinates in the format (x_min, y_min, x_max, y_max).
542
+ bbox (tuple | list): Bounding box coordinates in the format (x_min, y_min, x_max, y_max).
544
543
 
545
544
  Returns:
546
545
  width (float): Width of the bounding box.
@@ -575,10 +574,6 @@ def plot_labels(boxes, cls, names=(), save_dir=Path(""), on_plot=None):
575
574
  import polars
576
575
  from matplotlib.colors import LinearSegmentedColormap
577
576
 
578
- # Filter matplotlib>=3.7.2 warning
579
- warnings.filterwarnings("ignore", category=UserWarning, message="The figure layout has changed to tight")
580
- warnings.filterwarnings("ignore", category=FutureWarning)
581
-
582
577
  # Plot dataset labels
583
578
  LOGGER.info(f"Plotting labels to {save_dir / 'labels.jpg'}... ")
584
579
  nc = int(cls.max() + 1) # number of classes
@@ -600,8 +595,8 @@ def plot_labels(boxes, cls, names=(), save_dir=Path(""), on_plot=None):
600
595
  ax[0].set_xlabel("classes")
601
596
  boxes = np.column_stack([0.5 - boxes[:, 2:4] / 2, 0.5 + boxes[:, 2:4] / 2]) * 1000
602
597
  img = Image.fromarray(np.ones((1000, 1000, 3), dtype=np.uint8) * 255)
603
- for cls, box in zip(cls[:500], boxes[:500]):
604
- ImageDraw.Draw(img).rectangle(box.tolist(), width=1, outline=colors(cls)) # plot
598
+ for class_id, box in zip(cls[:500], boxes[:500]):
599
+ ImageDraw.Draw(img).rectangle(box.tolist(), width=1, outline=colors(class_id)) # plot
605
600
  ax[1].imshow(img)
606
601
  ax[1].axis("off")
607
602
 
@@ -77,7 +77,7 @@ def run_ray_tune(
77
77
  "perspective": tune.uniform(0.0, 0.001), # image perspective (+/- fraction), range 0-0.001
78
78
  "flipud": tune.uniform(0.0, 1.0), # image flip up-down (probability)
79
79
  "fliplr": tune.uniform(0.0, 1.0), # image flip left-right (probability)
80
- "bgr": tune.uniform(0.0, 1.0), # image channel BGR (probability)
80
+ "bgr": tune.uniform(0.0, 1.0), # swap RGB↔BGR channels (probability)
81
81
  "mosaic": tune.uniform(0.0, 1.0), # image mosaic (probability)
82
82
  "mixup": tune.uniform(0.0, 1.0), # image mixup (probability)
83
83
  "cutmix": tune.uniform(0.0, 1.0), # image cutmix (probability)