dgenerate-ultralytics-headless 8.3.196__py3-none-any.whl → 8.3.248__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 (243) hide show
  1. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/METADATA +33 -34
  2. dgenerate_ultralytics_headless-8.3.248.dist-info/RECORD +298 -0
  3. tests/__init__.py +5 -7
  4. tests/conftest.py +8 -15
  5. tests/test_cli.py +8 -10
  6. tests/test_cuda.py +9 -10
  7. tests/test_engine.py +29 -2
  8. tests/test_exports.py +69 -21
  9. tests/test_integrations.py +8 -11
  10. tests/test_python.py +109 -71
  11. tests/test_solutions.py +170 -159
  12. ultralytics/__init__.py +27 -9
  13. ultralytics/cfg/__init__.py +57 -64
  14. ultralytics/cfg/datasets/Argoverse.yaml +7 -6
  15. ultralytics/cfg/datasets/DOTAv1.5.yaml +1 -1
  16. ultralytics/cfg/datasets/DOTAv1.yaml +1 -1
  17. ultralytics/cfg/datasets/ImageNet.yaml +1 -1
  18. ultralytics/cfg/datasets/Objects365.yaml +19 -15
  19. ultralytics/cfg/datasets/SKU-110K.yaml +1 -1
  20. ultralytics/cfg/datasets/VOC.yaml +19 -21
  21. ultralytics/cfg/datasets/VisDrone.yaml +5 -5
  22. ultralytics/cfg/datasets/african-wildlife.yaml +1 -1
  23. ultralytics/cfg/datasets/coco-pose.yaml +24 -2
  24. ultralytics/cfg/datasets/coco.yaml +2 -2
  25. ultralytics/cfg/datasets/coco128-seg.yaml +1 -1
  26. ultralytics/cfg/datasets/coco8-pose.yaml +21 -0
  27. ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
  28. ultralytics/cfg/datasets/dog-pose.yaml +28 -0
  29. ultralytics/cfg/datasets/dota8-multispectral.yaml +1 -1
  30. ultralytics/cfg/datasets/dota8.yaml +2 -2
  31. ultralytics/cfg/datasets/hand-keypoints.yaml +26 -2
  32. ultralytics/cfg/datasets/kitti.yaml +27 -0
  33. ultralytics/cfg/datasets/lvis.yaml +7 -7
  34. ultralytics/cfg/datasets/open-images-v7.yaml +1 -1
  35. ultralytics/cfg/datasets/tiger-pose.yaml +16 -0
  36. ultralytics/cfg/datasets/xView.yaml +16 -16
  37. ultralytics/cfg/default.yaml +96 -94
  38. ultralytics/cfg/models/11/yolo11-pose.yaml +1 -1
  39. ultralytics/cfg/models/11/yoloe-11-seg.yaml +2 -2
  40. ultralytics/cfg/models/11/yoloe-11.yaml +2 -2
  41. ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +1 -1
  42. ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +1 -1
  43. ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +1 -1
  44. ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +1 -1
  45. ultralytics/cfg/models/v10/yolov10b.yaml +2 -2
  46. ultralytics/cfg/models/v10/yolov10l.yaml +2 -2
  47. ultralytics/cfg/models/v10/yolov10m.yaml +2 -2
  48. ultralytics/cfg/models/v10/yolov10n.yaml +2 -2
  49. ultralytics/cfg/models/v10/yolov10s.yaml +2 -2
  50. ultralytics/cfg/models/v10/yolov10x.yaml +2 -2
  51. ultralytics/cfg/models/v3/yolov3-tiny.yaml +1 -1
  52. ultralytics/cfg/models/v6/yolov6.yaml +1 -1
  53. ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +9 -6
  54. ultralytics/cfg/models/v8/yoloe-v8.yaml +9 -6
  55. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +1 -1
  56. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +1 -1
  57. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +2 -2
  58. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +2 -2
  59. ultralytics/cfg/models/v8/yolov8-ghost.yaml +2 -2
  60. ultralytics/cfg/models/v8/yolov8-obb.yaml +1 -1
  61. ultralytics/cfg/models/v8/yolov8-p2.yaml +1 -1
  62. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +1 -1
  63. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +1 -1
  64. ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +1 -1
  65. ultralytics/cfg/models/v8/yolov8-world.yaml +1 -1
  66. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +6 -6
  67. ultralytics/cfg/models/v9/yolov9s.yaml +1 -1
  68. ultralytics/cfg/trackers/botsort.yaml +16 -17
  69. ultralytics/cfg/trackers/bytetrack.yaml +9 -11
  70. ultralytics/data/__init__.py +4 -4
  71. ultralytics/data/annotator.py +3 -4
  72. ultralytics/data/augment.py +286 -476
  73. ultralytics/data/base.py +18 -26
  74. ultralytics/data/build.py +151 -26
  75. ultralytics/data/converter.py +38 -50
  76. ultralytics/data/dataset.py +47 -75
  77. ultralytics/data/loaders.py +42 -49
  78. ultralytics/data/split.py +5 -6
  79. ultralytics/data/split_dota.py +8 -15
  80. ultralytics/data/utils.py +41 -45
  81. ultralytics/engine/exporter.py +462 -462
  82. ultralytics/engine/model.py +150 -191
  83. ultralytics/engine/predictor.py +30 -40
  84. ultralytics/engine/results.py +177 -311
  85. ultralytics/engine/trainer.py +193 -120
  86. ultralytics/engine/tuner.py +77 -63
  87. ultralytics/engine/validator.py +39 -22
  88. ultralytics/hub/__init__.py +16 -19
  89. ultralytics/hub/auth.py +6 -12
  90. ultralytics/hub/google/__init__.py +7 -10
  91. ultralytics/hub/session.py +15 -25
  92. ultralytics/hub/utils.py +5 -8
  93. ultralytics/models/__init__.py +1 -1
  94. ultralytics/models/fastsam/__init__.py +1 -1
  95. ultralytics/models/fastsam/model.py +8 -10
  96. ultralytics/models/fastsam/predict.py +19 -30
  97. ultralytics/models/fastsam/utils.py +1 -2
  98. ultralytics/models/fastsam/val.py +5 -7
  99. ultralytics/models/nas/__init__.py +1 -1
  100. ultralytics/models/nas/model.py +5 -8
  101. ultralytics/models/nas/predict.py +7 -9
  102. ultralytics/models/nas/val.py +1 -2
  103. ultralytics/models/rtdetr/__init__.py +1 -1
  104. ultralytics/models/rtdetr/model.py +7 -8
  105. ultralytics/models/rtdetr/predict.py +15 -19
  106. ultralytics/models/rtdetr/train.py +10 -13
  107. ultralytics/models/rtdetr/val.py +21 -23
  108. ultralytics/models/sam/__init__.py +15 -2
  109. ultralytics/models/sam/amg.py +14 -20
  110. ultralytics/models/sam/build.py +26 -19
  111. ultralytics/models/sam/build_sam3.py +377 -0
  112. ultralytics/models/sam/model.py +29 -32
  113. ultralytics/models/sam/modules/blocks.py +83 -144
  114. ultralytics/models/sam/modules/decoders.py +22 -40
  115. ultralytics/models/sam/modules/encoders.py +44 -101
  116. ultralytics/models/sam/modules/memory_attention.py +16 -30
  117. ultralytics/models/sam/modules/sam.py +206 -79
  118. ultralytics/models/sam/modules/tiny_encoder.py +64 -83
  119. ultralytics/models/sam/modules/transformer.py +18 -28
  120. ultralytics/models/sam/modules/utils.py +174 -50
  121. ultralytics/models/sam/predict.py +2268 -366
  122. ultralytics/models/sam/sam3/__init__.py +3 -0
  123. ultralytics/models/sam/sam3/decoder.py +546 -0
  124. ultralytics/models/sam/sam3/encoder.py +529 -0
  125. ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
  126. ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
  127. ultralytics/models/sam/sam3/model_misc.py +199 -0
  128. ultralytics/models/sam/sam3/necks.py +129 -0
  129. ultralytics/models/sam/sam3/sam3_image.py +339 -0
  130. ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
  131. ultralytics/models/sam/sam3/vitdet.py +547 -0
  132. ultralytics/models/sam/sam3/vl_combiner.py +160 -0
  133. ultralytics/models/utils/loss.py +14 -26
  134. ultralytics/models/utils/ops.py +13 -17
  135. ultralytics/models/yolo/__init__.py +1 -1
  136. ultralytics/models/yolo/classify/predict.py +9 -12
  137. ultralytics/models/yolo/classify/train.py +15 -41
  138. ultralytics/models/yolo/classify/val.py +34 -32
  139. ultralytics/models/yolo/detect/predict.py +8 -11
  140. ultralytics/models/yolo/detect/train.py +13 -32
  141. ultralytics/models/yolo/detect/val.py +75 -63
  142. ultralytics/models/yolo/model.py +37 -53
  143. ultralytics/models/yolo/obb/predict.py +5 -14
  144. ultralytics/models/yolo/obb/train.py +11 -14
  145. ultralytics/models/yolo/obb/val.py +42 -39
  146. ultralytics/models/yolo/pose/__init__.py +1 -1
  147. ultralytics/models/yolo/pose/predict.py +7 -22
  148. ultralytics/models/yolo/pose/train.py +10 -22
  149. ultralytics/models/yolo/pose/val.py +40 -59
  150. ultralytics/models/yolo/segment/predict.py +16 -20
  151. ultralytics/models/yolo/segment/train.py +3 -12
  152. ultralytics/models/yolo/segment/val.py +106 -56
  153. ultralytics/models/yolo/world/train.py +12 -16
  154. ultralytics/models/yolo/world/train_world.py +11 -34
  155. ultralytics/models/yolo/yoloe/__init__.py +7 -7
  156. ultralytics/models/yolo/yoloe/predict.py +16 -23
  157. ultralytics/models/yolo/yoloe/train.py +31 -56
  158. ultralytics/models/yolo/yoloe/train_seg.py +5 -10
  159. ultralytics/models/yolo/yoloe/val.py +16 -21
  160. ultralytics/nn/__init__.py +7 -7
  161. ultralytics/nn/autobackend.py +152 -80
  162. ultralytics/nn/modules/__init__.py +60 -60
  163. ultralytics/nn/modules/activation.py +4 -6
  164. ultralytics/nn/modules/block.py +133 -217
  165. ultralytics/nn/modules/conv.py +52 -97
  166. ultralytics/nn/modules/head.py +64 -116
  167. ultralytics/nn/modules/transformer.py +79 -89
  168. ultralytics/nn/modules/utils.py +16 -21
  169. ultralytics/nn/tasks.py +111 -156
  170. ultralytics/nn/text_model.py +40 -67
  171. ultralytics/solutions/__init__.py +12 -12
  172. ultralytics/solutions/ai_gym.py +11 -17
  173. ultralytics/solutions/analytics.py +15 -16
  174. ultralytics/solutions/config.py +5 -6
  175. ultralytics/solutions/distance_calculation.py +10 -13
  176. ultralytics/solutions/heatmap.py +7 -13
  177. ultralytics/solutions/instance_segmentation.py +5 -8
  178. ultralytics/solutions/object_blurrer.py +7 -10
  179. ultralytics/solutions/object_counter.py +12 -19
  180. ultralytics/solutions/object_cropper.py +8 -14
  181. ultralytics/solutions/parking_management.py +33 -31
  182. ultralytics/solutions/queue_management.py +10 -12
  183. ultralytics/solutions/region_counter.py +9 -12
  184. ultralytics/solutions/security_alarm.py +15 -20
  185. ultralytics/solutions/similarity_search.py +13 -17
  186. ultralytics/solutions/solutions.py +75 -74
  187. ultralytics/solutions/speed_estimation.py +7 -10
  188. ultralytics/solutions/streamlit_inference.py +4 -7
  189. ultralytics/solutions/templates/similarity-search.html +7 -18
  190. ultralytics/solutions/trackzone.py +7 -10
  191. ultralytics/solutions/vision_eye.py +5 -8
  192. ultralytics/trackers/__init__.py +1 -1
  193. ultralytics/trackers/basetrack.py +3 -5
  194. ultralytics/trackers/bot_sort.py +10 -27
  195. ultralytics/trackers/byte_tracker.py +14 -30
  196. ultralytics/trackers/track.py +3 -6
  197. ultralytics/trackers/utils/gmc.py +11 -22
  198. ultralytics/trackers/utils/kalman_filter.py +37 -48
  199. ultralytics/trackers/utils/matching.py +12 -15
  200. ultralytics/utils/__init__.py +116 -116
  201. ultralytics/utils/autobatch.py +2 -4
  202. ultralytics/utils/autodevice.py +17 -18
  203. ultralytics/utils/benchmarks.py +70 -70
  204. ultralytics/utils/callbacks/base.py +8 -10
  205. ultralytics/utils/callbacks/clearml.py +5 -13
  206. ultralytics/utils/callbacks/comet.py +32 -46
  207. ultralytics/utils/callbacks/dvc.py +13 -18
  208. ultralytics/utils/callbacks/mlflow.py +4 -5
  209. ultralytics/utils/callbacks/neptune.py +7 -15
  210. ultralytics/utils/callbacks/platform.py +314 -38
  211. ultralytics/utils/callbacks/raytune.py +3 -4
  212. ultralytics/utils/callbacks/tensorboard.py +23 -31
  213. ultralytics/utils/callbacks/wb.py +10 -13
  214. ultralytics/utils/checks.py +151 -87
  215. ultralytics/utils/cpu.py +3 -8
  216. ultralytics/utils/dist.py +19 -15
  217. ultralytics/utils/downloads.py +29 -41
  218. ultralytics/utils/errors.py +6 -14
  219. ultralytics/utils/events.py +2 -4
  220. ultralytics/utils/export/__init__.py +7 -0
  221. ultralytics/utils/{export.py → export/engine.py} +16 -16
  222. ultralytics/utils/export/imx.py +325 -0
  223. ultralytics/utils/export/tensorflow.py +231 -0
  224. ultralytics/utils/files.py +24 -28
  225. ultralytics/utils/git.py +9 -11
  226. ultralytics/utils/instance.py +30 -51
  227. ultralytics/utils/logger.py +212 -114
  228. ultralytics/utils/loss.py +15 -24
  229. ultralytics/utils/metrics.py +131 -160
  230. ultralytics/utils/nms.py +21 -30
  231. ultralytics/utils/ops.py +107 -165
  232. ultralytics/utils/patches.py +33 -21
  233. ultralytics/utils/plotting.py +122 -119
  234. ultralytics/utils/tal.py +28 -44
  235. ultralytics/utils/torch_utils.py +70 -187
  236. ultralytics/utils/tqdm.py +20 -20
  237. ultralytics/utils/triton.py +13 -19
  238. ultralytics/utils/tuner.py +17 -5
  239. dgenerate_ultralytics_headless-8.3.196.dist-info/RECORD +0 -281
  240. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/WHEEL +0 -0
  241. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/entry_points.txt +0 -0
  242. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/licenses/LICENSE +0 -0
  243. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/top_level.txt +0 -0
