dgenerate-ultralytics-headless 8.3.253__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 (299) hide show
  1. dgenerate_ultralytics_headless-8.3.253.dist-info/METADATA +405 -0
  2. dgenerate_ultralytics_headless-8.3.253.dist-info/RECORD +299 -0
  3. dgenerate_ultralytics_headless-8.3.253.dist-info/WHEEL +5 -0
  4. dgenerate_ultralytics_headless-8.3.253.dist-info/entry_points.txt +3 -0
  5. dgenerate_ultralytics_headless-8.3.253.dist-info/licenses/LICENSE +661 -0
  6. dgenerate_ultralytics_headless-8.3.253.dist-info/top_level.txt +1 -0
  7. tests/__init__.py +23 -0
  8. tests/conftest.py +59 -0
  9. tests/test_cli.py +131 -0
  10. tests/test_cuda.py +216 -0
  11. tests/test_engine.py +157 -0
  12. tests/test_exports.py +309 -0
  13. tests/test_integrations.py +151 -0
  14. tests/test_python.py +777 -0
  15. tests/test_solutions.py +371 -0
  16. ultralytics/__init__.py +48 -0
  17. ultralytics/assets/bus.jpg +0 -0
  18. ultralytics/assets/zidane.jpg +0 -0
  19. ultralytics/cfg/__init__.py +1028 -0
  20. ultralytics/cfg/datasets/Argoverse.yaml +78 -0
  21. ultralytics/cfg/datasets/DOTAv1.5.yaml +37 -0
  22. ultralytics/cfg/datasets/DOTAv1.yaml +36 -0
  23. ultralytics/cfg/datasets/GlobalWheat2020.yaml +68 -0
  24. ultralytics/cfg/datasets/HomeObjects-3K.yaml +32 -0
  25. ultralytics/cfg/datasets/ImageNet.yaml +2025 -0
  26. ultralytics/cfg/datasets/Objects365.yaml +447 -0
  27. ultralytics/cfg/datasets/SKU-110K.yaml +58 -0
  28. ultralytics/cfg/datasets/TT100K.yaml +346 -0
  29. ultralytics/cfg/datasets/VOC.yaml +102 -0
  30. ultralytics/cfg/datasets/VisDrone.yaml +87 -0
  31. ultralytics/cfg/datasets/african-wildlife.yaml +25 -0
  32. ultralytics/cfg/datasets/brain-tumor.yaml +22 -0
  33. ultralytics/cfg/datasets/carparts-seg.yaml +44 -0
  34. ultralytics/cfg/datasets/coco-pose.yaml +64 -0
  35. ultralytics/cfg/datasets/coco.yaml +118 -0
  36. ultralytics/cfg/datasets/coco128-seg.yaml +101 -0
  37. ultralytics/cfg/datasets/coco128.yaml +101 -0
  38. ultralytics/cfg/datasets/coco8-grayscale.yaml +103 -0
  39. ultralytics/cfg/datasets/coco8-multispectral.yaml +104 -0
  40. ultralytics/cfg/datasets/coco8-pose.yaml +47 -0
  41. ultralytics/cfg/datasets/coco8-seg.yaml +101 -0
  42. ultralytics/cfg/datasets/coco8.yaml +101 -0
  43. ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
  44. ultralytics/cfg/datasets/crack-seg.yaml +22 -0
  45. ultralytics/cfg/datasets/dog-pose.yaml +52 -0
  46. ultralytics/cfg/datasets/dota8-multispectral.yaml +38 -0
  47. ultralytics/cfg/datasets/dota8.yaml +35 -0
  48. ultralytics/cfg/datasets/hand-keypoints.yaml +50 -0
  49. ultralytics/cfg/datasets/kitti.yaml +27 -0
  50. ultralytics/cfg/datasets/lvis.yaml +1240 -0
  51. ultralytics/cfg/datasets/medical-pills.yaml +21 -0
  52. ultralytics/cfg/datasets/open-images-v7.yaml +663 -0
  53. ultralytics/cfg/datasets/package-seg.yaml +22 -0
  54. ultralytics/cfg/datasets/signature.yaml +21 -0
  55. ultralytics/cfg/datasets/tiger-pose.yaml +41 -0
  56. ultralytics/cfg/datasets/xView.yaml +155 -0
  57. ultralytics/cfg/default.yaml +130 -0
  58. ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +17 -0
  59. ultralytics/cfg/models/11/yolo11-cls.yaml +33 -0
  60. ultralytics/cfg/models/11/yolo11-obb.yaml +50 -0
  61. ultralytics/cfg/models/11/yolo11-pose.yaml +51 -0
  62. ultralytics/cfg/models/11/yolo11-seg.yaml +50 -0
  63. ultralytics/cfg/models/11/yolo11.yaml +50 -0
  64. ultralytics/cfg/models/11/yoloe-11-seg.yaml +48 -0
  65. ultralytics/cfg/models/11/yoloe-11.yaml +48 -0
  66. ultralytics/cfg/models/12/yolo12-cls.yaml +32 -0
  67. ultralytics/cfg/models/12/yolo12-obb.yaml +48 -0
  68. ultralytics/cfg/models/12/yolo12-pose.yaml +49 -0
  69. ultralytics/cfg/models/12/yolo12-seg.yaml +48 -0
  70. ultralytics/cfg/models/12/yolo12.yaml +48 -0
  71. ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +53 -0
  72. ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +45 -0
  73. ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +45 -0
  74. ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +57 -0
  75. ultralytics/cfg/models/v10/yolov10b.yaml +45 -0
  76. ultralytics/cfg/models/v10/yolov10l.yaml +45 -0
  77. ultralytics/cfg/models/v10/yolov10m.yaml +45 -0
  78. ultralytics/cfg/models/v10/yolov10n.yaml +45 -0
  79. ultralytics/cfg/models/v10/yolov10s.yaml +45 -0
  80. ultralytics/cfg/models/v10/yolov10x.yaml +45 -0
  81. ultralytics/cfg/models/v3/yolov3-spp.yaml +49 -0
  82. ultralytics/cfg/models/v3/yolov3-tiny.yaml +40 -0
  83. ultralytics/cfg/models/v3/yolov3.yaml +49 -0
  84. ultralytics/cfg/models/v5/yolov5-p6.yaml +62 -0
  85. ultralytics/cfg/models/v5/yolov5.yaml +51 -0
  86. ultralytics/cfg/models/v6/yolov6.yaml +56 -0
  87. ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +48 -0
  88. ultralytics/cfg/models/v8/yoloe-v8.yaml +48 -0
  89. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +28 -0
  90. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +28 -0
  91. ultralytics/cfg/models/v8/yolov8-cls.yaml +32 -0
  92. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +58 -0
  93. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +60 -0
  94. ultralytics/cfg/models/v8/yolov8-ghost.yaml +50 -0
  95. ultralytics/cfg/models/v8/yolov8-obb.yaml +49 -0
  96. ultralytics/cfg/models/v8/yolov8-p2.yaml +57 -0
  97. ultralytics/cfg/models/v8/yolov8-p6.yaml +59 -0
  98. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +60 -0
  99. ultralytics/cfg/models/v8/yolov8-pose.yaml +50 -0
  100. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +49 -0
  101. ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +59 -0
  102. ultralytics/cfg/models/v8/yolov8-seg.yaml +49 -0
  103. ultralytics/cfg/models/v8/yolov8-world.yaml +51 -0
  104. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +49 -0
  105. ultralytics/cfg/models/v8/yolov8.yaml +49 -0
  106. ultralytics/cfg/models/v9/yolov9c-seg.yaml +41 -0
  107. ultralytics/cfg/models/v9/yolov9c.yaml +41 -0
  108. ultralytics/cfg/models/v9/yolov9e-seg.yaml +64 -0
  109. ultralytics/cfg/models/v9/yolov9e.yaml +64 -0
  110. ultralytics/cfg/models/v9/yolov9m.yaml +41 -0
  111. ultralytics/cfg/models/v9/yolov9s.yaml +41 -0
  112. ultralytics/cfg/models/v9/yolov9t.yaml +41 -0
  113. ultralytics/cfg/trackers/botsort.yaml +21 -0
  114. ultralytics/cfg/trackers/bytetrack.yaml +12 -0
  115. ultralytics/data/__init__.py +26 -0
  116. ultralytics/data/annotator.py +66 -0
  117. ultralytics/data/augment.py +2801 -0
  118. ultralytics/data/base.py +435 -0
  119. ultralytics/data/build.py +437 -0
  120. ultralytics/data/converter.py +855 -0
  121. ultralytics/data/dataset.py +834 -0
  122. ultralytics/data/loaders.py +704 -0
  123. ultralytics/data/scripts/download_weights.sh +18 -0
  124. ultralytics/data/scripts/get_coco.sh +61 -0
  125. ultralytics/data/scripts/get_coco128.sh +18 -0
  126. ultralytics/data/scripts/get_imagenet.sh +52 -0
  127. ultralytics/data/split.py +138 -0
  128. ultralytics/data/split_dota.py +344 -0
  129. ultralytics/data/utils.py +798 -0
  130. ultralytics/engine/__init__.py +1 -0
  131. ultralytics/engine/exporter.py +1580 -0
  132. ultralytics/engine/model.py +1125 -0
  133. ultralytics/engine/predictor.py +508 -0
  134. ultralytics/engine/results.py +1522 -0
  135. ultralytics/engine/trainer.py +977 -0
  136. ultralytics/engine/tuner.py +449 -0
  137. ultralytics/engine/validator.py +387 -0
  138. ultralytics/hub/__init__.py +166 -0
  139. ultralytics/hub/auth.py +151 -0
  140. ultralytics/hub/google/__init__.py +174 -0
  141. ultralytics/hub/session.py +422 -0
  142. ultralytics/hub/utils.py +162 -0
  143. ultralytics/models/__init__.py +9 -0
  144. ultralytics/models/fastsam/__init__.py +7 -0
  145. ultralytics/models/fastsam/model.py +79 -0
  146. ultralytics/models/fastsam/predict.py +169 -0
  147. ultralytics/models/fastsam/utils.py +23 -0
  148. ultralytics/models/fastsam/val.py +38 -0
  149. ultralytics/models/nas/__init__.py +7 -0
  150. ultralytics/models/nas/model.py +98 -0
  151. ultralytics/models/nas/predict.py +56 -0
  152. ultralytics/models/nas/val.py +38 -0
  153. ultralytics/models/rtdetr/__init__.py +7 -0
  154. ultralytics/models/rtdetr/model.py +63 -0
  155. ultralytics/models/rtdetr/predict.py +88 -0
  156. ultralytics/models/rtdetr/train.py +89 -0
  157. ultralytics/models/rtdetr/val.py +216 -0
  158. ultralytics/models/sam/__init__.py +25 -0
  159. ultralytics/models/sam/amg.py +275 -0
  160. ultralytics/models/sam/build.py +365 -0
  161. ultralytics/models/sam/build_sam3.py +377 -0
  162. ultralytics/models/sam/model.py +169 -0
  163. ultralytics/models/sam/modules/__init__.py +1 -0
  164. ultralytics/models/sam/modules/blocks.py +1067 -0
  165. ultralytics/models/sam/modules/decoders.py +495 -0
  166. ultralytics/models/sam/modules/encoders.py +794 -0
  167. ultralytics/models/sam/modules/memory_attention.py +298 -0
  168. ultralytics/models/sam/modules/sam.py +1160 -0
  169. ultralytics/models/sam/modules/tiny_encoder.py +979 -0
  170. ultralytics/models/sam/modules/transformer.py +344 -0
  171. ultralytics/models/sam/modules/utils.py +512 -0
  172. ultralytics/models/sam/predict.py +3940 -0
  173. ultralytics/models/sam/sam3/__init__.py +3 -0
  174. ultralytics/models/sam/sam3/decoder.py +546 -0
  175. ultralytics/models/sam/sam3/encoder.py +529 -0
  176. ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
  177. ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
  178. ultralytics/models/sam/sam3/model_misc.py +199 -0
  179. ultralytics/models/sam/sam3/necks.py +129 -0
  180. ultralytics/models/sam/sam3/sam3_image.py +339 -0
  181. ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
  182. ultralytics/models/sam/sam3/vitdet.py +547 -0
  183. ultralytics/models/sam/sam3/vl_combiner.py +160 -0
  184. ultralytics/models/utils/__init__.py +1 -0
  185. ultralytics/models/utils/loss.py +466 -0
  186. ultralytics/models/utils/ops.py +315 -0
  187. ultralytics/models/yolo/__init__.py +7 -0
  188. ultralytics/models/yolo/classify/__init__.py +7 -0
  189. ultralytics/models/yolo/classify/predict.py +90 -0
  190. ultralytics/models/yolo/classify/train.py +202 -0
  191. ultralytics/models/yolo/classify/val.py +216 -0
  192. ultralytics/models/yolo/detect/__init__.py +7 -0
  193. ultralytics/models/yolo/detect/predict.py +122 -0
  194. ultralytics/models/yolo/detect/train.py +227 -0
  195. ultralytics/models/yolo/detect/val.py +507 -0
  196. ultralytics/models/yolo/model.py +430 -0
  197. ultralytics/models/yolo/obb/__init__.py +7 -0
  198. ultralytics/models/yolo/obb/predict.py +56 -0
  199. ultralytics/models/yolo/obb/train.py +79 -0
  200. ultralytics/models/yolo/obb/val.py +302 -0
  201. ultralytics/models/yolo/pose/__init__.py +7 -0
  202. ultralytics/models/yolo/pose/predict.py +65 -0
  203. ultralytics/models/yolo/pose/train.py +110 -0
  204. ultralytics/models/yolo/pose/val.py +248 -0
  205. ultralytics/models/yolo/segment/__init__.py +7 -0
  206. ultralytics/models/yolo/segment/predict.py +109 -0
  207. ultralytics/models/yolo/segment/train.py +69 -0
  208. ultralytics/models/yolo/segment/val.py +307 -0
  209. ultralytics/models/yolo/world/__init__.py +5 -0
  210. ultralytics/models/yolo/world/train.py +173 -0
  211. ultralytics/models/yolo/world/train_world.py +178 -0
  212. ultralytics/models/yolo/yoloe/__init__.py +22 -0
  213. ultralytics/models/yolo/yoloe/predict.py +162 -0
  214. ultralytics/models/yolo/yoloe/train.py +287 -0
  215. ultralytics/models/yolo/yoloe/train_seg.py +122 -0
  216. ultralytics/models/yolo/yoloe/val.py +206 -0
  217. ultralytics/nn/__init__.py +27 -0
  218. ultralytics/nn/autobackend.py +964 -0
  219. ultralytics/nn/modules/__init__.py +182 -0
  220. ultralytics/nn/modules/activation.py +54 -0
  221. ultralytics/nn/modules/block.py +1947 -0
  222. ultralytics/nn/modules/conv.py +669 -0
  223. ultralytics/nn/modules/head.py +1183 -0
  224. ultralytics/nn/modules/transformer.py +793 -0
  225. ultralytics/nn/modules/utils.py +159 -0
  226. ultralytics/nn/tasks.py +1768 -0
  227. ultralytics/nn/text_model.py +356 -0
  228. ultralytics/py.typed +1 -0
  229. ultralytics/solutions/__init__.py +41 -0
  230. ultralytics/solutions/ai_gym.py +108 -0
  231. ultralytics/solutions/analytics.py +264 -0
  232. ultralytics/solutions/config.py +107 -0
  233. ultralytics/solutions/distance_calculation.py +123 -0
  234. ultralytics/solutions/heatmap.py +125 -0
  235. ultralytics/solutions/instance_segmentation.py +86 -0
  236. ultralytics/solutions/object_blurrer.py +89 -0
  237. ultralytics/solutions/object_counter.py +190 -0
  238. ultralytics/solutions/object_cropper.py +87 -0
  239. ultralytics/solutions/parking_management.py +280 -0
  240. ultralytics/solutions/queue_management.py +93 -0
  241. ultralytics/solutions/region_counter.py +133 -0
  242. ultralytics/solutions/security_alarm.py +151 -0
  243. ultralytics/solutions/similarity_search.py +219 -0
  244. ultralytics/solutions/solutions.py +828 -0
  245. ultralytics/solutions/speed_estimation.py +114 -0
  246. ultralytics/solutions/streamlit_inference.py +260 -0
  247. ultralytics/solutions/templates/similarity-search.html +156 -0
  248. ultralytics/solutions/trackzone.py +88 -0
  249. ultralytics/solutions/vision_eye.py +67 -0
  250. ultralytics/trackers/__init__.py +7 -0
  251. ultralytics/trackers/basetrack.py +115 -0
  252. ultralytics/trackers/bot_sort.py +257 -0
  253. ultralytics/trackers/byte_tracker.py +469 -0
  254. ultralytics/trackers/track.py +116 -0
  255. ultralytics/trackers/utils/__init__.py +1 -0
  256. ultralytics/trackers/utils/gmc.py +339 -0
  257. ultralytics/trackers/utils/kalman_filter.py +482 -0
  258. ultralytics/trackers/utils/matching.py +154 -0
  259. ultralytics/utils/__init__.py +1450 -0
  260. ultralytics/utils/autobatch.py +118 -0
  261. ultralytics/utils/autodevice.py +205 -0
  262. ultralytics/utils/benchmarks.py +728 -0
  263. ultralytics/utils/callbacks/__init__.py +5 -0
  264. ultralytics/utils/callbacks/base.py +233 -0
  265. ultralytics/utils/callbacks/clearml.py +146 -0
  266. ultralytics/utils/callbacks/comet.py +625 -0
  267. ultralytics/utils/callbacks/dvc.py +197 -0
  268. ultralytics/utils/callbacks/hub.py +110 -0
  269. ultralytics/utils/callbacks/mlflow.py +134 -0
  270. ultralytics/utils/callbacks/neptune.py +126 -0
  271. ultralytics/utils/callbacks/platform.py +453 -0
  272. ultralytics/utils/callbacks/raytune.py +42 -0
  273. ultralytics/utils/callbacks/tensorboard.py +123 -0
  274. ultralytics/utils/callbacks/wb.py +188 -0
  275. ultralytics/utils/checks.py +1020 -0
  276. ultralytics/utils/cpu.py +85 -0
  277. ultralytics/utils/dist.py +123 -0
  278. ultralytics/utils/downloads.py +529 -0
  279. ultralytics/utils/errors.py +35 -0
  280. ultralytics/utils/events.py +113 -0
  281. ultralytics/utils/export/__init__.py +7 -0
  282. ultralytics/utils/export/engine.py +237 -0
  283. ultralytics/utils/export/imx.py +325 -0
  284. ultralytics/utils/export/tensorflow.py +231 -0
  285. ultralytics/utils/files.py +219 -0
  286. ultralytics/utils/git.py +137 -0
  287. ultralytics/utils/instance.py +484 -0
  288. ultralytics/utils/logger.py +506 -0
  289. ultralytics/utils/loss.py +849 -0
  290. ultralytics/utils/metrics.py +1563 -0
  291. ultralytics/utils/nms.py +337 -0
  292. ultralytics/utils/ops.py +664 -0
  293. ultralytics/utils/patches.py +201 -0
  294. ultralytics/utils/plotting.py +1047 -0
  295. ultralytics/utils/tal.py +404 -0
  296. ultralytics/utils/torch_utils.py +984 -0
  297. ultralytics/utils/tqdm.py +443 -0
  298. ultralytics/utils/triton.py +112 -0
  299. ultralytics/utils/tuner.py +168 -0
