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.
- {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/METADATA +1 -1
- {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/RECORD +117 -105
- tests/test_exports.py +3 -1
- tests/test_python.py +2 -2
- tests/test_solutions.py +6 -6
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/__init__.py +4 -4
- ultralytics/cfg/datasets/Argoverse.yaml +7 -6
- ultralytics/cfg/datasets/DOTAv1.5.yaml +1 -1
- ultralytics/cfg/datasets/DOTAv1.yaml +1 -1
- ultralytics/cfg/datasets/VOC.yaml +15 -16
- ultralytics/cfg/datasets/african-wildlife.yaml +1 -1
- ultralytics/cfg/datasets/coco128-seg.yaml +1 -1
- ultralytics/cfg/datasets/dota8-multispectral.yaml +1 -1
- ultralytics/cfg/datasets/dota8.yaml +2 -2
- ultralytics/cfg/datasets/kitti.yaml +1 -1
- ultralytics/cfg/datasets/xView.yaml +16 -16
- ultralytics/cfg/models/11/yolo11-pose.yaml +1 -1
- ultralytics/cfg/models/11/yoloe-11-seg.yaml +2 -2
- ultralytics/cfg/models/11/yoloe-11.yaml +2 -2
- ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +9 -6
- ultralytics/cfg/models/v8/yoloe-v8.yaml +9 -6
- ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +2 -2
- ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +2 -2
- ultralytics/cfg/models/v8/yolov8-ghost.yaml +2 -2
- ultralytics/cfg/models/v8/yolov8-obb.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-p2.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-world.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-worldv2.yaml +6 -6
- ultralytics/data/augment.py +1 -1
- ultralytics/data/base.py +4 -2
- ultralytics/data/build.py +4 -4
- ultralytics/data/loaders.py +17 -12
- ultralytics/data/utils.py +4 -4
- ultralytics/engine/exporter.py +40 -25
- ultralytics/engine/predictor.py +8 -6
- ultralytics/engine/results.py +12 -13
- ultralytics/engine/trainer.py +10 -2
- ultralytics/engine/tuner.py +2 -3
- ultralytics/engine/validator.py +2 -2
- ultralytics/models/fastsam/model.py +2 -2
- ultralytics/models/fastsam/predict.py +2 -3
- ultralytics/models/fastsam/val.py +4 -4
- ultralytics/models/rtdetr/predict.py +2 -3
- ultralytics/models/rtdetr/val.py +10 -5
- ultralytics/models/sam/__init__.py +14 -1
- ultralytics/models/sam/build.py +22 -13
- ultralytics/models/sam/build_sam3.py +377 -0
- ultralytics/models/sam/model.py +13 -5
- ultralytics/models/sam/modules/blocks.py +20 -8
- ultralytics/models/sam/modules/decoders.py +2 -3
- ultralytics/models/sam/modules/encoders.py +4 -1
- ultralytics/models/sam/modules/memory_attention.py +6 -2
- ultralytics/models/sam/modules/sam.py +159 -10
- ultralytics/models/sam/modules/utils.py +134 -4
- ultralytics/models/sam/predict.py +2073 -139
- ultralytics/models/sam/sam3/__init__.py +3 -0
- ultralytics/models/sam/sam3/decoder.py +546 -0
- ultralytics/models/sam/sam3/encoder.py +535 -0
- ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
- ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
- ultralytics/models/sam/sam3/model_misc.py +198 -0
- ultralytics/models/sam/sam3/necks.py +129 -0
- ultralytics/models/sam/sam3/sam3_image.py +339 -0
- ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
- ultralytics/models/sam/sam3/vitdet.py +546 -0
- ultralytics/models/sam/sam3/vl_combiner.py +160 -0
- ultralytics/models/yolo/classify/val.py +1 -1
- ultralytics/models/yolo/detect/train.py +1 -1
- ultralytics/models/yolo/detect/val.py +7 -7
- ultralytics/models/yolo/obb/val.py +19 -8
- ultralytics/models/yolo/pose/val.py +1 -1
- ultralytics/models/yolo/segment/val.py +1 -1
- ultralytics/nn/autobackend.py +9 -9
- ultralytics/nn/modules/block.py +1 -1
- ultralytics/nn/modules/transformer.py +21 -1
- ultralytics/nn/tasks.py +3 -3
- ultralytics/nn/text_model.py +2 -7
- ultralytics/solutions/ai_gym.py +1 -1
- ultralytics/solutions/analytics.py +6 -6
- ultralytics/solutions/config.py +1 -1
- ultralytics/solutions/distance_calculation.py +1 -1
- ultralytics/solutions/object_counter.py +1 -1
- ultralytics/solutions/object_cropper.py +3 -6
- ultralytics/solutions/parking_management.py +21 -17
- ultralytics/solutions/queue_management.py +5 -5
- ultralytics/solutions/region_counter.py +2 -2
- ultralytics/solutions/security_alarm.py +1 -1
- ultralytics/solutions/solutions.py +45 -22
- ultralytics/solutions/speed_estimation.py +1 -1
- ultralytics/trackers/basetrack.py +1 -1
- ultralytics/trackers/bot_sort.py +4 -3
- ultralytics/trackers/byte_tracker.py +4 -4
- ultralytics/trackers/utils/gmc.py +6 -7
- ultralytics/trackers/utils/kalman_filter.py +2 -1
- ultralytics/trackers/utils/matching.py +4 -3
- ultralytics/utils/__init__.py +12 -3
- ultralytics/utils/benchmarks.py +2 -2
- ultralytics/utils/callbacks/tensorboard.py +19 -25
- ultralytics/utils/checks.py +4 -3
- ultralytics/utils/downloads.py +1 -1
- ultralytics/utils/export/tensorflow.py +16 -2
- ultralytics/utils/files.py +13 -12
- ultralytics/utils/logger.py +62 -27
- ultralytics/utils/metrics.py +1 -1
- ultralytics/utils/ops.py +7 -9
- ultralytics/utils/patches.py +3 -3
- ultralytics/utils/plotting.py +7 -12
- ultralytics/utils/tuner.py +1 -1
- {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/WHEEL +0 -0
- {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.236.dist-info → dgenerate_ultralytics_headless-8.3.239.dist-info}/top_level.txt +0 -0
ultralytics/utils/files.py
CHANGED
|
@@ -28,15 +28,15 @@ class WorkingDirectory(contextlib.ContextDecorator):
|
|
|
28
28
|
|
|
29
29
|
Examples:
|
|
30
30
|
Using as a context manager:
|
|
31
|
-
>>> with WorkingDirectory(
|
|
32
|
-
|
|
33
|
-
|
|
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(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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(
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
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
|
-
|
|
218
|
+
LOGGER.info(f"Re-saving {model_name} model to {save_path}")
|
|
218
219
|
model.save(save_path)
|
ultralytics/utils/logger.py
CHANGED
|
@@ -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).
|
|
290
|
+
statistics, and GPU metrics (if available).
|
|
286
291
|
|
|
292
|
+
Example output (rates=False, default):
|
|
287
293
|
```python
|
|
288
|
-
|
|
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
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
-
|
|
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:
|
ultralytics/utils/metrics.py
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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] #
|
|
402
|
-
y[..., 3] = x[..., 3] + x[..., 1] #
|
|
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="[|@#!¡·$€%&()
|
|
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)
|
ultralytics/utils/patches.py
CHANGED
|
@@ -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
|
|
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
|
|
109
|
-
|
|
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
|
|
ultralytics/utils/plotting.py
CHANGED
|
@@ -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
|
|
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
|
|
526
|
-
if IS_COLAB or IS_KAGGLE: #
|
|
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 |
|
|
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
|
|
604
|
-
ImageDraw.Draw(img).rectangle(box.tolist(), width=1, outline=colors(
|
|
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
|
|
ultralytics/utils/tuner.py
CHANGED
|
@@ -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), #
|
|
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)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|