tests/test_solutions.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
3
  # Tests Ultralytics Solutions: https://docs.ultralytics.com/solutions/,
4
- # including every solution excluding DistanceCalculation and Security Alarm System.
4
+ # Includes all solutions except DistanceCalculation and the Security Alarm System.
5
5
 
6
6
  import os
7
7
  from unittest.mock import patch
@@ -10,12 +10,13 @@ import cv2
10
10
  import numpy as np
11
11
  import pytest
12
12
 
13
- from tests import MODEL, TMP
13
+ from tests import MODEL
14
14
  from ultralytics import solutions
15
- from ultralytics.utils import ASSETS_URL, IS_RASPBERRYPI, checks
15
+ from ultralytics.utils import ASSETS_URL, IS_RASPBERRYPI, TORCH_VERSION, checks
16
16
  from ultralytics.utils.downloads import safe_download
17
+ from ultralytics.utils.torch_utils import TORCH_2_4
17
18
 
18
- # Pre-defined arguments values
19
+ # Predefined argument values
19
20
  SHOW = False
20
21
  DEMO_VIDEO = "solutions_ci_demo.mp4" # for all the solutions, except workout, object cropping and parking management
21
22
  CROP_VIDEO = "decelera_landscape_min.mov" # for object cropping solution
@@ -28,139 +29,6 @@ REGION = [(10, 200), (540, 200), (540, 180), (10, 180)] # for object counting,
28
29
  HORIZONTAL_LINE = [(10, 200), (540, 200)] # for object counting