@@ -0,0 +1,1028 @@
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
+
3
+ from __future__ import annotations
4
+
5
+ import ast
6
+ import shutil
7
+ import subprocess
8
+ import sys
9
+ from pathlib import Path
10
+ from types import SimpleNamespace
11
+ from typing import Any
12
+
13
+ from ultralytics import __version__
14
+ from ultralytics.utils import (
15
+ ASSETS,
16
+ DEFAULT_CFG,
17
+ DEFAULT_CFG_DICT,
18
+ DEFAULT_CFG_PATH,
19
+ FLOAT_OR_INT,
20
+ IS_VSCODE,
21
+ LOGGER,
22
+ RANK,
23
+ ROOT,
24
+ RUNS_DIR,
25
+ SETTINGS,
26
+ SETTINGS_FILE,
27
+ STR_OR_PATH,
28
+ TESTS_RUNNING,
29
+ YAML,
30
+ IterableSimpleNamespace,
31
+ checks,
32
+ colorstr,
33
+ deprecation_warn,
34
+ vscode_msg,
35
+ )
36
+
37
+ # Define valid solutions
38
+ SOLUTION_MAP = {
39
+ "count": "ObjectCounter",
40
+ "crop": "ObjectCropper",
41
+ "blur": "ObjectBlurrer",
42
+ "workout": "AIGym",
43
+ "heatmap": "Heatmap",
44
+ "isegment": "InstanceSegmentation",
45
+ "visioneye": "VisionEye",
46
+ "speed": "SpeedEstimator",
47
+ "queue": "QueueManager",
48
+ "analytics": "Analytics",
49
+ "inference": "Inference",
50
+ "trackzone": "TrackZone",
51
+ "help": None,
52
+ }
53
+
54
+ # Define valid tasks and modes
55
+ MODES = frozenset({"train", "val", "predict", "export", "track", "benchmark"})
56
+ TASKS = frozenset({"detect", "segment", "classify", "pose", "obb"})
57
+ TASK2DATA = {
58
+ "detect": "coco8.yaml",
59
+ "segment": "coco8-seg.yaml",
60
+ "classify": "imagenet10",
61
+ "pose": "coco8-pose.yaml",
62
+ "obb": "dota8.yaml",
63
+ }
64
+ TASK2MODEL = {
65
+ "detect": "yolo11n.pt",
66
+ "segment": "yolo11n-seg.pt",
67
+ "classify": "yolo11n-cls.pt",
68
+ "pose": "yolo11n-pose.pt",
69
+ "obb": "yolo11n-obb.pt",
70
+ }
71
+ TASK2METRIC = {
72
+ "detect": "metrics/mAP50-95(B)",
73
+ "segment": "metrics/mAP50-95(M)",
74
+ "classify": "metrics/accuracy_top1",
75
+ "pose": "metrics/mAP50-95(P)",
76
+ "obb": "metrics/mAP50-95(B)",
77
+ }
78
+
79
+ ARGV = sys.argv or ["", ""] # sometimes sys.argv = []
80
+ SOLUTIONS_HELP_MSG = f"""
81
+ Arguments received: {["yolo", *ARGV[1:]]!s}. Ultralytics 'yolo solutions' usage overview:
82
+
83
+ yolo solutions SOLUTION ARGS
84
+
85
+ Where SOLUTION (optional) is one of {list(SOLUTION_MAP.keys())[:-1]}
86
+ ARGS (optional) are any number of custom 'arg=value' pairs like 'show_in=True' that override defaults
87
+ at https://docs.ultralytics.com/usage/cfg
88
+
89
+ 1. Call object counting solution
90
+ yolo solutions count source="path/to/video.mp4" region="[(20, 400), (1080, 400), (1080, 360), (20, 360)]"
91
+
92
+ 2. Call heatmap solution
93
+ yolo solutions heatmap colormap=cv2.COLORMAP_PARULA model=yolo11n.pt
94
+
95
+ 3. Call queue management solution
96
+ yolo solutions queue region="[(20, 400), (1080, 400), (1080, 360), (20, 360)]" model=yolo11n.pt
97
+
98
+ 4. Call workout monitoring solution for push-ups
99
+ yolo solutions workout model=yolo11n-pose.pt kpts=[6, 8, 10]
100
+
101
+ 5. Generate analytical graphs
102
+ yolo solutions analytics analytics_type="pie"
103
+
104
+ 6. Track objects within specific zones
105
+ yolo solutions trackzone source="path/to/video.mp4" region="[(150, 150), (1130, 150), (1130, 570), (150, 570)]"
106
+
107
+ 7. Streamlit real-time webcam inference GUI
108
+ yolo streamlit-predict
109
+ """
110
+ CLI_HELP_MSG = f"""
111
+ Arguments received: {["yolo", *ARGV[1:]]!s}. Ultralytics 'yolo' commands use the following syntax:
112
+
113
+ yolo TASK MODE ARGS
114
+
115
+ Where TASK (optional) is one of {list(TASKS)}
116
+ MODE (required) is one of {list(MODES)}
117
+ ARGS (optional) are any number of custom 'arg=value' pairs like 'imgsz=320' that override defaults.
118
+ See all ARGS at https://docs.ultralytics.com/usage/cfg or with 'yolo cfg'
119
+
120
+ 1. Train a detection model for 10 epochs with an initial learning_rate of 0.01
121
+ yolo train data=coco8.yaml model=yolo11n.pt epochs=10 lr0=0.01
122
+
123
+ 2. Predict a YouTube video using a pretrained segmentation model at image size 320:
124
+ yolo predict model=yolo11n-seg.pt source='https://youtu.be/LNwODJXcvt4' imgsz=320
125
+
126
+ 3. Validate a pretrained detection model at batch-size 1 and image size 640:
127
+ yolo val model=yolo11n.pt data=coco8.yaml batch=1 imgsz=640
128
+
129
+ 4. Export a YOLO11n classification model to ONNX format at image size 224 by 128 (no TASK required)
130
+ yolo export model=yolo11n-cls.pt format=onnx imgsz=224,128
131
+
132
+ 5. Ultralytics solutions usage
133
+ yolo solutions count or any of {list(SOLUTION_MAP.keys())[1:-1]} source="path/to/video.mp4"
134
+
135
+ 6. Run special commands:
136
+ yolo help
137
+ yolo checks
138
+ yolo version
139
+ yolo settings
140
+ yolo copy-cfg
141
+ yolo cfg
142
+ yolo solutions help
143
+
144
+ Docs: https://docs.ultralytics.com
145
+ Solutions: https://docs.ultralytics.com/solutions/
146
+ Community: https://community.ultralytics.com
147
+ GitHub: https://github.com/ultralytics/ultralytics
148
+ """
149
+
150
+ # Define keys for arg type checks
151
+ CFG_FLOAT_KEYS = frozenset(
152
+ { # integer or float arguments, i.e. x=2 and x=2.0
153
+ "warmup_epochs",
154
+ "box",
155
+ "cls",
156
+ "dfl",
157
+ "degrees",
158
+ "shear",
159
+ "time",
160
+ "workspace",
161
+ "batch",
162
+ }
163
+ )
164
+ CFG_FRACTION_KEYS = frozenset(
165
+ { # fractional float arguments with 0.0<=values<=1.0
166
+ "dropout",
167
+ "lr0",
168
+ "lrf",
169
+ "momentum",
170
+ "weight_decay",
171
+ "warmup_momentum",
172
+ "warmup_bias_lr",
173
+ "hsv_h",
174
+ "hsv_s",
175
+ "hsv_v",
176
+ "translate",
177
+ "scale",
178
+ "perspective",
179
+ "flipud",
180
+ "fliplr",
181
+ "bgr",
182
+ "mosaic",
183
+ "mixup",
184
+ "cutmix",
185
+ "copy_paste",
186
+ "conf",
187
+ "iou",
188
+ "fraction",
189
+ }
190
+ )
191
+ CFG_INT_KEYS = frozenset(
192
+ { # integer-only arguments
193
+ "epochs",
194
+ "patience",
195
+ "workers",
196
+ "seed",
197
+ "close_mosaic",
198
+ "mask_ratio",
199
+ "max_det",
200
+ "vid_stride",
201
+ "line_width",
202
+ "nbs",
203
+ "save_period",
204
+ }
205
+ )
206
+ CFG_BOOL_KEYS = frozenset(
207
+ { # boolean-only arguments
208
+ "save",
209
+ "exist_ok",
210
+ "verbose",
211
+ "deterministic",
212
+ "single_cls",
213
+ "rect",
214
+ "cos_lr",
215
+ "overlap_mask",
216
+ "val",
217
+ "save_json",
218
+ "half",
219
+ "dnn",
220
+ "plots",
221
+ "show",
222
+ "save_txt",
223
+ "save_conf",
224
+ "save_crop",
225
+ "save_frames",
226
+ "show_labels",
227
+ "show_conf",
228
+ "visualize",
229
+ "augment",
230
+ "agnostic_nms",
231
+ "retina_masks",
232
+ "show_boxes",
233
+ "keras",
234
+ "optimize",
235
+ "int8",
236
+ "dynamic",
237
+ "simplify",
238
+ "nms",
239
+ "profile",
240
+ "multi_scale",
241
+ }
242
+ )
243
+
244
+
245
+ def cfg2dict(cfg: str | Path | dict | SimpleNamespace) -> dict:
246
+ """Convert a configuration object to a dictionary.
247
+
248
+ Args:
249
+ cfg (str | Path | dict | SimpleNamespace): Configuration object to be converted. Can be a file path, a string, a
250
+ dictionary, or a SimpleNamespace object.
251
+
252
+ Returns:
253
+ (dict): Configuration object in dictionary format.
254
+
255
+ Examples:
256
+ Convert a YAML file path to a dictionary:
257
+ >>> config_dict = cfg2dict("config.yaml")
258
+
259
+ Convert a SimpleNamespace to a dictionary:
260
+ >>> from types import SimpleNamespace
261
+ >>> config_sn = SimpleNamespace(param1="value1", param2="value2")
262
+ >>> config_dict = cfg2dict(config_sn)
263
+
264
+ Pass through an already existing dictionary:
265
+ >>> config_dict = cfg2dict({"param1": "value1", "param2": "value2"})
266
+
267
+ Notes:
268
+ - If cfg is a path or string, it's loaded as YAML and converted to a dictionary.
269
+ - If cfg is a SimpleNamespace object, it's converted to a dictionary using vars().
270
+ - If cfg is already a dictionary, it's returned unchanged.
271
+ """
272
+ if isinstance(cfg, STR_OR_PATH):
273
+ cfg = YAML.load(cfg) # load dict
274
+ elif isinstance(cfg, SimpleNamespace):
275
+ cfg = vars(cfg) # convert to dict
276
+ return cfg
277
+
278
+
279
+ def get_cfg(
280
+ cfg: str | Path | dict | SimpleNamespace = DEFAULT_CFG_DICT, overrides: dict | None = None
281
+ ) -> SimpleNamespace:
282
+ """Load and merge configuration data from a file or dictionary, with optional overrides.
283
+
284
+ Args:
285
+ cfg (str | Path | dict | SimpleNamespace): Configuration data source. Can be a file path, dictionary, or
286
+ SimpleNamespace object.
287
+ overrides (dict | None): Dictionary containing key-value pairs to override the base configuration.
288
+
289
+ Returns:
290
+ (SimpleNamespace): Namespace containing the merged configuration arguments.
291
+
292
+ Examples:
293
+ >>> from ultralytics.cfg import get_cfg
294
+ >>> config = get_cfg() # Load default configuration
295
+ >>> config_with_overrides = get_cfg("path/to/config.yaml", overrides={"epochs": 50, "batch_size": 16})
296
+
297
+ Notes:
298
+ - If both `cfg` and `overrides` are provided, the values in `overrides` will take precedence.
299
+ - Special handling ensures alignment and correctness of the configuration, such as converting numeric
300
+ `project` and `name` to strings and validating configuration keys and values.
301
+ - The function performs type and value checks on the configuration data.
302
+ """
303
+ cfg = cfg2dict(cfg)
304
+
305
+ # Merge overrides
306
+ if overrides:
307
+ overrides = cfg2dict(overrides)
308
+ if "save_dir" not in cfg:
309
+ overrides.pop("save_dir", None) # special override keys to ignore
310
+ check_dict_alignment(cfg, overrides)
311
+ cfg = {**cfg, **overrides} # merge cfg and overrides dicts (prefer overrides)
312
+
313
+ # Special handling for numeric project/name
314
+ for k in "project", "name":
315
+ if k in cfg and isinstance(cfg[k], FLOAT_OR_INT):
316
+ cfg[k] = str(cfg[k])
317
+ if cfg.get("name") == "model": # assign model to 'name' arg
318
+ cfg["name"] = str(cfg.get("model", "")).partition(".")[0]
319
+ LOGGER.warning(f"'name=model' automatically updated to 'name={cfg['name']}'.")
320
+
321
+ # Type and Value checks
322
+ check_cfg(cfg)
323
+
324
+ # Return instance
325
+ return IterableSimpleNamespace(**cfg)
326
+
327
+
328
+ def check_cfg(cfg: dict, hard: bool = True) -> None:
329
+ """Check configuration argument types and values for the Ultralytics library.
330
+
331
+ This function validates the types and values of configuration arguments, ensuring correctness and converting them if
332
+ necessary. It checks for specific key types defined in global variables such as `CFG_FLOAT_KEYS`,
333
+ `CFG_FRACTION_KEYS`, `CFG_INT_KEYS`, and `CFG_BOOL_KEYS`.
334
+
335
+ Args:
336
+ cfg (dict): Configuration dictionary to validate.
337
+ hard (bool): If True, raises exceptions for invalid types and values; if False, attempts to convert them.
338
+
339
+ Examples:
340
+ >>> config = {
341
+ ... "epochs": 50, # valid integer
342
+ ... "lr0": 0.01, # valid float
343
+ ... "momentum": 1.2, # invalid float (out of 0.0-1.0 range)
344
+ ... "save": "true", # invalid bool
345
+ ... }
346
+ >>> check_cfg(config, hard=False)
347
+ >>> print(config)
348
+ {'epochs': 50, 'lr0': 0.01, 'momentum': 1.2, 'save': False} # corrected 'save' key
349
+
350
+ Notes:
351
+ - The function modifies the input dictionary in-place.
352
+ - None values are ignored as they may be from optional arguments.
353
+ - Fraction keys are checked to be within the range [0.0, 1.0].
354
+ """
355
+ for k, v in cfg.items():
356
+ if v is not None: # None values may be from optional args
357
+ if k in CFG_FLOAT_KEYS and not isinstance(v, FLOAT_OR_INT):
358
+ if hard:
359
+ raise TypeError(
360
+ f"'{k}={v}' is of invalid type {type(v).__name__}. "
361
+ f"Valid '{k}' types are int (i.e. '{k}=0') or float (i.e. '{k}=0.5')"
362
+ )
363
+ cfg[k] = float(v)
364
+ elif k in CFG_FRACTION_KEYS:
365
+ if not isinstance(v, FLOAT_OR_INT):
366
+ if hard:
367
+ raise TypeError(
368
+ f"'{k}={v}' is of invalid type {type(v).__name__}. "
369
+ f"Valid '{k}' types are int (i.e. '{k}=0') or float (i.e. '{k}=0.5')"
370
+ )
371
+ cfg[k] = v = float(v)
372
+ if not (0.0 <= v <= 1.0):
373
+ raise ValueError(f"'{k}={v}' is an invalid value. Valid '{k}' values are between 0.0 and 1.0.")
374
+ elif k in CFG_INT_KEYS and not isinstance(v, int):
375
+ if hard:
376
+ raise TypeError(
377
+ f"'{k}={v}' is of invalid type {type(v).__name__}. '{k}' must be an int (i.e. '{k}=8')"
378
+ )
379
+ cfg[k] = int(v)
380
+ elif k in CFG_BOOL_KEYS and not isinstance(v, bool):
381
+ if hard:
382
+ raise TypeError(
383
+ f"'{k}={v}' is of invalid type {type(v).__name__}. "
384
+ f"'{k}' must be a bool (i.e. '{k}=True' or '{k}=False')"
385
+ )
386
+ cfg[k] = bool(v)
387
+
388
+
389
+ def get_save_dir(args: SimpleNamespace, name: str | None = None) -> Path:
390
+ """Return the directory path for saving outputs, derived from arguments or default settings.
391
+
392
+ Args:
393
+ args (SimpleNamespace): Namespace object containing configurations such as 'project', 'name', 'task', 'mode',
394
+ and 'save_dir'.
395
+ name (str | None): Optional name for the output directory. If not provided, it defaults to 'args.name' or the
396
+ 'args.mode'.
397
+
398
+ Returns:
399
+ (Path): Directory path where outputs should be saved.
400
+
401
+ Examples:
402
+ >>> from types import SimpleNamespace
403
+ >>> args = SimpleNamespace(project="my_project", task="detect", mode="train", exist_ok=True)
404
+ >>> save_dir = get_save_dir(args)
405
+ >>> print(save_dir)
406
+ my_project/detect/train
407
+ """
408
+ if getattr(args, "save_dir", None):
409
+ save_dir = args.save_dir
410
+ else:
411
+ from ultralytics.utils.files import increment_path
412
+
413
+ runs = (ROOT.parent / "tests/tmp/runs" if TESTS_RUNNING else RUNS_DIR) / args.task
414
+ nested = args.project and len(Path(args.project).parts) > 1 # e.g. "user/project" or "org\repo"
415
+ project = runs / args.project if nested else args.project or runs
416
+ name = name or args.name or f"{args.mode}"
417
+ save_dir = increment_path(Path(project) / name, exist_ok=args.exist_ok if RANK in {-1, 0} else True, mkdir=True)
418
+
419
+ return Path(save_dir).resolve() # resolve to display full path in console
420
+
421
+
422
+ def _handle_deprecation(custom: dict) -> dict:
423
+ """Handle deprecated configuration keys by mapping them to current equivalents with deprecation warnings.
424
+
425
+ Args:
426
+ custom (dict): Configuration dictionary potentially containing deprecated keys.
427
+
428
+ Returns:
429
+ (dict): Updated configuration dictionary with deprecated keys replaced.
430
+
431
+ Examples:
432
+ >>> custom_config = {"boxes": True, "hide_labels": "False", "line_thickness": 2}
433
+ >>> _handle_deprecation(custom_config)
434
+ >>> print(custom_config)
435
+ {'show_boxes': True, 'show_labels': True, 'line_width': 2}
436
+
437
+ Notes:
438
+ This function modifies the input dictionary in-place, replacing deprecated keys with their current
439
+ equivalents. It also handles value conversions where necessary, such as inverting boolean values for
440
+ 'hide_labels' and 'hide_conf'.
441
+ """
442
+ deprecated_mappings = {
443
+ "boxes": ("show_boxes", lambda v: v),
444
+ "hide_labels": ("show_labels", lambda v: not bool(v)),
445
+ "hide_conf": ("show_conf", lambda v: not bool(v)),
446
+ "line_thickness": ("line_width", lambda v: v),
447
+ }
448
+ removed_keys = {"label_smoothing", "save_hybrid", "crop_fraction"}
449
+
450
+ for old_key, (new_key, transform) in deprecated_mappings.items():
451
+ if old_key not in custom:
452
+ continue
453
+ deprecation_warn(old_key, new_key)
454
+ custom[new_key] = transform(custom.pop(old_key))
455
+
456
+ for key in removed_keys:
457
+ if key not in custom:
458
+ continue
459
+ deprecation_warn(key)
460
+ custom.pop(key)
461
+
462
+ return custom
463
+
464
+
465
+ def check_dict_alignment(
466
+ base: dict, custom: dict, e: Exception | None = None, allowed_custom_keys: set | None = None
467
+ ) -> None:
468
+ """Check alignment between custom and base configuration dictionaries, handling deprecated keys and providing error
469
+ messages for mismatched keys.
470
+
471
+ Args:
472
+ base (dict): The base configuration dictionary containing valid keys.
473
+ custom (dict): The custom configuration dictionary to be checked for alignment.
474
+ e (Exception | None): Optional error instance passed by the calling function.
475
+ allowed_custom_keys (set | None): Optional set of additional keys that are allowed in the custom dictionary.
476
+
477
+ Raises:
478
+ SystemExit: If mismatched keys are found between the custom and base dictionaries.
479
+
480
+ Examples:
481
+ >>> base_cfg = {"epochs": 50, "lr0": 0.01, "batch_size": 16}
482
+ >>> custom_cfg = {"epoch": 100, "lr": 0.02, "batch_size": 32}
483
+ >>> try:
484
+ ... check_dict_alignment(base_cfg, custom_cfg)
485
+ ... except SystemExit:
486
+ ... print("Mismatched keys found")
487
+
488
+ Notes:
489
+ - Suggests corrections for mismatched keys based on similarity to valid keys.
490
+ - Automatically replaces deprecated keys in the custom configuration with updated equivalents.
491
+ - Prints detailed error messages for each mismatched key to help users correct their configurations.
492
+ """
493
+ custom = _handle_deprecation(custom)
494
+ base_keys, custom_keys = (frozenset(x.keys()) for x in (base, custom))
495
+ # Allow 'augmentations' as a valid custom parameter for custom Albumentations transforms
496
+ if allowed_custom_keys is None:
497
+ allowed_custom_keys = {"augmentations"}
498
+ if mismatched := [k for k in custom_keys if k not in base_keys and k not in allowed_custom_keys]:
499
+ from difflib import get_close_matches
500
+
501
+ string = ""
502
+ for x in mismatched:
503
+ matches = get_close_matches(x, base_keys) # key list
504
+ matches = [f"{k}={base[k]}" if base.get(k) is not None else k for k in matches]
505
+ match_str = f"Similar arguments are i.e. {matches}." if matches else ""
506
+ string += f"'{colorstr('red', 'bold', x)}' is not a valid YOLO argument. {match_str}\n"
507
+ raise SyntaxError(string + CLI_HELP_MSG) from e
508
+
509
+
510
+ def merge_equals_args(args: list[str]) -> list[str]:
511
+ """Merge arguments around isolated '=' in a list of strings and join fragments with brackets.
512
+
513
+ This function handles the following cases:
514
+ 1. ['arg', '=', 'val'] becomes ['arg=val']
515
+ 2. ['arg=', 'val'] becomes ['arg=val']
516
+ 3. ['arg', '=val'] becomes ['arg=val']
517
+ 4. Joins fragments with brackets, e.g., ['imgsz=[3,', '640,', '640]'] becomes ['imgsz=[3,640,640]']
518
+
519
+ Args:
520
+ args (list[str]): A list of strings where each element represents an argument or fragment.
521
+
522
+ Returns:
523
+ (list[str]): A list of strings where the arguments around isolated '=' are merged and fragments with brackets
524
+ are joined.
525
+
526
+ Examples:
527
+ >>> args = ["arg1", "=", "value", "arg2=", "value2", "arg3", "=value3", "imgsz=[3,", "640,", "640]"]
528
+ >>> merge_equals_args(args)
529
+ ['arg1=value', 'arg2=value2', 'arg3=value3', 'imgsz=[3,640,640]']
530
+ """
531
+ new_args = []
532
+ current = ""
533
+ depth = 0
534
+
535
+ i = 0
536
+ while i < len(args):
537
+ arg = args[i]
538
+
539
+ # Handle equals sign merging
540
+ if arg == "=" and 0 < i < len(args) - 1: # merge ['arg', '=', 'val']
541
+ new_args[-1] += f"={args[i + 1]}"
542
+ i += 2
543
+ continue
544
+ elif arg.endswith("=") and i < len(args) - 1 and "=" not in args[i + 1]: # merge ['arg=', 'val']
545
+ new_args.append(f"{arg}{args[i + 1]}")
546
+ i += 2
547
+ continue
548
+ elif arg.startswith("=") and i > 0: # merge ['arg', '=val']
549
+ new_args[-1] += arg
550
+ i += 1
551
+ continue
552
+
553
+ # Handle bracket joining
554
+ depth += arg.count("[") - arg.count("]")
555
+ current += arg
556
+ if depth == 0:
557
+ new_args.append(current)
558
+ current = ""
559
+
560
+ i += 1
561
+
562
+ # Append any remaining current string
563
+ if current:
564
+ new_args.append(current)
565
+
566
+ return new_args
567
+
568
+
569
+ def handle_yolo_hub(args: list[str]) -> None:
570
+ """Handle Ultralytics HUB command-line interface (CLI) commands for authentication.
571
+
572
+ This function processes Ultralytics HUB CLI commands such as login and logout. It should be called when executing a
573
+ script with arguments related to HUB authentication.
574
+
575
+ Args:
576
+ args (list[str]): A list of command line arguments. The first argument should be either 'login' or 'logout'. For
577
+ 'login', an optional second argument can be the API key.
578
+
579
+ Examples:
580
+ $ yolo login YOUR_API_KEY
581
+
582
+ Notes:
583
+ - The function imports the 'hub' module from ultralytics to perform login and logout operations.
584
+ - For the 'login' command, if no API key is provided, an empty string is passed to the login function.
585
+ - The 'logout' command does not require any additional arguments.
586
+ """
587
+ from ultralytics import hub
588
+
589
+ if args[0] == "login":
590
+ key = args[1] if len(args) > 1 else ""
591
+ # Log in to Ultralytics HUB using the provided API key
592
+ hub.login(key)
593
+ elif args[0] == "logout":
594
+ # Log out from Ultralytics HUB
595
+ hub.logout()
596
+
597
+
598
+ def handle_yolo_settings(args: list[str]) -> None:
599
+ """Handle YOLO settings command-line interface (CLI) commands.
600
+
601
+ This function processes YOLO settings CLI commands such as reset and updating individual settings. It should be
602
+ called when executing a script with arguments related to YOLO settings management.
603
+
604
+ Args:
605
+ args (list[str]): A list of command line arguments for YOLO settings management.
606
+
607
+ Examples:
608
+ >>> handle_yolo_settings(["reset"]) # Reset YOLO settings
609
+ >>> handle_yolo_settings(["default_cfg_path=yolo11n.yaml"]) # Update a specific setting
610
+
611
+ Notes:
612
+ - If no arguments are provided, the function will display the current settings.
613
+ - The 'reset' command will delete the existing settings file and create new default settings.
614
+ - Other arguments are treated as key-value pairs to update specific settings.
615
+ - The function will check for alignment between the provided settings and the existing ones.
616
+ - After processing, the updated settings will be displayed.
617
+ - For more information on handling YOLO settings, visit:
618
+ https://docs.ultralytics.com/quickstart/#ultralytics-settings
619
+ """
620
+ url = "https://docs.ultralytics.com/quickstart/#ultralytics-settings" # help URL
621
+ try:
622
+ if any(args):
623
+ if args[0] == "reset":
624
+ SETTINGS_FILE.unlink() # delete the settings file
625
+ SETTINGS.reset() # create new settings
626
+ LOGGER.info("Settings reset successfully") # inform the user that settings have been reset
627
+ else: # save a new setting
628
+ new = dict(parse_key_value_pair(a) for a in args)
629
+ check_dict_alignment(SETTINGS, new)
630
+ SETTINGS.update(new)
631
+ for k, v in new.items():
632
+ LOGGER.info(f"✅ Updated '{k}={v}'")
633
+
634
+ LOGGER.info(SETTINGS) # print the current settings
635
+ LOGGER.info(f"💡 Learn more about Ultralytics Settings at {url}")
636
+ except Exception as e:
637
+ LOGGER.warning(f"settings error: '{e}'. Please see {url} for help.")
638
+
639
+
640
+ def handle_yolo_solutions(args: list[str]) -> None:
641
+ """Process YOLO solutions arguments and run the specified computer vision solutions pipeline.
642
+
643
+ Args:
644
+ args (list[str]): Command-line arguments for configuring and running the Ultralytics YOLO solutions.
645
+
646
+ Examples:
647
+ Run people counting solution with default settings:
648
+ >>> handle_yolo_solutions(["count"])
649
+
650
+ Run analytics with custom configuration:
651
+ >>> handle_yolo_solutions(["analytics", "conf=0.25", "source=path/to/video.mp4"])
652
+
653
+ Run inference with custom configuration, requires Streamlit version 1.29.0 or higher.
654
+ >>> handle_yolo_solutions(["inference", "model=yolo11n.pt"])
655
+
656
+ Notes:
657
+ - Arguments can be provided in the format 'key=value' or as boolean flags
658
+ - Available solutions are defined in SOLUTION_MAP with their respective classes and methods
659
+ - If an invalid solution is provided, defaults to 'count' solution
660
+ - Output videos are saved in 'runs/solution/{solution_name}' directory
661
+ - For 'analytics' solution, frame numbers are tracked for generating analytical graphs
662
+ - Video processing can be interrupted by pressing 'q'
663
+ - Processes video frames sequentially and saves output in .avi format
664
+ - If no source is specified, downloads and uses a default sample video
665
+ - The inference solution will be launched using the 'streamlit run' command.
666
+ - The Streamlit app file is located in the Ultralytics package directory.
667
+ """
668
+ from ultralytics.solutions.config import SolutionConfig
669
+
670
+ full_args_dict = vars(SolutionConfig()) # arguments dictionary
671
+ overrides = {}
672
+
673
+ # check dictionary alignment
674
+ for arg in merge_equals_args(args):
675
+ arg = arg.lstrip("-").rstrip(",")
676
+ if "=" in arg:
677
+ try:
678
+ k, v = parse_key_value_pair(arg)
679
+ overrides[k] = v
680
+ except (NameError, SyntaxError, ValueError, AssertionError) as e:
681
+ check_dict_alignment(full_args_dict, {arg: ""}, e)
682
+ elif arg in full_args_dict and isinstance(full_args_dict.get(arg), bool):
683
+ overrides[arg] = True
684
+ check_dict_alignment(full_args_dict, overrides) # dict alignment
685
+
686
+ # Get solution name
687
+ if not args:
688
+ LOGGER.warning("No solution name provided. i.e `yolo solutions count`. Defaulting to 'count'.")
689
+ args = ["count"]
690
+ if args[0] == "help":
691
+ LOGGER.info(SOLUTIONS_HELP_MSG)
692
+ return # Early return for 'help' case
693
+ elif args[0] in SOLUTION_MAP:
694
+ solution_name = args.pop(0) # Extract the solution name directly
695
+ else:
696
+ LOGGER.warning(
697
+ f"❌ '{args[0]}' is not a valid solution. 💡 Defaulting to 'count'.\n"
698
+ f"🚀 Available solutions: {', '.join(list(SOLUTION_MAP.keys())[:-1])}\n"
699
+ )
700
+ solution_name = "count" # Default for invalid solution
701
+
702
+ if solution_name == "inference":
703
+ checks.check_requirements("streamlit>=1.29.0")
704
+ LOGGER.info("💡 Loading Ultralytics live inference app...")
705
+ subprocess.run(
706
+ [ # Run subprocess with Streamlit custom argument
707
+ "streamlit",
708
+ "run",
709
+ str(ROOT / "solutions/streamlit_inference.py"),
710
+ "--server.headless",
711
+ "true",
712
+ overrides.pop("model", "yolo11n.pt"),
713
+ ]
714
+ )
715
+ else:
716
+ import cv2 # Only needed for cap and vw functionality
717
+
718
+ from ultralytics import solutions
719
+
720
+ solution = getattr(solutions, SOLUTION_MAP[solution_name])(is_cli=True, **overrides) # class i.e. ObjectCounter
721
+
722
+ cap = cv2.VideoCapture(solution.CFG["source"]) # read the video file
723
+ if solution_name != "crop":
724
+ # extract width, height and fps of the video file, create save directory and initialize video writer
725
+ w, h, fps = (
726
+ int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)
727
+ )
728
+ if solution_name == "analytics": # analytical graphs follow fixed shape for output i.e w=1920, h=1080
729
+ w, h = 1280, 720
730
+ save_dir = get_save_dir(SimpleNamespace(task="solutions", name="exp", exist_ok=False, project=None))
731
+ save_dir.mkdir(parents=True, exist_ok=True) # create the output directory i.e. runs/solutions/exp
732
+ vw = cv2.VideoWriter(str(save_dir / f"{solution_name}.avi"), cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
733
+
734
+ try: # Process video frames
735
+ f_n = 0 # frame number, required for analytical graphs
736
+ while cap.isOpened():
737
+ success, frame = cap.read()
738
+ if not success:
739
+ break
740
+ results = solution(frame, f_n := f_n + 1) if solution_name == "analytics" else solution(frame)
741
+ if solution_name != "crop":
742
+ vw.write(results.plot_im)
743
+ if solution.CFG["show"] and cv2.waitKey(1) & 0xFF == ord("q"):
744
+ break
745
+ finally:
746
+ cap.release()
747
+
748
+
749
+ def parse_key_value_pair(pair: str = "key=value") -> tuple:
750
+ """Parse a key-value pair string into separate key and value components.
751
+
752
+ Args:
753
+ pair (str): A string containing a key-value pair in the format "key=value".
754
+
755
+ Returns:
756
+ key (str): The parsed key.
757
+ value (str): The parsed value.
758
+
759
+ Raises:
760
+ AssertionError: If the value is missing or empty.
761
+
762
+ Examples:
763
+ >>> key, value = parse_key_value_pair("model=yolo11n.pt")
764
+ >>> print(f"Key: {key}, Value: {value}")
765
+ Key: model, Value: yolo11n.pt
766
+
767
+ >>> key, value = parse_key_value_pair("epochs=100")
768
+ >>> print(f"Key: {key}, Value: {value}")
769
+ Key: epochs, Value: 100
770
+
771
+ Notes:
772
+ - The function splits the input string on the first '=' character.
773
+ - Leading and trailing whitespace is removed from both key and value.
774
+ - An assertion error is raised if the value is empty after stripping.
775
+ """
776
+ k, v = pair.split("=", 1) # split on first '=' sign
777
+ k, v = k.strip(), v.strip() # remove spaces
778
+ assert v, f"missing '{k}' value"
779
+ return k, smart_value(v)
780
+
781
+
782
+ def smart_value(v: str) -> Any:
783
+ """Convert a string representation of a value to its appropriate Python type.
784
+
785
+ This function attempts to convert a given string into a Python object of the most appropriate type. It handles
786
+ conversions to None, bool, int, float, and other types that can be evaluated safely.
787
+
788
+ Args:
789
+ v (str): The string representation of the value to be converted.
790
+
791
+ Returns:
792
+ (Any): The converted value. The type can be None, bool, int, float, or the original string if no conversion is
793
+ applicable.
794
+
795
+ Examples:
796
+ >>> smart_value("42")
797
+ 42
798
+ >>> smart_value("3.14")
799
+ 3.14
800
+ >>> smart_value("True")
801
+ True
802
+ >>> smart_value("None")
803
+ None
804
+ >>> smart_value("some_string")
805
+ 'some_string'
806
+
807
+ Notes:
808
+ - The function uses a case-insensitive comparison for boolean and None values.
809
+ - For other types, it attempts to use Python's ast.literal_eval() function for safe evaluation.
810
+ - If no conversion is possible, the original string is returned.
811
+ """
812
+ v_lower = v.lower()
813
+ if v_lower == "none":
814
+ return None
815
+ elif v_lower == "true":
816
+ return True
817
+ elif v_lower == "false":
818
+ return False
819
+ else:
820
+ try:
821
+ return ast.literal_eval(v)
822
+ except Exception:
823
+ return v
824
+
825
+
826
+ def entrypoint(debug: str = "") -> None:
827
+ """Ultralytics entrypoint function for parsing and executing command-line arguments.
828
+
829
+ This function serves as the main entry point for the Ultralytics CLI, parsing command-line arguments and executing
830
+ the corresponding tasks such as training, validation, prediction, exporting models, and more.
831
+
832
+ Args:
833
+ debug (str): Space-separated string of command-line arguments for debugging purposes.
834
+
835
+ Examples:
836
+ Train a detection model for 10 epochs with an initial learning_rate of 0.01:
837
+ >>> entrypoint("train data=coco8.yaml model=yolo11n.pt epochs=10 lr0=0.01")
838
+
839
+ Predict a YouTube video using a pretrained segmentation model at image size 320:
840
+ >>> entrypoint("predict model=yolo11n-seg.pt source='https://youtu.be/LNwODJXcvt4' imgsz=320")
841
+
842
+ Validate a pretrained detection model at batch-size 1 and image size 640:
843
+ >>> entrypoint("val model=yolo11n.pt data=coco8.yaml batch=1 imgsz=640")
844
+
845
+ Notes:
846
+ - If no arguments are passed, the function will display the usage help message.
847
+ - For a list of all available commands and their arguments, see the provided help messages and the
848
+ Ultralytics documentation at https://docs.ultralytics.com.
849
+ """
850
+ args = (debug.split(" ") if debug else ARGV)[1:]
851
+ if not args: # no arguments passed
852
+ LOGGER.info(CLI_HELP_MSG)
853
+ return
854
+
855
+ special = {
856
+ "checks": checks.collect_system_info,
857
+ "version": lambda: LOGGER.info(__version__),
858
+ "settings": lambda: handle_yolo_settings(args[1:]),
859
+ "cfg": lambda: YAML.print(DEFAULT_CFG_PATH),
860
+ "hub": lambda: handle_yolo_hub(args[1:]),
861
+ "login": lambda: handle_yolo_hub(args),
862
+ "logout": lambda: handle_yolo_hub(args),
863
+ "copy-cfg": copy_default_cfg,
864
+ "solutions": lambda: handle_yolo_solutions(args[1:]),
865
+ "help": lambda: LOGGER.info(CLI_HELP_MSG), # help below hub for -h flag precedence
866
+ }
867
+ full_args_dict = {**DEFAULT_CFG_DICT, **{k: None for k in TASKS}, **{k: None for k in MODES}, **special}
868
+
869
+ # Define common misuses of special commands, i.e. -h, -help, --help
870
+ special.update({k[0]: v for k, v in special.items()}) # singular
871
+ special.update({k[:-1]: v for k, v in special.items() if len(k) > 1 and k.endswith("s")}) # singular
872
+ special = {**special, **{f"-{k}": v for k, v in special.items()}, **{f"--{k}": v for k, v in special.items()}}
873
+
874
+ overrides = {} # basic overrides, i.e. imgsz=320
875
+ for a in merge_equals_args(args): # merge spaces around '=' sign
876
+ if a.startswith("--"):
877
+ LOGGER.warning(f"argument '{a}' does not require leading dashes '--', updating to '{a[2:]}'.")
878
+ a = a[2:]
879
+ if a.endswith(","):
880
+ LOGGER.warning(f"argument '{a}' does not require trailing comma ',', updating to '{a[:-1]}'.")
881
+ a = a[:-1]
882
+ if "=" in a:
883
+ try:
884
+ k, v = parse_key_value_pair(a)
885
+ if k == "cfg" and v is not None: # custom.yaml passed
886
+ LOGGER.info(f"Overriding {DEFAULT_CFG_PATH} with {v}")
887
+ overrides = {k: val for k, val in YAML.load(checks.check_yaml(v)).items() if k != "cfg"}
888
+ else:
889
+ overrides[k] = v
890
+ except (NameError, SyntaxError, ValueError, AssertionError) as e:
891
+ check_dict_alignment(full_args_dict, {a: ""}, e)
892
+
893
+ elif a in TASKS:
894
+ overrides["task"] = a
895
+ elif a in MODES:
896
+ overrides["mode"] = a
897
+ elif a.lower() in special:
898
+ special[a.lower()]()
899
+ return
900
+ elif a in DEFAULT_CFG_DICT and isinstance(DEFAULT_CFG_DICT[a], bool):
901
+ overrides[a] = True # auto-True for default bool args, i.e. 'yolo show' sets show=True
902
+ elif a in DEFAULT_CFG_DICT:
903
+ raise SyntaxError(
904
+ f"'{colorstr('red', 'bold', a)}' is a valid YOLO argument but is missing an '=' sign "
905
+ f"to set its value, i.e. try '{a}={DEFAULT_CFG_DICT[a]}'\n{CLI_HELP_MSG}"
906
+ )
907
+ else:
908
+ check_dict_alignment(full_args_dict, {a: ""})
909
+
910
+ # Check keys
911
+ check_dict_alignment(full_args_dict, overrides)
912
+
913
+ # Mode
914
+ mode = overrides.get("mode")
915
+ if mode is None:
916
+ mode = DEFAULT_CFG.mode or "predict"
917
+ LOGGER.warning(f"'mode' argument is missing. Valid modes are {list(MODES)}. Using default 'mode={mode}'.")
918
+ elif mode not in MODES:
919
+ raise ValueError(f"Invalid 'mode={mode}'. Valid modes are {list(MODES)}.\n{CLI_HELP_MSG}")
920
+
921
+ # Task
922
+ task = overrides.pop("task", None)
923
+ if task:
924
+ if task not in TASKS:
925
+ if task == "track":
926
+ LOGGER.warning(
927
+ f"invalid 'task=track', setting 'task=detect' and 'mode=track'. Valid tasks are {list(TASKS)}.\n{CLI_HELP_MSG}."
928
+ )
929
+ task, mode = "detect", "track"
930
+ else:
931
+ raise ValueError(f"Invalid 'task={task}'. Valid tasks are {list(TASKS)}.\n{CLI_HELP_MSG}")
932
+ if "model" not in overrides:
933
+ overrides["model"] = TASK2MODEL[task]
934
+
935
+ # Model
936
+ model = overrides.pop("model", DEFAULT_CFG.model)
937
+ if model is None:
938
+ model = "yolo11n.pt"
939
+ LOGGER.warning(f"'model' argument is missing. Using default 'model={model}'.")
940
+ overrides["model"] = model
941
+ stem = Path(model).stem.lower()
942
+ if "rtdetr" in stem: # guess architecture
943
+ from ultralytics import RTDETR
944
+
945
+ model = RTDETR(model) # no task argument
946
+ elif "fastsam" in stem:
947
+ from ultralytics import FastSAM
948
+
949
+ model = FastSAM(model)
950
+ elif "sam_" in stem or "sam2_" in stem or "sam2.1_" in stem:
951
+ from ultralytics import SAM
952
+
953
+ model = SAM(model)
954
+ else:
955
+ from ultralytics import YOLO
956
+
957
+ model = YOLO(model, task=task)
958
+ if "yoloe" in stem or "world" in stem:
959
+ cls_list = overrides.pop("classes", DEFAULT_CFG.classes)
960
+ if cls_list is not None and isinstance(cls_list, str):
961
+ model.set_classes(cls_list.split(",")) # convert "person, bus" -> ['person', ' bus'].
962
+ # Task Update
963
+ if task != model.task:
964
+ if task:
965
+ LOGGER.warning(
966
+ f"conflicting 'task={task}' passed with 'task={model.task}' model. "
967
+ f"Ignoring 'task={task}' and updating to 'task={model.task}' to match model."
968
+ )
969
+ task = model.task
970
+
971
+ # Mode
972
+ if mode in {"predict", "track"} and "source" not in overrides:
973
+ overrides["source"] = (
974
+ "https://ultralytics.com/images/boats.jpg" if task == "obb" else DEFAULT_CFG.source or ASSETS
975
+ )
976
+ LOGGER.warning(f"'source' argument is missing. Using default 'source={overrides['source']}'.")
977
+ elif mode in {"train", "val"}:
978
+ if "data" not in overrides and "resume" not in overrides:
979
+ overrides["data"] = DEFAULT_CFG.data or TASK2DATA.get(task or DEFAULT_CFG.task, DEFAULT_CFG.data)
980
+ LOGGER.warning(f"'data' argument is missing. Using default 'data={overrides['data']}'.")
981
+ elif mode == "export":
982
+ if "format" not in overrides:
983
+ overrides["format"] = DEFAULT_CFG.format or "torchscript"
984
+ LOGGER.warning(f"'format' argument is missing. Using default 'format={overrides['format']}'.")
985
+
986
+ # Run command in python
987
+ getattr(model, mode)(**overrides) # default args from model
988
+
989
+ # Show help
990
+ LOGGER.info(f"💡 Learn more at https://docs.ultralytics.com/modes/{mode}")
991
+
992
+ # Recommend VS Code extension
993
+ if IS_VSCODE and SETTINGS.get("vscode_msg", True):
994
+ LOGGER.info(vscode_msg())
995
+
996
+
997
+ # Special modes --------------------------------------------------------------------------------------------------------
998
+ def copy_default_cfg() -> None:
999
+ """Copy the default configuration file and create a new one with '_copy' appended to its name.
1000
+
1001
+ This function duplicates the existing default configuration file (DEFAULT_CFG_PATH) and saves it with '_copy'
1002
+ appended to its name in the current working directory. It provides a convenient way to create a custom configuration
1003
+ file based on the default settings.
1004
+
1005
+ Examples:
1006
+ >>> copy_default_cfg()
1007
+ # Output: default.yaml copied to /path/to/current/directory/default_copy.yaml
1008
+ # Example YOLO command with this new custom cfg:
1009
+ # yolo cfg='/path/to/current/directory/default_copy.yaml' imgsz=320 batch=8
1010
+
1011
+ Notes:
1012
+ - The new configuration file is created in the current working directory.
1013
+ - After copying, the function prints a message with the new file's location and an example
1014
+ YOLO command demonstrating how to use the new configuration file.
1015
+ - This function is useful for users who want to modify the default configuration without
1016
+ altering the original file.
1017
+ """
1018
+ new_file = Path.cwd() / DEFAULT_CFG_PATH.name.replace(".yaml", "_copy.yaml")
1019
+ shutil.copy2(DEFAULT_CFG_PATH, new_file)
1020
+ LOGGER.info(
1021
+ f"{DEFAULT_CFG_PATH} copied to {new_file}\n"
1022
+ f"Example YOLO command with this new custom cfg:\n yolo cfg='{new_file}' imgsz=320 batch=8"
1023
+ )
1024
+
1025
+
1026
+ if __name__ == "__main__":
1027
+ # Example: entrypoint(debug='yolo predict model=yolo11n.pt')
1028
+ entrypoint(debug="")