dgenerate-ultralytics-headless 8.3.137__py3-none-any.whl → 8.3.224__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.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/METADATA +41 -34
- dgenerate_ultralytics_headless-8.3.224.dist-info/RECORD +285 -0
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/WHEEL +1 -1
- tests/__init__.py +7 -6
- tests/conftest.py +15 -39
- tests/test_cli.py +17 -17
- tests/test_cuda.py +17 -8
- tests/test_engine.py +36 -10
- tests/test_exports.py +98 -37
- tests/test_integrations.py +12 -15
- tests/test_python.py +126 -82
- tests/test_solutions.py +319 -135
- ultralytics/__init__.py +27 -9
- ultralytics/cfg/__init__.py +83 -87
- ultralytics/cfg/datasets/Argoverse.yaml +4 -4
- ultralytics/cfg/datasets/DOTAv1.5.yaml +2 -2
- ultralytics/cfg/datasets/DOTAv1.yaml +2 -2
- ultralytics/cfg/datasets/GlobalWheat2020.yaml +2 -2
- ultralytics/cfg/datasets/HomeObjects-3K.yaml +4 -5
- ultralytics/cfg/datasets/ImageNet.yaml +3 -3
- ultralytics/cfg/datasets/Objects365.yaml +24 -20
- ultralytics/cfg/datasets/SKU-110K.yaml +9 -9
- ultralytics/cfg/datasets/VOC.yaml +10 -13
- ultralytics/cfg/datasets/VisDrone.yaml +43 -33
- ultralytics/cfg/datasets/african-wildlife.yaml +5 -5
- ultralytics/cfg/datasets/brain-tumor.yaml +4 -5
- ultralytics/cfg/datasets/carparts-seg.yaml +5 -5
- ultralytics/cfg/datasets/coco-pose.yaml +26 -4
- ultralytics/cfg/datasets/coco.yaml +4 -4
- ultralytics/cfg/datasets/coco128-seg.yaml +2 -2
- ultralytics/cfg/datasets/coco128.yaml +2 -2
- ultralytics/cfg/datasets/coco8-grayscale.yaml +103 -0
- ultralytics/cfg/datasets/coco8-multispectral.yaml +2 -2
- ultralytics/cfg/datasets/coco8-pose.yaml +23 -2
- ultralytics/cfg/datasets/coco8-seg.yaml +2 -2
- ultralytics/cfg/datasets/coco8.yaml +2 -2
- ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
- ultralytics/cfg/datasets/crack-seg.yaml +5 -5
- ultralytics/cfg/datasets/dog-pose.yaml +32 -4
- ultralytics/cfg/datasets/dota8-multispectral.yaml +2 -2
- ultralytics/cfg/datasets/dota8.yaml +2 -2
- ultralytics/cfg/datasets/hand-keypoints.yaml +29 -4
- ultralytics/cfg/datasets/lvis.yaml +9 -9
- ultralytics/cfg/datasets/medical-pills.yaml +4 -5
- ultralytics/cfg/datasets/open-images-v7.yaml +7 -10
- ultralytics/cfg/datasets/package-seg.yaml +5 -5
- ultralytics/cfg/datasets/signature.yaml +4 -4
- ultralytics/cfg/datasets/tiger-pose.yaml +20 -4
- ultralytics/cfg/datasets/xView.yaml +5 -5
- ultralytics/cfg/default.yaml +96 -93
- ultralytics/cfg/trackers/botsort.yaml +16 -17
- ultralytics/cfg/trackers/bytetrack.yaml +9 -11
- ultralytics/data/__init__.py +4 -4
- ultralytics/data/annotator.py +12 -12
- ultralytics/data/augment.py +531 -564
- ultralytics/data/base.py +76 -81
- ultralytics/data/build.py +206 -42
- ultralytics/data/converter.py +179 -78
- ultralytics/data/dataset.py +121 -121
- ultralytics/data/loaders.py +114 -91
- ultralytics/data/split.py +28 -15
- ultralytics/data/split_dota.py +67 -48
- ultralytics/data/utils.py +110 -89
- ultralytics/engine/exporter.py +422 -460
- ultralytics/engine/model.py +224 -252
- ultralytics/engine/predictor.py +94 -89
- ultralytics/engine/results.py +345 -595
- ultralytics/engine/trainer.py +231 -134
- ultralytics/engine/tuner.py +279 -73
- ultralytics/engine/validator.py +53 -46
- ultralytics/hub/__init__.py +26 -28
- ultralytics/hub/auth.py +30 -16
- ultralytics/hub/google/__init__.py +34 -36
- ultralytics/hub/session.py +53 -77
- ultralytics/hub/utils.py +23 -109
- ultralytics/models/__init__.py +1 -1
- ultralytics/models/fastsam/__init__.py +1 -1
- ultralytics/models/fastsam/model.py +36 -18
- ultralytics/models/fastsam/predict.py +33 -44
- ultralytics/models/fastsam/utils.py +4 -5
- ultralytics/models/fastsam/val.py +12 -14
- ultralytics/models/nas/__init__.py +1 -1
- ultralytics/models/nas/model.py +16 -20
- ultralytics/models/nas/predict.py +12 -14
- ultralytics/models/nas/val.py +4 -5
- ultralytics/models/rtdetr/__init__.py +1 -1
- ultralytics/models/rtdetr/model.py +9 -9
- ultralytics/models/rtdetr/predict.py +22 -17
- ultralytics/models/rtdetr/train.py +20 -16
- ultralytics/models/rtdetr/val.py +79 -59
- ultralytics/models/sam/__init__.py +8 -2
- ultralytics/models/sam/amg.py +53 -38
- ultralytics/models/sam/build.py +29 -31
- ultralytics/models/sam/model.py +33 -38
- ultralytics/models/sam/modules/blocks.py +159 -182
- ultralytics/models/sam/modules/decoders.py +38 -47
- ultralytics/models/sam/modules/encoders.py +114 -133
- ultralytics/models/sam/modules/memory_attention.py +38 -31
- ultralytics/models/sam/modules/sam.py +114 -93
- ultralytics/models/sam/modules/tiny_encoder.py +268 -291
- ultralytics/models/sam/modules/transformer.py +59 -66
- ultralytics/models/sam/modules/utils.py +55 -72
- ultralytics/models/sam/predict.py +745 -341
- ultralytics/models/utils/loss.py +118 -107
- ultralytics/models/utils/ops.py +118 -71
- ultralytics/models/yolo/__init__.py +1 -1
- ultralytics/models/yolo/classify/predict.py +28 -26
- ultralytics/models/yolo/classify/train.py +50 -81
- ultralytics/models/yolo/classify/val.py +68 -61
- ultralytics/models/yolo/detect/predict.py +12 -15
- ultralytics/models/yolo/detect/train.py +56 -46
- ultralytics/models/yolo/detect/val.py +279 -223
- ultralytics/models/yolo/model.py +167 -86
- ultralytics/models/yolo/obb/predict.py +7 -11
- ultralytics/models/yolo/obb/train.py +23 -25
- ultralytics/models/yolo/obb/val.py +107 -99
- ultralytics/models/yolo/pose/__init__.py +1 -1
- ultralytics/models/yolo/pose/predict.py +12 -14
- ultralytics/models/yolo/pose/train.py +31 -69
- ultralytics/models/yolo/pose/val.py +119 -254
- ultralytics/models/yolo/segment/predict.py +21 -25
- ultralytics/models/yolo/segment/train.py +12 -66
- ultralytics/models/yolo/segment/val.py +126 -305
- ultralytics/models/yolo/world/train.py +53 -45
- ultralytics/models/yolo/world/train_world.py +51 -32
- ultralytics/models/yolo/yoloe/__init__.py +7 -7
- ultralytics/models/yolo/yoloe/predict.py +30 -37
- ultralytics/models/yolo/yoloe/train.py +89 -71
- ultralytics/models/yolo/yoloe/train_seg.py +15 -17
- ultralytics/models/yolo/yoloe/val.py +56 -41
- ultralytics/nn/__init__.py +9 -11
- ultralytics/nn/autobackend.py +179 -107
- ultralytics/nn/modules/__init__.py +67 -67
- ultralytics/nn/modules/activation.py +8 -7
- ultralytics/nn/modules/block.py +302 -323
- ultralytics/nn/modules/conv.py +61 -104
- ultralytics/nn/modules/head.py +488 -186
- ultralytics/nn/modules/transformer.py +183 -123
- ultralytics/nn/modules/utils.py +15 -20
- ultralytics/nn/tasks.py +327 -203
- ultralytics/nn/text_model.py +81 -65
- ultralytics/py.typed +1 -0
- ultralytics/solutions/__init__.py +12 -12
- ultralytics/solutions/ai_gym.py +19 -27
- ultralytics/solutions/analytics.py +36 -26
- ultralytics/solutions/config.py +29 -28
- ultralytics/solutions/distance_calculation.py +23 -24
- ultralytics/solutions/heatmap.py +17 -19
- ultralytics/solutions/instance_segmentation.py +21 -19
- ultralytics/solutions/object_blurrer.py +16 -17
- ultralytics/solutions/object_counter.py +48 -53
- ultralytics/solutions/object_cropper.py +22 -16
- ultralytics/solutions/parking_management.py +61 -58
- ultralytics/solutions/queue_management.py +19 -19
- ultralytics/solutions/region_counter.py +63 -50
- ultralytics/solutions/security_alarm.py +22 -25
- ultralytics/solutions/similarity_search.py +107 -60
- ultralytics/solutions/solutions.py +343 -262
- ultralytics/solutions/speed_estimation.py +35 -31
- ultralytics/solutions/streamlit_inference.py +104 -40
- ultralytics/solutions/templates/similarity-search.html +31 -24
- ultralytics/solutions/trackzone.py +24 -24
- ultralytics/solutions/vision_eye.py +11 -12
- ultralytics/trackers/__init__.py +1 -1
- ultralytics/trackers/basetrack.py +18 -27
- ultralytics/trackers/bot_sort.py +48 -39
- ultralytics/trackers/byte_tracker.py +94 -94
- ultralytics/trackers/track.py +7 -16
- ultralytics/trackers/utils/gmc.py +37 -69
- ultralytics/trackers/utils/kalman_filter.py +68 -76
- ultralytics/trackers/utils/matching.py +13 -17
- ultralytics/utils/__init__.py +251 -275
- ultralytics/utils/autobatch.py +19 -7
- ultralytics/utils/autodevice.py +68 -38
- ultralytics/utils/benchmarks.py +169 -130
- ultralytics/utils/callbacks/base.py +12 -13
- ultralytics/utils/callbacks/clearml.py +14 -15
- ultralytics/utils/callbacks/comet.py +139 -66
- ultralytics/utils/callbacks/dvc.py +19 -27
- ultralytics/utils/callbacks/hub.py +8 -6
- ultralytics/utils/callbacks/mlflow.py +6 -10
- ultralytics/utils/callbacks/neptune.py +11 -19
- ultralytics/utils/callbacks/platform.py +73 -0
- ultralytics/utils/callbacks/raytune.py +3 -4
- ultralytics/utils/callbacks/tensorboard.py +9 -12
- ultralytics/utils/callbacks/wb.py +33 -30
- ultralytics/utils/checks.py +163 -114
- ultralytics/utils/cpu.py +89 -0
- ultralytics/utils/dist.py +24 -20
- ultralytics/utils/downloads.py +176 -146
- ultralytics/utils/errors.py +11 -13
- ultralytics/utils/events.py +113 -0
- ultralytics/utils/export/__init__.py +7 -0
- ultralytics/utils/{export.py → export/engine.py} +81 -63
- ultralytics/utils/export/imx.py +294 -0
- ultralytics/utils/export/tensorflow.py +217 -0
- ultralytics/utils/files.py +33 -36
- ultralytics/utils/git.py +137 -0
- ultralytics/utils/instance.py +105 -120
- ultralytics/utils/logger.py +404 -0
- ultralytics/utils/loss.py +99 -61
- ultralytics/utils/metrics.py +649 -478
- ultralytics/utils/nms.py +337 -0
- ultralytics/utils/ops.py +263 -451
- ultralytics/utils/patches.py +70 -31
- ultralytics/utils/plotting.py +253 -223
- ultralytics/utils/tal.py +48 -61
- ultralytics/utils/torch_utils.py +244 -251
- ultralytics/utils/tqdm.py +438 -0
- ultralytics/utils/triton.py +22 -23
- ultralytics/utils/tuner.py +11 -10
- dgenerate_ultralytics_headless-8.3.137.dist-info/RECORD +0 -272
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/top_level.txt +0 -0
ultralytics/cfg/__init__.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import shutil
|
|
4
6
|
import subprocess
|
|
5
7
|
import sys
|
|
6
8
|
from pathlib import Path
|
|
7
9
|
from types import SimpleNamespace
|
|
8
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
9
11
|
|
|
10
12
|
from ultralytics import __version__
|
|
11
13
|
from ultralytics.utils import (
|
|
@@ -13,6 +15,7 @@ from ultralytics.utils import (
|
|
|
13
15
|
DEFAULT_CFG,
|
|
14
16
|
DEFAULT_CFG_DICT,
|
|
15
17
|
DEFAULT_CFG_PATH,
|
|
18
|
+
FLOAT_OR_INT,
|
|
16
19
|
IS_VSCODE,
|
|
17
20
|
LOGGER,
|
|
18
21
|
RANK,
|
|
@@ -20,6 +23,7 @@ from ultralytics.utils import (
|
|
|
20
23
|
RUNS_DIR,
|
|
21
24
|
SETTINGS,
|
|
22
25
|
SETTINGS_FILE,
|
|
26
|
+
STR_OR_PATH,
|
|
23
27
|
TESTS_RUNNING,
|
|
24
28
|
YAML,
|
|
25
29
|
IterableSimpleNamespace,
|
|
@@ -70,18 +74,17 @@ TASK2METRIC = {
|
|
|
70
74
|
"pose": "metrics/mAP50-95(P)",
|
|
71
75
|
"obb": "metrics/mAP50-95(B)",
|
|
72
76
|
}
|
|
73
|
-
MODELS = frozenset({TASK2MODEL[task] for task in TASKS})
|
|
74
77
|
|
|
75
78
|
ARGV = sys.argv or ["", ""] # sometimes sys.argv = []
|
|
76
79
|
SOLUTIONS_HELP_MSG = f"""
|
|
77
|
-
Arguments received: {
|
|
80
|
+
Arguments received: {["yolo", *ARGV[1:]]!s}. Ultralytics 'yolo solutions' usage overview:
|
|
78
81
|
|
|
79
82
|
yolo solutions SOLUTION ARGS
|
|
80
83
|
|
|
81
84
|
Where SOLUTION (optional) is one of {list(SOLUTION_MAP.keys())[:-1]}
|
|
82
|
-
ARGS (optional) are any number of custom 'arg=value' pairs like 'show_in=True' that override defaults
|
|
85
|
+
ARGS (optional) are any number of custom 'arg=value' pairs like 'show_in=True' that override defaults
|
|
83
86
|
at https://docs.ultralytics.com/usage/cfg
|
|
84
|
-
|
|
87
|
+
|
|
85
88
|
1. Call object counting solution
|
|
86
89
|
yolo solutions count source="path/to/video.mp4" region="[(20, 400), (1080, 400), (1080, 360), (20, 360)]"
|
|
87
90
|
|
|
@@ -96,20 +99,20 @@ SOLUTIONS_HELP_MSG = f"""
|
|
|
96
99
|
|
|
97
100
|
5. Generate analytical graphs
|
|
98
101
|
yolo solutions analytics analytics_type="pie"
|
|
99
|
-
|
|
102
|
+
|
|
100
103
|
6. Track objects within specific zones
|
|
101
104
|
yolo solutions trackzone source="path/to/video.mp4" region="[(150, 150), (1130, 150), (1130, 570), (150, 570)]"
|
|
102
|
-
|
|
105
|
+
|
|
103
106
|
7. Streamlit real-time webcam inference GUI
|
|
104
107
|
yolo streamlit-predict
|
|
105
108
|
"""
|
|
106
109
|
CLI_HELP_MSG = f"""
|
|
107
|
-
Arguments received: {
|
|
110
|
+
Arguments received: {["yolo", *ARGV[1:]]!s}. Ultralytics 'yolo' commands use the following syntax:
|
|
108
111
|
|
|
109
112
|
yolo TASK MODE ARGS
|
|
110
113
|
|
|
111
|
-
Where TASK (optional) is one of {TASKS}
|
|
112
|
-
MODE (required) is one of {MODES}
|
|
114
|
+
Where TASK (optional) is one of {list(TASKS)}
|
|
115
|
+
MODE (required) is one of {list(MODES)}
|
|
113
116
|
ARGS (optional) are any number of custom 'arg=value' pairs like 'imgsz=320' that override defaults.
|
|
114
117
|
See all ARGS at https://docs.ultralytics.com/usage/cfg or with 'yolo cfg'
|
|
115
118
|
|
|
@@ -238,13 +241,12 @@ CFG_BOOL_KEYS = frozenset(
|
|
|
238
241
|
)
|
|
239
242
|
|
|
240
243
|
|
|
241
|
-
def cfg2dict(cfg:
|
|
242
|
-
"""
|
|
243
|
-
Converts a configuration object to a dictionary.
|
|
244
|
+
def cfg2dict(cfg: str | Path | dict | SimpleNamespace) -> dict:
|
|
245
|
+
"""Convert a configuration object to a dictionary.
|
|
244
246
|
|
|
245
247
|
Args:
|
|
246
|
-
cfg (str | Path |
|
|
247
|
-
|
|
248
|
+
cfg (str | Path | dict | SimpleNamespace): Configuration object to be converted. Can be a file path, a string, a
|
|
249
|
+
dictionary, or a SimpleNamespace object.
|
|
248
250
|
|
|
249
251
|
Returns:
|
|
250
252
|
(dict): Configuration object in dictionary format.
|
|
@@ -266,21 +268,22 @@ def cfg2dict(cfg: Union[str, Path, Dict, SimpleNamespace]) -> Dict:
|
|
|
266
268
|
- If cfg is a SimpleNamespace object, it's converted to a dictionary using vars().
|
|
267
269
|
- If cfg is already a dictionary, it's returned unchanged.
|
|
268
270
|
"""
|
|
269
|
-
if isinstance(cfg,
|
|
271
|
+
if isinstance(cfg, STR_OR_PATH):
|
|
270
272
|
cfg = YAML.load(cfg) # load dict
|
|
271
273
|
elif isinstance(cfg, SimpleNamespace):
|
|
272
274
|
cfg = vars(cfg) # convert to dict
|
|
273
275
|
return cfg
|
|
274
276
|
|
|
275
277
|
|
|
276
|
-
def get_cfg(
|
|
277
|
-
|
|
278
|
-
|
|
278
|
+
def get_cfg(
|
|
279
|
+
cfg: str | Path | dict | SimpleNamespace = DEFAULT_CFG_DICT, overrides: dict | None = None
|
|
280
|
+
) -> SimpleNamespace:
|
|
281
|
+
"""Load and merge configuration data from a file or dictionary, with optional overrides.
|
|
279
282
|
|
|
280
283
|
Args:
|
|
281
|
-
cfg (str | Path |
|
|
284
|
+
cfg (str | Path | dict | SimpleNamespace): Configuration data source. Can be a file path, dictionary, or
|
|
282
285
|
SimpleNamespace object.
|
|
283
|
-
overrides (
|
|
286
|
+
overrides (dict | None): Dictionary containing key-value pairs to override the base configuration.
|
|
284
287
|
|
|
285
288
|
Returns:
|
|
286
289
|
(SimpleNamespace): Namespace containing the merged configuration arguments.
|
|
@@ -308,10 +311,10 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, ove
|
|
|
308
311
|
|
|
309
312
|
# Special handling for numeric project/name
|
|
310
313
|
for k in "project", "name":
|
|
311
|
-
if k in cfg and isinstance(cfg[k],
|
|
314
|
+
if k in cfg and isinstance(cfg[k], FLOAT_OR_INT):
|
|
312
315
|
cfg[k] = str(cfg[k])
|
|
313
316
|
if cfg.get("name") == "model": # assign model to 'name' arg
|
|
314
|
-
cfg["name"] = str(cfg.get("model", "")).
|
|
317
|
+
cfg["name"] = str(cfg.get("model", "")).partition(".")[0]
|
|
315
318
|
LOGGER.warning(f"'name=model' automatically updated to 'name={cfg['name']}'.")
|
|
316
319
|
|
|
317
320
|
# Type and Value checks
|
|
@@ -321,12 +324,11 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, ove
|
|
|
321
324
|
return IterableSimpleNamespace(**cfg)
|
|
322
325
|
|
|
323
326
|
|
|
324
|
-
def check_cfg(cfg:
|
|
325
|
-
"""
|
|
326
|
-
Checks configuration argument types and values for the Ultralytics library.
|
|
327
|
+
def check_cfg(cfg: dict, hard: bool = True) -> None:
|
|
328
|
+
"""Check configuration argument types and values for the Ultralytics library.
|
|
327
329
|
|
|
328
|
-
This function validates the types and values of configuration arguments, ensuring correctness and converting
|
|
329
|
-
|
|
330
|
+
This function validates the types and values of configuration arguments, ensuring correctness and converting them if
|
|
331
|
+
necessary. It checks for specific key types defined in global variables such as `CFG_FLOAT_KEYS`,
|
|
330
332
|
`CFG_FRACTION_KEYS`, `CFG_INT_KEYS`, and `CFG_BOOL_KEYS`.
|
|
331
333
|
|
|
332
334
|
Args:
|
|
@@ -351,7 +353,7 @@ def check_cfg(cfg: Dict, hard: bool = True) -> None:
|
|
|
351
353
|
"""
|
|
352
354
|
for k, v in cfg.items():
|
|
353
355
|
if v is not None: # None values may be from optional args
|
|
354
|
-
if k in CFG_FLOAT_KEYS and not isinstance(v,
|
|
356
|
+
if k in CFG_FLOAT_KEYS and not isinstance(v, FLOAT_OR_INT):
|
|
355
357
|
if hard:
|
|
356
358
|
raise TypeError(
|
|
357
359
|
f"'{k}={v}' is of invalid type {type(v).__name__}. "
|
|
@@ -359,7 +361,7 @@ def check_cfg(cfg: Dict, hard: bool = True) -> None:
|
|
|
359
361
|
)
|
|
360
362
|
cfg[k] = float(v)
|
|
361
363
|
elif k in CFG_FRACTION_KEYS:
|
|
362
|
-
if not isinstance(v,
|
|
364
|
+
if not isinstance(v, FLOAT_OR_INT):
|
|
363
365
|
if hard:
|
|
364
366
|
raise TypeError(
|
|
365
367
|
f"'{k}={v}' is of invalid type {type(v).__name__}. "
|
|
@@ -383,15 +385,14 @@ def check_cfg(cfg: Dict, hard: bool = True) -> None:
|
|
|
383
385
|
cfg[k] = bool(v)
|
|
384
386
|
|
|
385
387
|
|
|
386
|
-
def get_save_dir(args: SimpleNamespace, name: str = None) -> Path:
|
|
387
|
-
"""
|
|
388
|
-
Returns the directory path for saving outputs, derived from arguments or default settings.
|
|
388
|
+
def get_save_dir(args: SimpleNamespace, name: str | None = None) -> Path:
|
|
389
|
+
"""Return the directory path for saving outputs, derived from arguments or default settings.
|
|
389
390
|
|
|
390
391
|
Args:
|
|
391
|
-
args (SimpleNamespace): Namespace object containing configurations such as 'project', 'name', 'task',
|
|
392
|
-
|
|
393
|
-
name (str | None): Optional name for the output directory. If not provided, it defaults to 'args.name'
|
|
394
|
-
|
|
392
|
+
args (SimpleNamespace): Namespace object containing configurations such as 'project', 'name', 'task', 'mode',
|
|
393
|
+
and 'save_dir'.
|
|
394
|
+
name (str | None): Optional name for the output directory. If not provided, it defaults to 'args.name' or the
|
|
395
|
+
'args.mode'.
|
|
395
396
|
|
|
396
397
|
Returns:
|
|
397
398
|
(Path): Directory path where outputs should be saved.
|
|
@@ -412,16 +413,18 @@ def get_save_dir(args: SimpleNamespace, name: str = None) -> Path:
|
|
|
412
413
|
name = name or args.name or f"{args.mode}"
|
|
413
414
|
save_dir = increment_path(Path(project) / name, exist_ok=args.exist_ok if RANK in {-1, 0} else True)
|
|
414
415
|
|
|
415
|
-
return Path(save_dir)
|
|
416
|
+
return Path(save_dir).resolve() # resolve to display full path in console
|
|
416
417
|
|
|
417
418
|
|
|
418
|
-
def _handle_deprecation(custom:
|
|
419
|
-
"""
|
|
420
|
-
Handles deprecated configuration keys by mapping them to current equivalents with deprecation warnings.
|
|
419
|
+
def _handle_deprecation(custom: dict) -> dict:
|
|
420
|
+
"""Handle deprecated configuration keys by mapping them to current equivalents with deprecation warnings.
|
|
421
421
|
|
|
422
422
|
Args:
|
|
423
423
|
custom (dict): Configuration dictionary potentially containing deprecated keys.
|
|
424
424
|
|
|
425
|
+
Returns:
|
|
426
|
+
(dict): Updated configuration dictionary with deprecated keys replaced.
|
|
427
|
+
|
|
425
428
|
Examples:
|
|
426
429
|
>>> custom_config = {"boxes": True, "hide_labels": "False", "line_thickness": 2}
|
|
427
430
|
>>> _handle_deprecation(custom_config)
|
|
@@ -456,9 +459,8 @@ def _handle_deprecation(custom: Dict) -> Dict:
|
|
|
456
459
|
return custom
|
|
457
460
|
|
|
458
461
|
|
|
459
|
-
def check_dict_alignment(base:
|
|
460
|
-
"""
|
|
461
|
-
Checks alignment between custom and base configuration dictionaries, handling deprecated keys and providing error
|
|
462
|
+
def check_dict_alignment(base: dict, custom: dict, e: Exception | None = None) -> None:
|
|
463
|
+
"""Check alignment between custom and base configuration dictionaries, handling deprecated keys and providing error
|
|
462
464
|
messages for mismatched keys.
|
|
463
465
|
|
|
464
466
|
Args:
|
|
@@ -496,9 +498,8 @@ def check_dict_alignment(base: Dict, custom: Dict, e: Exception = None) -> None:
|
|
|
496
498
|
raise SyntaxError(string + CLI_HELP_MSG) from e
|
|
497
499
|
|
|
498
500
|
|
|
499
|
-
def merge_equals_args(args:
|
|
500
|
-
"""
|
|
501
|
-
Merges arguments around isolated '=' in a list of strings and joins fragments with brackets.
|
|
501
|
+
def merge_equals_args(args: list[str]) -> list[str]:
|
|
502
|
+
"""Merge arguments around isolated '=' in a list of strings and join fragments with brackets.
|
|
502
503
|
|
|
503
504
|
This function handles the following cases:
|
|
504
505
|
1. ['arg', '=', 'val'] becomes ['arg=val']
|
|
@@ -507,10 +508,11 @@ def merge_equals_args(args: List[str]) -> List[str]:
|
|
|
507
508
|
4. Joins fragments with brackets, e.g., ['imgsz=[3,', '640,', '640]'] becomes ['imgsz=[3,640,640]']
|
|
508
509
|
|
|
509
510
|
Args:
|
|
510
|
-
args (
|
|
511
|
+
args (list[str]): A list of strings where each element represents an argument or fragment.
|
|
511
512
|
|
|
512
513
|
Returns:
|
|
513
|
-
(
|
|
514
|
+
(list[str]): A list of strings where the arguments around isolated '=' are merged and fragments with brackets
|
|
515
|
+
are joined.
|
|
514
516
|
|
|
515
517
|
Examples:
|
|
516
518
|
>>> args = ["arg1", "=", "value", "arg2=", "value2", "arg3", "=value3", "imgsz=[3,", "640,", "640]"]
|
|
@@ -555,16 +557,15 @@ def merge_equals_args(args: List[str]) -> List[str]:
|
|
|
555
557
|
return new_args
|
|
556
558
|
|
|
557
559
|
|
|
558
|
-
def handle_yolo_hub(args:
|
|
559
|
-
"""
|
|
560
|
-
Handles Ultralytics HUB command-line interface (CLI) commands for authentication.
|
|
560
|
+
def handle_yolo_hub(args: list[str]) -> None:
|
|
561
|
+
"""Handle Ultralytics HUB command-line interface (CLI) commands for authentication.
|
|
561
562
|
|
|
562
563
|
This function processes Ultralytics HUB CLI commands such as login and logout. It should be called when executing a
|
|
563
564
|
script with arguments related to HUB authentication.
|
|
564
565
|
|
|
565
566
|
Args:
|
|
566
|
-
args (
|
|
567
|
-
|
|
567
|
+
args (list[str]): A list of command line arguments. The first argument should be either 'login' or 'logout'. For
|
|
568
|
+
'login', an optional second argument can be the API key.
|
|
568
569
|
|
|
569
570
|
Examples:
|
|
570
571
|
$ yolo login YOUR_API_KEY
|
|
@@ -585,15 +586,14 @@ def handle_yolo_hub(args: List[str]) -> None:
|
|
|
585
586
|
hub.logout()
|
|
586
587
|
|
|
587
588
|
|
|
588
|
-
def handle_yolo_settings(args:
|
|
589
|
-
"""
|
|
590
|
-
Handles YOLO settings command-line interface (CLI) commands.
|
|
589
|
+
def handle_yolo_settings(args: list[str]) -> None:
|
|
590
|
+
"""Handle YOLO settings command-line interface (CLI) commands.
|
|
591
591
|
|
|
592
592
|
This function processes YOLO settings CLI commands such as reset and updating individual settings. It should be
|
|
593
593
|
called when executing a script with arguments related to YOLO settings management.
|
|
594
594
|
|
|
595
595
|
Args:
|
|
596
|
-
args (
|
|
596
|
+
args (list[str]): A list of command line arguments for YOLO settings management.
|
|
597
597
|
|
|
598
598
|
Examples:
|
|
599
599
|
>>> handle_yolo_settings(["reset"]) # Reset YOLO settings
|
|
@@ -619,6 +619,8 @@ def handle_yolo_settings(args: List[str]) -> None:
|
|
|
619
619
|
new = dict(parse_key_value_pair(a) for a in args)
|
|
620
620
|
check_dict_alignment(SETTINGS, new)
|
|
621
621
|
SETTINGS.update(new)
|
|
622
|
+
for k, v in new.items():
|
|
623
|
+
LOGGER.info(f"✅ Updated '{k}={v}'")
|
|
622
624
|
|
|
623
625
|
LOGGER.info(SETTINGS) # print the current settings
|
|
624
626
|
LOGGER.info(f"💡 Learn more about Ultralytics Settings at {url}")
|
|
@@ -626,14 +628,11 @@ def handle_yolo_settings(args: List[str]) -> None:
|
|
|
626
628
|
LOGGER.warning(f"settings error: '{e}'. Please see {url} for help.")
|
|
627
629
|
|
|
628
630
|
|
|
629
|
-
def handle_yolo_solutions(args:
|
|
630
|
-
"""
|
|
631
|
-
Processes YOLO solutions arguments and runs the specified computer vision solutions pipeline.
|
|
631
|
+
def handle_yolo_solutions(args: list[str]) -> None:
|
|
632
|
+
"""Process YOLO solutions arguments and run the specified computer vision solutions pipeline.
|
|
632
633
|
|
|
633
634
|
Args:
|
|
634
|
-
args (
|
|
635
|
-
solutions: https://docs.ultralytics.com/solutions/, It can include solution name, source,
|
|
636
|
-
and other configuration parameters.
|
|
635
|
+
args (list[str]): Command-line arguments for configuring and running the Ultralytics YOLO solutions.
|
|
637
636
|
|
|
638
637
|
Examples:
|
|
639
638
|
Run people counting solution with default settings:
|
|
@@ -739,8 +738,7 @@ def handle_yolo_solutions(args: List[str]) -> None:
|
|
|
739
738
|
|
|
740
739
|
|
|
741
740
|
def parse_key_value_pair(pair: str = "key=value") -> tuple:
|
|
742
|
-
"""
|
|
743
|
-
Parses a key-value pair string into separate key and value components.
|
|
741
|
+
"""Parse a key-value pair string into separate key and value components.
|
|
744
742
|
|
|
745
743
|
Args:
|
|
746
744
|
pair (str): A string containing a key-value pair in the format "key=value".
|
|
@@ -773,8 +771,7 @@ def parse_key_value_pair(pair: str = "key=value") -> tuple:
|
|
|
773
771
|
|
|
774
772
|
|
|
775
773
|
def smart_value(v: str) -> Any:
|
|
776
|
-
"""
|
|
777
|
-
Converts a string representation of a value to its appropriate Python type.
|
|
774
|
+
"""Convert a string representation of a value to its appropriate Python type.
|
|
778
775
|
|
|
779
776
|
This function attempts to convert a given string into a Python object of the most appropriate type. It handles
|
|
780
777
|
conversions to None, bool, int, float, and other types that can be evaluated safely.
|
|
@@ -783,8 +780,8 @@ def smart_value(v: str) -> Any:
|
|
|
783
780
|
v (str): The string representation of the value to be converted.
|
|
784
781
|
|
|
785
782
|
Returns:
|
|
786
|
-
(Any): The converted value. The type can be None, bool, int, float, or the original string if no conversion
|
|
787
|
-
|
|
783
|
+
(Any): The converted value. The type can be None, bool, int, float, or the original string if no conversion is
|
|
784
|
+
applicable.
|
|
788
785
|
|
|
789
786
|
Examples:
|
|
790
787
|
>>> smart_value("42")
|
|
@@ -818,11 +815,10 @@ def smart_value(v: str) -> Any:
|
|
|
818
815
|
|
|
819
816
|
|
|
820
817
|
def entrypoint(debug: str = "") -> None:
|
|
821
|
-
"""
|
|
822
|
-
Ultralytics entrypoint function for parsing and executing command-line arguments.
|
|
818
|
+
"""Ultralytics entrypoint function for parsing and executing command-line arguments.
|
|
823
819
|
|
|
824
|
-
This function serves as the main entry point for the Ultralytics CLI, parsing command-line arguments and
|
|
825
|
-
|
|
820
|
+
This function serves as the main entry point for the Ultralytics CLI, parsing command-line arguments and executing
|
|
821
|
+
the corresponding tasks such as training, validation, prediction, exporting models, and more.
|
|
826
822
|
|
|
827
823
|
Args:
|
|
828
824
|
debug (str): Space-separated string of command-line arguments for debugging purposes.
|
|
@@ -848,7 +844,6 @@ def entrypoint(debug: str = "") -> None:
|
|
|
848
844
|
return
|
|
849
845
|
|
|
850
846
|
special = {
|
|
851
|
-
"help": lambda: LOGGER.info(CLI_HELP_MSG),
|
|
852
847
|
"checks": checks.collect_system_info,
|
|
853
848
|
"version": lambda: LOGGER.info(__version__),
|
|
854
849
|
"settings": lambda: handle_yolo_settings(args[1:]),
|
|
@@ -858,6 +853,7 @@ def entrypoint(debug: str = "") -> None:
|
|
|
858
853
|
"logout": lambda: handle_yolo_hub(args),
|
|
859
854
|
"copy-cfg": copy_default_cfg,
|
|
860
855
|
"solutions": lambda: handle_yolo_solutions(args[1:]),
|
|
856
|
+
"help": lambda: LOGGER.info(CLI_HELP_MSG), # help below hub for -h flag precedence
|
|
861
857
|
}
|
|
862
858
|
full_args_dict = {**DEFAULT_CFG_DICT, **{k: None for k in TASKS}, **{k: None for k in MODES}, **special}
|
|
863
859
|
|
|
@@ -909,9 +905,9 @@ def entrypoint(debug: str = "") -> None:
|
|
|
909
905
|
mode = overrides.get("mode")
|
|
910
906
|
if mode is None:
|
|
911
907
|
mode = DEFAULT_CFG.mode or "predict"
|
|
912
|
-
LOGGER.warning(f"'mode' argument is missing. Valid modes are {MODES}. Using default 'mode={mode}'.")
|
|
908
|
+
LOGGER.warning(f"'mode' argument is missing. Valid modes are {list(MODES)}. Using default 'mode={mode}'.")
|
|
913
909
|
elif mode not in MODES:
|
|
914
|
-
raise ValueError(f"Invalid 'mode={mode}'. Valid modes are {MODES}.\n{CLI_HELP_MSG}")
|
|
910
|
+
raise ValueError(f"Invalid 'mode={mode}'. Valid modes are {list(MODES)}.\n{CLI_HELP_MSG}")
|
|
915
911
|
|
|
916
912
|
# Task
|
|
917
913
|
task = overrides.pop("task", None)
|
|
@@ -919,11 +915,11 @@ def entrypoint(debug: str = "") -> None:
|
|
|
919
915
|
if task not in TASKS:
|
|
920
916
|
if task == "track":
|
|
921
917
|
LOGGER.warning(
|
|
922
|
-
f"invalid 'task=track', setting 'task=detect' and 'mode=track'. Valid tasks are {TASKS}.\n{CLI_HELP_MSG}."
|
|
918
|
+
f"invalid 'task=track', setting 'task=detect' and 'mode=track'. Valid tasks are {list(TASKS)}.\n{CLI_HELP_MSG}."
|
|
923
919
|
)
|
|
924
920
|
task, mode = "detect", "track"
|
|
925
921
|
else:
|
|
926
|
-
raise ValueError(f"Invalid 'task={task}'. Valid tasks are {TASKS}.\n{CLI_HELP_MSG}")
|
|
922
|
+
raise ValueError(f"Invalid 'task={task}'. Valid tasks are {list(TASKS)}.\n{CLI_HELP_MSG}")
|
|
927
923
|
if "model" not in overrides:
|
|
928
924
|
overrides["model"] = TASK2MODEL[task]
|
|
929
925
|
|
|
@@ -950,9 +946,10 @@ def entrypoint(debug: str = "") -> None:
|
|
|
950
946
|
from ultralytics import YOLO
|
|
951
947
|
|
|
952
948
|
model = YOLO(model, task=task)
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
949
|
+
if "yoloe" in stem or "world" in stem:
|
|
950
|
+
cls_list = overrides.pop("classes", DEFAULT_CFG.classes)
|
|
951
|
+
if cls_list is not None and isinstance(cls_list, str):
|
|
952
|
+
model.set_classes(cls_list.split(",")) # convert "person, bus" -> ['person', ' bus'].
|
|
956
953
|
# Task Update
|
|
957
954
|
if task != model.task:
|
|
958
955
|
if task:
|
|
@@ -990,12 +987,11 @@ def entrypoint(debug: str = "") -> None:
|
|
|
990
987
|
|
|
991
988
|
# Special modes --------------------------------------------------------------------------------------------------------
|
|
992
989
|
def copy_default_cfg() -> None:
|
|
993
|
-
"""
|
|
994
|
-
Copies the default configuration file and creates a new one with '_copy' appended to its name.
|
|
990
|
+
"""Copy the default configuration file and create a new one with '_copy' appended to its name.
|
|
995
991
|
|
|
996
|
-
This function duplicates the existing default configuration file (DEFAULT_CFG_PATH) and saves it
|
|
997
|
-
|
|
998
|
-
|
|
992
|
+
This function duplicates the existing default configuration file (DEFAULT_CFG_PATH) and saves it with '_copy'
|
|
993
|
+
appended to its name in the current working directory. It provides a convenient way to create a custom configuration
|
|
994
|
+
file based on the default settings.
|
|
999
995
|
|
|
1000
996
|
Examples:
|
|
1001
997
|
>>> copy_default_cfg()
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
# parent
|
|
7
7
|
# ├── ultralytics
|
|
8
8
|
# └── datasets
|
|
9
|
-
# └── Argoverse
|
|
9
|
+
# └── Argoverse ← downloads here (31.5 GB)
|
|
10
10
|
|
|
11
11
|
# 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, ..]
|
|
12
|
-
path:
|
|
12
|
+
path: Argoverse # dataset root dir
|
|
13
13
|
train: Argoverse-1.1/images/train/ # train images (relative to 'path') 39384 images
|
|
14
14
|
val: Argoverse-1.1/images/val/ # val images (relative to 'path') 15062 images
|
|
15
15
|
test: Argoverse-1.1/images/test/ # test images (optional) https://eval.ai/web/challenges/challenge-page/800/overview
|
|
@@ -30,14 +30,14 @@ download: |
|
|
|
30
30
|
import json
|
|
31
31
|
from pathlib import Path
|
|
32
32
|
|
|
33
|
-
from
|
|
33
|
+
from ultralytics.utils import TQDM
|
|
34
34
|
from ultralytics.utils.downloads import download
|
|
35
35
|
|
|
36
36
|
def argoverse2yolo(set):
|
|
37
37
|
"""Convert Argoverse dataset annotations to YOLO format for object detection tasks."""
|
|
38
38
|
labels = {}
|
|
39
39
|
a = json.load(open(set, "rb"))
|
|
40
|
-
for annot in
|
|
40
|
+
for annot in TQDM(a["annotations"], desc=f"Converting {set} to YOLOv5 format..."):
|
|
41
41
|
img_id = annot["image_id"]
|
|
42
42
|
img_name = a["images"][img_id]["name"]
|
|
43
43
|
img_label_name = f"{img_name[:-3]}txt"
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
# parent
|
|
7
7
|
# ├── ultralytics
|
|
8
8
|
# └── datasets
|
|
9
|
-
# └── dota1.5
|
|
9
|
+
# └── dota1.5 ← downloads here (2GB)
|
|
10
10
|
|
|
11
11
|
# 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, ..]
|
|
12
|
-
path:
|
|
12
|
+
path: DOTAv1.5 # dataset root dir
|
|
13
13
|
train: images/train # train images (relative to 'path') 1411 images
|
|
14
14
|
val: images/val # val images (relative to 'path') 458 images
|
|
15
15
|
test: images/test # test images (optional) 937 images
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
# parent
|
|
7
7
|
# ├── ultralytics
|
|
8
8
|
# └── datasets
|
|
9
|
-
# └── dota1
|
|
9
|
+
# └── dota1 ← downloads here (2GB)
|
|
10
10
|
|
|
11
11
|
# 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, ..]
|
|
12
|
-
path:
|
|
12
|
+
path: DOTAv1 # dataset root dir
|
|
13
13
|
train: images/train # train images (relative to 'path') 1411 images
|
|
14
14
|
val: images/val # val images (relative to 'path') 458 images
|
|
15
15
|
test: images/test # test images (optional) 937 images
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
# parent
|
|
7
7
|
# ├── ultralytics
|
|
8
8
|
# └── datasets
|
|
9
|
-
# └── GlobalWheat2020
|
|
9
|
+
# └── GlobalWheat2020 ← downloads here (7.0 GB)
|
|
10
10
|
|
|
11
11
|
# 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, ..]
|
|
12
|
-
path:
|
|
12
|
+
path: GlobalWheat2020 # dataset root dir
|
|
13
13
|
train: # train images (relative to 'path') 3422 images
|
|
14
14
|
- images/arvalis_1
|
|
15
15
|
- images/arvalis_2
|
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
# parent
|
|
7
7
|
# ├── ultralytics
|
|
8
8
|
# └── datasets
|
|
9
|
-
# └── homeobjects-3K
|
|
9
|
+
# └── homeobjects-3K ← downloads here (390 MB)
|
|
10
10
|
|
|
11
11
|
# 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, ..]
|
|
12
|
-
path:
|
|
13
|
-
train: train
|
|
14
|
-
val:
|
|
15
|
-
test: # test images (relative to 'path')
|
|
12
|
+
path: homeobjects-3K # dataset root dir
|
|
13
|
+
train: images/train # train images (relative to 'path') 2285 images
|
|
14
|
+
val: images/val # val images (relative to 'path') 404 images
|
|
16
15
|
|
|
17
16
|
# Classes
|
|
18
17
|
names:
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
# parent
|
|
8
8
|
# ├── ultralytics
|
|
9
9
|
# └── datasets
|
|
10
|
-
# └── imagenet
|
|
10
|
+
# └── imagenet ← downloads here (144 GB)
|
|
11
11
|
|
|
12
12
|
# 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, ..]
|
|
13
|
-
path:
|
|
13
|
+
path: imagenet # dataset root dir
|
|
14
14
|
train: train # train images (relative to 'path') 1281167 images
|
|
15
15
|
val: val # val images (relative to 'path') 50000 images
|
|
16
16
|
test: # test images (optional)
|
|
@@ -342,7 +342,7 @@ names:
|
|
|
342
342
|
322: ringlet
|
|
343
343
|
323: monarch butterfly
|
|
344
344
|
324: small white
|
|
345
|
-
325:
|
|
345
|
+
325: sulfur butterfly
|
|
346
346
|
326: gossamer-winged butterfly
|
|
347
347
|
327: starfish
|
|
348
348
|
328: sea urchin
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
# parent
|
|
7
7
|
# ├── ultralytics
|
|
8
8
|
# └── datasets
|
|
9
|
-
# └── Objects365
|
|
9
|
+
# └── Objects365 ← downloads here (712 GB = 367G data + 345G zips)
|
|
10
10
|
|
|
11
11
|
# 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, ..]
|
|
12
|
-
path:
|
|
12
|
+
path: Objects365 # dataset root dir
|
|
13
13
|
train: images/train # train images (relative to 'path') 1742289 images
|
|
14
14
|
val: images/val # val images (relative to 'path') 80000 images
|
|
15
15
|
test: # test images (optional)
|
|
@@ -384,43 +384,41 @@ names:
|
|
|
384
384
|
|
|
385
385
|
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
|
386
386
|
download: |
|
|
387
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
387
388
|
from pathlib import Path
|
|
388
389
|
|
|
389
390
|
import numpy as np
|
|
390
|
-
from tqdm import tqdm
|
|
391
391
|
|
|
392
|
+
from ultralytics.utils import TQDM
|
|
392
393
|
from ultralytics.utils.checks import check_requirements
|
|
393
394
|
from ultralytics.utils.downloads import download
|
|
394
395
|
from ultralytics.utils.ops import xyxy2xywhn
|
|
395
396
|
|
|
396
|
-
check_requirements(
|
|
397
|
-
from
|
|
398
|
-
|
|
399
|
-
# Make Directories
|
|
400
|
-
dir = Path(yaml["path"]) # dataset root dir
|
|
401
|
-
for p in "images", "labels":
|
|
402
|
-
(dir / p).mkdir(parents=True, exist_ok=True)
|
|
403
|
-
for q in "train", "val":
|
|
404
|
-
(dir / p / q).mkdir(parents=True, exist_ok=True)
|
|
397
|
+
check_requirements("faster-coco-eval")
|
|
398
|
+
from faster_coco_eval import COCO
|
|
405
399
|
|
|
406
400
|
# Train, Val Splits
|
|
401
|
+
dir = Path(yaml["path"])
|
|
407
402
|
for split, patches in [("train", 50 + 1), ("val", 43 + 1)]:
|
|
408
403
|
print(f"Processing {split} in {patches} patches ...")
|
|
409
404
|
images, labels = dir / "images" / split, dir / "labels" / split
|
|
405
|
+
images.mkdir(parents=True, exist_ok=True)
|
|
406
|
+
labels.mkdir(parents=True, exist_ok=True)
|
|
410
407
|
|
|
411
408
|
# Download
|
|
412
409
|
url = f"https://dorc.ks3-cn-beijing.ksyun.com/data-set/2020Objects365%E6%95%B0%E6%8D%AE%E9%9B%86/{split}/"
|
|
413
410
|
if split == "train":
|
|
414
411
|
download([f"{url}zhiyuan_objv2_{split}.tar.gz"], dir=dir) # annotations json
|
|
415
|
-
download([f"{url}patch{i}.tar.gz" for i in range(patches)], dir=images,
|
|
412
|
+
download([f"{url}patch{i}.tar.gz" for i in range(patches)], dir=images, threads=17) # 51 patches / 17 threads = 3
|
|
416
413
|
elif split == "val":
|
|
417
414
|
download([f"{url}zhiyuan_objv2_{split}.json"], dir=dir) # annotations json
|
|
418
|
-
download([f"{url}images/v1/patch{i}.tar.gz" for i in range(15 + 1)], dir=images,
|
|
419
|
-
download([f"{url}images/v2/patch{i}.tar.gz" for i in range(16, patches)], dir=images,
|
|
415
|
+
download([f"{url}images/v1/patch{i}.tar.gz" for i in range(15 + 1)], dir=images, threads=16)
|
|
416
|
+
download([f"{url}images/v2/patch{i}.tar.gz" for i in range(16, patches)], dir=images, threads=16)
|
|
420
417
|
|
|
421
418
|
# Move
|
|
422
|
-
|
|
423
|
-
|
|
419
|
+
files = list(images.rglob("*.jpg"))
|
|
420
|
+
with ThreadPoolExecutor(max_workers=16) as executor:
|
|
421
|
+
list(TQDM(executor.map(lambda f: f.rename(images / f.name), files), total=len(files), desc=f"Moving {split} images"))
|
|
424
422
|
|
|
425
423
|
# Labels
|
|
426
424
|
coco = COCO(dir / f"zhiyuan_objv2_{split}.json")
|
|
@@ -428,10 +426,12 @@ download: |
|
|
|
428
426
|
for cid, cat in enumerate(names):
|
|
429
427
|
catIds = coco.getCatIds(catNms=[cat])
|
|
430
428
|
imgIds = coco.getImgIds(catIds=catIds)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
429
|
+
|
|
430
|
+
def process_annotation(im):
|
|
431
|
+
"""Process and write annotations for a single image."""
|
|
434
432
|
try:
|
|
433
|
+
width, height = im["width"], im["height"]
|
|
434
|
+
path = Path(im["file_name"])
|
|
435
435
|
with open(labels / path.with_suffix(".txt").name, "a", encoding="utf-8") as file:
|
|
436
436
|
annIds = coco.getAnnIds(imgIds=im["id"], catIds=catIds, iscrowd=None)
|
|
437
437
|
for a in coco.loadAnns(annIds):
|
|
@@ -441,3 +441,7 @@ download: |
|
|
|
441
441
|
file.write(f"{cid} {x:.5f} {y:.5f} {w:.5f} {h:.5f}\n")
|
|
442
442
|
except Exception as e:
|
|
443
443
|
print(e)
|
|
444
|
+
|
|
445
|
+
images_list = coco.loadImgs(imgIds)
|
|
446
|
+
with ThreadPoolExecutor(max_workers=16) as executor:
|
|
447
|
+
list(TQDM(executor.map(process_annotation, images_list), total=len(images_list), desc=f"Class {cid + 1}/{len(names)} {cat}"))
|