29
30
  VERTICAL_LINE = [(320, 0), (320, 400)] # for object counting
30
31
 
31
- # Test configs for each solution : (name, class, needs_frame_count, video, kwargs)
32
- SOLUTIONS = [
33
- (
34
- "ObjectCounter",
35
- solutions.ObjectCounter,
36
- False,
37
- DEMO_VIDEO,
38
- {"region": REGION, "model": MODEL, "show": SHOW},
39
- ),
40
- (
41
- "ObjectCounter",
42
- solutions.ObjectCounter,
43
- False,
44
- DEMO_VIDEO,
45
- {"region": HORIZONTAL_LINE, "model": MODEL, "show": SHOW},
46
- ),
47
- (
48
- "ObjectCounterVertical",
49
- solutions.ObjectCounter,
50
- False,
51
- DEMO_VIDEO,
52
- {"region": VERTICAL_LINE, "model": MODEL, "show": SHOW},
53
- ),
54
- (
55
- "ObjectCounterwithOBB",
56
- solutions.ObjectCounter,
57
- False,
58
- DEMO_VIDEO,
59
- {"region": REGION, "model": "yolo11n-obb.pt", "show": SHOW},
60
- ),
61
- (
62
- "Heatmap",
63
- solutions.Heatmap,
64
- False,
65
- DEMO_VIDEO,
66
- {"colormap": cv2.COLORMAP_PARULA, "model": MODEL, "show": SHOW, "region": None},
67
- ),
68
- (
69
- "HeatmapWithRegion",
70
- solutions.Heatmap,
71
- False,
72
- DEMO_VIDEO,
73
- {"colormap": cv2.COLORMAP_PARULA, "region": REGION, "model": MODEL, "show": SHOW},
74
- ),
75
- (
76
- "SpeedEstimator",
77
- solutions.SpeedEstimator,
78
- False,
79
- DEMO_VIDEO,
80
- {"region": REGION, "model": MODEL, "show": SHOW},
81
- ),
82
- (
83
- "QueueManager",
84
- solutions.QueueManager,
85
- False,
86
- DEMO_VIDEO,
87
- {"region": REGION, "model": MODEL, "show": SHOW},
88
- ),
89
- (
90
- "LineAnalytics",
91
- solutions.Analytics,
92
- True,
93
- DEMO_VIDEO,
94
- {"analytics_type": "line", "model": MODEL, "show": SHOW, "figsize": (6.4, 3.2)},
95
- ),
96
- (
97
- "PieAnalytics",
98
- solutions.Analytics,
99
- True,
100
- DEMO_VIDEO,
101
- {"analytics_type": "pie", "model": MODEL, "show": SHOW, "figsize": (6.4, 3.2)},
102
- ),
103
- (
104
- "BarAnalytics",
105
- solutions.Analytics,
106
- True,
107
- DEMO_VIDEO,
108
- {"analytics_type": "bar", "model": MODEL, "show": SHOW, "figsize": (6.4, 3.2)},
109
- ),
110
- (
111
- "AreaAnalytics",
112
- solutions.Analytics,
113
- True,
114
- DEMO_VIDEO,
115
- {"analytics_type": "area", "model": MODEL, "show": SHOW, "figsize": (6.4, 3.2)},
116
- ),
117
- ("TrackZone", solutions.TrackZone, False, DEMO_VIDEO, {"region": REGION, "model": MODEL, "show": SHOW}),
118
- (
119
- "ObjectCropper",
120
- solutions.ObjectCropper,
121
- False,
122
- CROP_VIDEO,
123
- {"crop_dir": str(TMP / "cropped-detections"), "model": MODEL, "show": SHOW},
124
- ),
125
- (
126
- "ObjectBlurrer",
127
- solutions.ObjectBlurrer,
128
- False,
129
- DEMO_VIDEO,
130
- {"blur_ratio": 0.02, "model": MODEL, "show": SHOW},
131
- ),
132
- (
133
- "InstanceSegmentation",
134
- solutions.InstanceSegmentation,
135
- False,
136
- DEMO_VIDEO,
137
- {"model": "yolo11n-seg.pt", "show": SHOW},
138
- ),
139
- ("VisionEye", solutions.VisionEye, False, DEMO_VIDEO, {"model": MODEL, "show": SHOW}),
140
- (
141
- "RegionCounter",
142
- solutions.RegionCounter,
143
- False,
144
- DEMO_VIDEO,
145
- {"region": REGION, "model": MODEL, "show": SHOW},
146
- ),
147
- ("AIGym", solutions.AIGym, False, POSE_VIDEO, {"kpts": [6, 8, 10], "show": SHOW}),
148
- (
149
- "ParkingManager",
150
- solutions.ParkingManagement,
151
- False,
152
- PARKING_VIDEO,
153
- {"model": str(TMP / PARKING_MODEL), "show": SHOW, "json_file": str(TMP / PARKING_AREAS_JSON)},
154
- ),
155
- (
156
- "StreamlitInference",
157
- solutions.Inference,
158
- False,
159
- None, # streamlit application doesn't require video file
160
- {}, # streamlit application doesn't accept arguments
161
- ),
162
- ]
163
-
164
32
 
165
33
  def process_video(solution, video_path: str, needs_frame_count: bool = False):
166
34
  """Process video with solution, feeding frames and optional frame count to the solution instance."""
@@ -181,39 +49,172 @@ def process_video(solution, video_path: str, needs_frame_count: bool = False):
181
49
 
182
50
 
183
51
  @pytest.mark.skipif(IS_RASPBERRYPI, reason="Disabled for testing due to --slow test errors after YOLOE PR.")
184
- @pytest.mark.parametrize("name, solution_class, needs_frame_count, video, kwargs", SOLUTIONS)
185
- def test_solution(name, solution_class, needs_frame_count, video, kwargs):
52
+ @pytest.mark.parametrize(
53
+ "name, solution_class, needs_frame_count, video, kwargs",
54
+ [
55
+ (
56
+ "ObjectCounter",
57
+ solutions.ObjectCounter,
58
+ False,
59
+ DEMO_VIDEO,
60
+ {"region": REGION, "model": MODEL, "show": SHOW},
61
+ ),
62
+ (
63
+ "ObjectCounter",
64
+ solutions.ObjectCounter,
65
+ False,
66
+ DEMO_VIDEO,
67
+ {"region": HORIZONTAL_LINE, "model": MODEL, "show": SHOW},
68
+ ),
69
+ (
70
+ "ObjectCounterVertical",
71
+ solutions.ObjectCounter,
72
+ False,
73
+ DEMO_VIDEO,
74
+ {"region": VERTICAL_LINE, "model": MODEL, "show": SHOW},
75
+ ),
76
+ (
77
+ "ObjectCounterwithOBB",
78
+ solutions.ObjectCounter,
79
+ False,
80
+ DEMO_VIDEO,
81
+ {"region": REGION, "model": "yolo11n-obb.pt", "show": SHOW},
82
+ ),
83
+ (
84
+ "Heatmap",
85
+ solutions.Heatmap,
86
+ False,
87
+ DEMO_VIDEO,
88
+ {"colormap": cv2.COLORMAP_PARULA, "model": MODEL, "show": SHOW, "region": None},
89
+ ),
90
+ (
91
+ "HeatmapWithRegion",
92
+ solutions.Heatmap,
93
+ False,
94
+ DEMO_VIDEO,
95
+ {"colormap": cv2.COLORMAP_PARULA, "region": REGION, "model": MODEL, "show": SHOW},
96
+ ),
97
+ (
98
+ "SpeedEstimator",
99
+ solutions.SpeedEstimator,
100
+ False,
101
+ DEMO_VIDEO,
102
+ {"region": REGION, "model": MODEL, "show": SHOW},
103
+ ),
104
+ (
105
+ "QueueManager",
106
+ solutions.QueueManager,
107
+ False,
108
+ DEMO_VIDEO,
109
+ {"region": REGION, "model": MODEL, "show": SHOW},
110
+ ),
111
+ (
112
+ "LineAnalytics",
113
+ solutions.Analytics,
114
+ True,
115
+ DEMO_VIDEO,
116
+ {"analytics_type": "line", "model": MODEL, "show": SHOW, "figsize": (6.4, 3.2)},
117
+ ),
118
+ (
119
+ "PieAnalytics",
120
+ solutions.Analytics,
121
+ True,
122
+ DEMO_VIDEO,
123
+ {"analytics_type": "pie", "model": MODEL, "show": SHOW, "figsize": (6.4, 3.2)},
124
+ ),
125
+ (
126
+ "BarAnalytics",
127
+ solutions.Analytics,
128
+ True,
129
+ DEMO_VIDEO,
130
+ {"analytics_type": "bar", "model": MODEL, "show": SHOW, "figsize": (6.4, 3.2)},
131
+ ),
132
+ (
133
+ "AreaAnalytics",
134
+ solutions.Analytics,
135
+ True,
136
+ DEMO_VIDEO,
137
+ {"analytics_type": "area", "model": MODEL, "show": SHOW, "figsize": (6.4, 3.2)},
138
+ ),
139
+ ("TrackZone", solutions.TrackZone, False, DEMO_VIDEO, {"region": REGION, "model": MODEL, "show": SHOW}),
140
+ (
141
+ "ObjectCropper",
142
+ solutions.ObjectCropper,
143
+ False,
144
+ CROP_VIDEO,
145
+ {"temp_crop_dir": "cropped-detections", "model": MODEL, "show": SHOW},
146
+ ),
147
+ (
148
+ "ObjectBlurrer",
149
+ solutions.ObjectBlurrer,
150
+ False,
151
+ DEMO_VIDEO,
152
+ {"blur_ratio": 0.02, "model": MODEL, "show": SHOW},
153
+ ),
154
+ (
155
+ "InstanceSegmentation",
156
+ solutions.InstanceSegmentation,
157
+ False,
158
+ DEMO_VIDEO,
159
+ {"model": "yolo11n-seg.pt", "show": SHOW},
160
+ ),
161
+ ("VisionEye", solutions.VisionEye, False, DEMO_VIDEO, {"model": MODEL, "show": SHOW}),
162
+ (
163
+ "RegionCounter",
164
+ solutions.RegionCounter,
165
+ False,
166
+ DEMO_VIDEO,
167
+ {"region": REGION, "model": MODEL, "show": SHOW},
168
+ ),
169
+ ("AIGym", solutions.AIGym, False, POSE_VIDEO, {"kpts": [6, 8, 10], "show": SHOW}),
170
+ (
171
+ "ParkingManager",
172
+ solutions.ParkingManagement,
173
+ False,
174
+ PARKING_VIDEO,
175
+ {"temp_model": str(PARKING_MODEL), "show": SHOW, "temp_json_file": str(PARKING_AREAS_JSON)},
176
+ ),
177
+ (
178
+ "StreamlitInference",
179
+ solutions.Inference,
180
+ False,
181
+ None, # streamlit application doesn't require video file
182
+ {}, # streamlit application doesn't accept arguments
183
+ ),
184
+ ],
185
+ )
186
+ def test_solution(name, solution_class, needs_frame_count, video, kwargs, tmp_path):
186
187
  """Test individual Ultralytics solution with video processing and parameter validation."""
187
188
  if video:
188
189
  if name != "ObjectCounterVertical":
189
- safe_download(url=f"{ASSETS_URL}/{video}", dir=TMP)
190
+ safe_download(url=f"{ASSETS_URL}/{video}", dir=tmp_path)
190
191
  else:
191
- safe_download(url=f"{ASSETS_URL}/{VERTICAL_VIDEO}", dir=TMP)
192
+ safe_download(url=f"{ASSETS_URL}/{VERTICAL_VIDEO}", dir=tmp_path)
192
193
  if name == "ParkingManager":
193
- safe_download(url=f"{ASSETS_URL}/{PARKING_AREAS_JSON}", dir=TMP)
194
- safe_download(url=f"{ASSETS_URL}/{PARKING_MODEL}", dir=TMP)
194
+ safe_download(url=f"{ASSETS_URL}/{PARKING_AREAS_JSON}", dir=tmp_path)
195
+ safe_download(url=f"{ASSETS_URL}/{PARKING_MODEL}", dir=tmp_path)
196
+
195
197
  elif name == "StreamlitInference":
196
198
  if checks.check_imshow(): # do not merge with elif above
197
199
  solution_class(**kwargs).inference() # requires interactive GUI environment
198
200
  return
199
201
 
202
+ # Update kwargs to use tmp_path
203
+ kwargs_updated = {}
204
+ for key in kwargs:
205
+ if key.startswith("temp_"):
206
+ kwargs_updated[key.replace("temp_", "")] = str(tmp_path / kwargs[key])
207
+ else:
208
+ kwargs_updated[key] = kwargs[key]
209
+
200
210
  video = VERTICAL_VIDEO if name == "ObjectCounterVertical" else video
201
211
  process_video(
202
- solution=solution_class(**kwargs),
203
- video_path=str(TMP / video),
212
+ solution=solution_class(**kwargs_updated),
213
+ video_path=str(tmp_path / video),
204
214
  needs_frame_count=needs_frame_count,
205
215
  )
206
216
 
207
217
 
208
- @pytest.mark.skipif(checks.IS_PYTHON_3_8, reason="Disabled due to unsupported CLIP dependencies.")
209
- @pytest.mark.skipif(IS_RASPBERRYPI, reason="Disabled due to slow performance on Raspberry Pi.")
210
- def test_similarity_search():
211
- """Test similarity search solution with sample images and text query."""
212
- safe_download(f"{ASSETS_URL}/4-imgs-similaritysearch.zip", dir=TMP) # 4 dog images for testing in a zip file
213
- searcher = solutions.VisualAISearch(data=str(TMP / "4-imgs-similaritysearch"))
214
- _ = searcher("a dog sitting on a bench") # Returns the results in format "- img name | similarity score"
215
-
216
-
217
218
  def test_left_click_selection():
218
219
  """Test distance calculation left click selection functionality."""
219
220
  dc = solutions.DistanceCalculation()
@@ -242,13 +243,13 @@ def test_parking_json_none():
242
243
 
243
244
 
244
245
  def test_analytics_graph_not_supported():
245
- """Test that unsupported analytics type raises ModuleNotFoundError."""
246
+ """Test that unsupported analytics type raises ValueError."""
246
247
  try:
247
248
  analytics = solutions.Analytics(analytics_type="test") # 'test' is unsupported
248
249
  analytics.process(im0=np.zeros((640, 480, 3), dtype=np.uint8), frame_number=0)
249
- assert False, "Expected ModuleNotFoundError for unsupported chart type"
250
- except ModuleNotFoundError as e:
251
- assert "test chart is not supported" in str(e)
250
+ assert False, "Expected ValueError for unsupported chart type"
251
+ except ValueError as e:
252
+ assert "Unsupported analytics_type" in str(e)
252
253
 
253
254
 
254
255
  def test_area_chart_padding():
@@ -297,7 +298,16 @@ def test_streamlit_handle_video_upload_creates_file():
297
298
  os.remove("ultralytics.mp4")
298
299
 
299
300
 
300
- @pytest.mark.skipif(checks.IS_PYTHON_3_8, reason="Disabled due to unsupported CLIP dependencies.")
301
+ @pytest.mark.skipif(not TORCH_2_4, reason=f"VisualAISearch requires torch>=2.4 (found torch=={TORCH_VERSION})")
302
+ @pytest.mark.skipif(IS_RASPBERRYPI, reason="Disabled due to slow performance on Raspberry Pi.")
303
+ def test_similarity_search(tmp_path):
304
+ """Test similarity search solution with sample images and text query."""
305
+ safe_download(f"{ASSETS_URL}/4-imgs-similaritysearch.zip", dir=tmp_path) # 4 dog images for testing in a zip file
306
+ searcher = solutions.VisualAISearch(data=str(tmp_path / "4-imgs-similaritysearch"))
307
+ _ = searcher("a dog sitting on a bench") # Returns the results in format "- img name | similarity score"
308
+
309
+
310
+ @pytest.mark.skipif(not TORCH_2_4, reason=f"VisualAISearch requires torch>=2.4 (found torch=={TORCH_VERSION})")
301
311
  @pytest.mark.skipif(IS_RASPBERRYPI, reason="Disabled due to slow performance on Raspberry Pi.")
302
312
  def test_similarity_search_app_init():
303
313
  """Test SearchApp initializes with required attributes."""
@@ -306,6 +316,7 @@ def test_similarity_search_app_init():
306
316
  assert hasattr(app, "run")
307
317
 
308
318
 
319
+ @pytest.mark.skipif(not TORCH_2_4, reason=f"VisualAISearch requires torch>=2.4 (found torch=={TORCH_VERSION})")
309
320
  @pytest.mark.skipif(IS_RASPBERRYPI, reason="Disabled due to slow performance on Raspberry Pi.")
310
321
  def test_similarity_search_complete(tmp_path):
311
322
  """Test VisualAISearch end-to-end with sample image and query."""
ultralytics/__init__.py CHANGED
@@ -1,30 +1,48 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- __version__ = "8.3.196"
3
+ __version__ = "8.3.248"
4
4
 
5
+ import importlib
5
6
  import os
7
+ from typing import TYPE_CHECKING
6
8
 
7
9
  # Set ENV variables (place before imports)
8
10
  if not os.environ.get("OMP_NUM_THREADS"):
9
11
  os.environ["OMP_NUM_THREADS"] = "1" # default for reduced CPU utilization during training
10
12
 
11
- from ultralytics.models import NAS, RTDETR, SAM, YOLO, YOLOE, FastSAM, YOLOWorld
12
13
  from ultralytics.utils import ASSETS, SETTINGS
13
14
  from ultralytics.utils.checks import check_yolo as checks
14
15
  from ultralytics.utils.downloads import download
15
16
 
16
17
  settings = SETTINGS
18
+
19
+ MODELS = ("YOLO", "YOLOWorld", "YOLOE", "NAS", "SAM", "FastSAM", "RTDETR")
20
+
17
21
  __all__ = (
18
22
  "__version__",
19
23
  "ASSETS",
20
- "YOLO",
21
- "YOLOWorld",
22
- "YOLOE",
23
- "NAS",
24
- "SAM",
25
- "FastSAM",
26
- "RTDETR",
24
+ *MODELS,
27
25
  "checks",
28
26
  "download",
29
27
  "settings",
30
28
  )
29
+
30
+ if TYPE_CHECKING:
31
+ # Enable hints for type checkers
32
+ from ultralytics.models import YOLO, YOLOWorld, YOLOE, NAS, SAM, FastSAM, RTDETR # noqa
33
+
34
+
35
+ def __getattr__(name: str):
36
+ """Lazy-import model classes on first access."""
37
+ if name in MODELS:
38
+ return getattr(importlib.import_module("ultralytics.models"), name)
39
+ raise AttributeError(f"module {__name__} has no attribute {name}")
40
+
41
+
42
+ def __dir__():
43
+ """Extend dir() to include lazily available model names for IDE autocompletion."""
44
+ return sorted(set(globals()) | set(MODELS))
45
+
46
+
47
+ if __name__ == "__main__":
48
+ print(__version__)