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
@@ -18,8 +18,7 @@ from ultralytics.utils.checks import check_requirements
18
18
 
19
19
 
20
20
  def bbox_iof(polygon1: np.ndarray, bbox2: np.ndarray, eps: float = 1e-6) -> np.ndarray:
21
- """
22
- Calculate Intersection over Foreground (IoF) between polygons and bounding boxes.
21
+ """Calculate Intersection over Foreground (IoF) between polygons and bounding boxes.
23
22
 
24
23
  Args:
25
24
  polygon1 (np.ndarray): Polygon coordinates with shape (N, 8).
@@ -65,8 +64,7 @@ def bbox_iof(polygon1: np.ndarray, bbox2: np.ndarray, eps: float = 1e-6) -> np.n
65
64
 
66
65
 
67
66
  def load_yolo_dota(data_root: str, split: str = "train") -> list[dict[str, Any]]:
68
- """
69
- Load DOTA dataset annotations and image information.
67
+ """Load DOTA dataset annotations and image information.
70
68
 
71
69
  Args:
72
70
  data_root (str): Data root directory.
@@ -107,8 +105,7 @@ def get_windows(
107
105
  im_rate_thr: float = 0.6,
108
106
  eps: float = 0.01,
109
107
  ) -> np.ndarray:
110
- """
111
- Get the coordinates of sliding windows for image cropping.
108
+ """Get the coordinates of sliding windows for image cropping.
112
109
 
113
110
  Args:
114
111
  im_size (tuple[int, int]): Original image size, (H, W).
@@ -118,7 +115,7 @@ def get_windows(
118
115
  eps (float, optional): Epsilon value for math operations.
119
116
 
120
117
  Returns:
121
- (np.ndarray): Array of window coordinates with shape (N, 4) where each row is [x_start, y_start, x_stop, y_stop].
118
+ (np.ndarray): Array of window coordinates of shape (N, 4) where each row is [x_start, y_start, x_stop, y_stop].
122
119
  """
123
120
  h, w = im_size
124
121
  windows = []
@@ -175,8 +172,7 @@ def crop_and_save(
175
172
  lb_dir: str,
176
173
  allow_background_images: bool = True,
177
174
  ) -> None:
178
- """
179
- Crop images and save new labels for each window.
175
+ """Crop images and save new labels for each window.
180
176
 
181
177
  Args:
182
178
  anno (dict[str, Any]): Annotation dict, including 'filepath', 'label', 'ori_size' as its keys.
@@ -226,8 +222,7 @@ def split_images_and_labels(
226
222
  crop_sizes: tuple[int, ...] = (1024,),
227
223
  gaps: tuple[int, ...] = (200,),
228
224
  ) -> None:
229
- """
230
- Split both images and labels for a given dataset split.
225
+ """Split both images and labels for a given dataset split.
231
226
 
232
227
  Args:
233
228
  data_root (str): Root directory of the dataset.
@@ -265,8 +260,7 @@ def split_images_and_labels(
265
260
  def split_trainval(
266
261
  data_root: str, save_dir: str, crop_size: int = 1024, gap: int = 200, rates: tuple[float, ...] = (1.0,)
267
262
  ) -> None:
268
- """
269
- Split train and val sets of DOTA dataset with multiple scaling rates.
263
+ """Split train and val sets of DOTA dataset with multiple scaling rates.
270
264
 
271
265
  Args:
272
266
  data_root (str): Root directory of the dataset.
@@ -304,8 +298,7 @@ def split_trainval(
304
298
  def split_test(
305
299
  data_root: str, save_dir: str, crop_size: int = 1024, gap: int = 200, rates: tuple[float, ...] = (1.0,)
306
300
  ) -> None:
307
- """
308
- Split test set of DOTA dataset, labels are not included within this set.
301
+ """Split test set of DOTA dataset, labels are not included within this set.
309
302
 
310
303
  Args:
311
304
  data_root (str): Root directory of the dataset.
ultralytics/data/utils.py CHANGED
@@ -19,6 +19,7 @@ from PIL import Image, ImageOps
19
19
 
20
20
  from ultralytics.nn.autobackend import check_class_names
21
21
  from ultralytics.utils import (
22
+ ASSETS_URL,
22
23
  DATASETS_DIR,
23
24
  LOGGER,
24
25
  NUM_THREADS,
@@ -50,11 +51,10 @@ def img2label_paths(img_paths: list[str]) -> list[str]:
50
51
  def check_file_speeds(
51
52
  files: list[str], threshold_ms: float = 10, threshold_mb: float = 50, max_files: int = 5, prefix: str = ""
52
53
  ):
53
- """
54
- Check dataset file access speed and provide performance feedback.
54
+ """Check dataset file access speed and provide performance feedback.
55
55
 
56
- This function tests the access speed of dataset files by measuring ping (stat call) time and read speed.
57
- It samples up to 5 files from the provided list and warns if access times exceed the threshold.
56
+ This function tests the access speed of dataset files by measuring ping (stat call) time and read speed. It samples
57
+ up to 5 files from the provided list and warns if access times exceed the threshold.
58
58
 
59
59
  Args:
60
60
  files (list[str]): List of file paths to check for access speed.
@@ -250,21 +250,20 @@ def verify_image_label(args: tuple) -> list:
250
250
 
251
251
 
252
252
  def visualize_image_annotations(image_path: str, txt_path: str, label_map: dict[int, str]):
253
- """
254
- Visualize YOLO annotations (bounding boxes and class labels) on an image.
253
+ """Visualize YOLO annotations (bounding boxes and class labels) on an image.
255
254
 
256
- This function reads an image and its corresponding annotation file in YOLO format, then
257
- draws bounding boxes around detected objects and labels them with their respective class names.
258
- The bounding box colors are assigned based on the class ID, and the text color is dynamically
259
- adjusted for readability, depending on the background color's luminance.
255
+ This function reads an image and its corresponding annotation file in YOLO format, then draws bounding boxes around
256
+ detected objects and labels them with their respective class names. The bounding box colors are assigned based on
257
+ the class ID, and the text color is dynamically adjusted for readability, depending on the background color's
258
+ luminance.
260
259
 
261
260
  Args:
262
- image_path (str): The path to the image file to annotate, and it can be in formats supported by PIL.
263
- txt_path (str): The path to the annotation file in YOLO format, that should contain one line per object.
261
+ image_path (str): Path to the image file to annotate. The file must be readable by PIL.
262
+ txt_path (str): Path to the annotation file in YOLO format, which should contain one line per object.
264
263
  label_map (dict[int, str]): A dictionary that maps class IDs (integers) to class labels (strings).
265
264
 
266
265
  Examples:
267
- >>> label_map = {0: "cat", 1: "dog", 2: "bird"} # It should include all annotated classes details
266
+ >>> label_map = {0: "cat", 1: "dog", 2: "bird"} # Should include all annotated classes
268
267
  >>> visualize_image_annotations("path/to/image.jpg", "path/to/annotations.txt", label_map)
269
268
  """
270
269
  import matplotlib.pyplot as plt
@@ -284,7 +283,7 @@ def visualize_image_annotations(image_path: str, txt_path: str, label_map: dict[
284
283
  annotations.append((x, y, w, h, int(class_id)))
285
284
  _, ax = plt.subplots(1) # Plot the image and annotations
286
285
  for x, y, w, h, label in annotations:
287
- color = tuple(c / 255 for c in colors(label, True)) # Get and normalize the RGB color
286
+ color = tuple(c / 255 for c in colors(label, False)) # Get and normalize an RGB color for Matplotlib
288
287
  rect = plt.Rectangle((x, y), w, h, linewidth=2, edgecolor=color, facecolor="none") # Create a rectangle
289
288
  ax.add_patch(rect)
290
289
  luminance = 0.2126 * color[0] + 0.7152 * color[1] + 0.0722 * color[2] # Formula for luminance
@@ -296,13 +295,12 @@ def visualize_image_annotations(image_path: str, txt_path: str, label_map: dict[
296
295
  def polygon2mask(
297
296
  imgsz: tuple[int, int], polygons: list[np.ndarray], color: int = 1, downsample_ratio: int = 1
298
297
  ) -> np.ndarray:
299
- """
300
- Convert a list of polygons to a binary mask of the specified image size.
298
+ """Convert a list of polygons to a binary mask of the specified image size.
301
299
 
302
300
  Args:
303
301
  imgsz (tuple[int, int]): The size of the image as (height, width).
304
- polygons (list[np.ndarray]): A list of polygons. Each polygon is an array with shape (N, M), where
305
- N is the number of polygons, and M is the number of points such that M % 2 = 0.
302
+ polygons (list[np.ndarray]): A list of polygons. Each polygon is an array with shape (N, M), where N is the
303
+ number of polygons, and M is the number of points such that M % 2 = 0.
306
304
  color (int, optional): The color value to fill in the polygons on the mask.
307
305
  downsample_ratio (int, optional): Factor by which to downsample the mask.
308
306
 
@@ -321,13 +319,12 @@ def polygon2mask(
321
319
  def polygons2masks(
322
320
  imgsz: tuple[int, int], polygons: list[np.ndarray], color: int, downsample_ratio: int = 1
323
321
  ) -> np.ndarray:
324
- """
325
- Convert a list of polygons to a set of binary masks of the specified image size.
322
+ """Convert a list of polygons to a set of binary masks of the specified image size.
326
323
 
327
324
  Args:
328
325
  imgsz (tuple[int, int]): The size of the image as (height, width).
329
- polygons (list[np.ndarray]): A list of polygons. Each polygon is an array with shape (N, M), where
330
- N is the number of polygons, and M is the number of points such that M % 2 = 0.
326
+ polygons (list[np.ndarray]): A list of polygons. Each polygon is an array with shape (N, M), where N is the
327
+ number of polygons, and M is the number of points such that M % 2 = 0.
331
328
  color (int): The color value to fill in the polygons on the masks.
332
329
  downsample_ratio (int, optional): Factor by which to downsample each mask.
333
330
 
@@ -367,8 +364,7 @@ def polygons2masks_overlap(
367
364
 
368
365
 
369
366
  def find_dataset_yaml(path: Path) -> Path:
370
- """
371
- Find and return the YAML file associated with a Detect, Segment or Pose dataset.
367
+ """Find and return the YAML file associated with a Detect, Segment or Pose dataset.
372
368
 
373
369
  This function searches for a YAML file at the root level of the provided directory first, and if not found, it
374
370
  performs a recursive search. It prefers YAML files that have the same stem as the provided path.
@@ -388,8 +384,7 @@ def find_dataset_yaml(path: Path) -> Path:
388
384
 
389
385
 
390
386
  def check_det_dataset(dataset: str, autodownload: bool = True) -> dict[str, Any]:
391
- """
392
- Download, verify, and/or unzip a dataset if not found locally.
387
+ """Download, verify, and/or unzip a dataset if not found locally.
393
388
 
394
389
  This function checks the availability of a specified dataset, and if not found, it has the option to download and
395
390
  unzip the dataset. It then reads and parses the accompanying YAML data, ensuring key requirements are met and also
@@ -459,7 +454,7 @@ def check_det_dataset(dataset: str, autodownload: bool = True) -> dict[str, Any]
459
454
  if not all(x.exists() for x in val):
460
455
  name = clean_url(dataset) # dataset name with URL auth stripped
461
456
  LOGGER.info("")
462
- m = f"Dataset '{name}' images not found, missing path '{[x for x in val if not x.exists()][0]}'"
457
+ m = f"Dataset '{name}' images not found, missing path '{next(x for x in val if not x.exists())}'"
463
458
  if s and autodownload:
464
459
  LOGGER.warning(m)
465
460
  else:
@@ -483,11 +478,10 @@ def check_det_dataset(dataset: str, autodownload: bool = True) -> dict[str, Any]
483
478
 
484
479
 
485
480
  def check_cls_dataset(dataset: str | Path, split: str = "") -> dict[str, Any]:
486
- """
487
- Check a classification dataset such as Imagenet.
481
+ """Check a classification dataset such as Imagenet.
488
482
 
489
- This function accepts a `dataset` name and attempts to retrieve the corresponding dataset information.
490
- If the dataset is not found locally, it attempts to download the dataset from the internet and save it locally.
483
+ This function accepts a `dataset` name and attempts to retrieve the corresponding dataset information. If the
484
+ dataset is not found locally, it attempts to download the dataset from the internet and save it locally.
491
485
 
492
486
  Args:
493
487
  dataset (str | Path): The name of the dataset.
@@ -512,14 +506,18 @@ def check_cls_dataset(dataset: str | Path, split: str = "") -> dict[str, Any]:
512
506
  dataset = Path(dataset)
513
507
  data_dir = (dataset if dataset.is_dir() else (DATASETS_DIR / dataset)).resolve()
514
508
  if not data_dir.is_dir():
509
+ if data_dir.suffix != "":
510
+ raise ValueError(
511
+ f'Classification datasets must be a directory (data="path/to/dir") not a file (data="{dataset}"), '
512
+ "See https://docs.ultralytics.com/datasets/classify/"
513
+ )
515
514
  LOGGER.info("")
516
515
  LOGGER.warning(f"Dataset not found, missing path {data_dir}, attempting download...")
517
516
  t = time.time()
518
517
  if str(dataset) == "imagenet":
519
518
  subprocess.run(["bash", str(ROOT / "data/scripts/get_imagenet.sh")], check=True)
520
519
  else:
521
- url = f"https://github.com/ultralytics/assets/releases/download/v0.0.0/{dataset}.zip"
522
- download(url, dir=data_dir.parent)
520
+ download(f"{ASSETS_URL}/{dataset}.zip", dir=data_dir.parent)
523
521
  LOGGER.info(f"Dataset download success ✅ ({time.time() - t:.1f}s), saved to {colorstr('bold', data_dir)}\n")
524
522
  train_set = data_dir / "train"
525
523
  if not train_set.is_dir():
@@ -576,8 +574,7 @@ def check_cls_dataset(dataset: str | Path, split: str = "") -> dict[str, Any]:
576
574
 
577
575
 
578
576
  class HUBDatasetStats:
579
- """
580
- A class for generating HUB dataset JSON and `-hub` dataset directory.
577
+ """A class for generating HUB dataset JSON and `-hub` dataset directory.
581
578
 
582
579
  Args:
583
580
  path (str): Path to data.yaml or data.zip (with data.yaml inside data.zip).
@@ -595,10 +592,6 @@ class HUBDatasetStats:
595
592
  get_json: Return dataset JSON for Ultralytics HUB.
596
593
  process_images: Compress images for Ultralytics HUB.
597
594
 
598
- Note:
599
- Download *.zip files from https://github.com/ultralytics/hub/tree/main/example_datasets
600
- i.e. https://github.com/ultralytics/hub/raw/main/example_datasets/coco8.zip for coco8.zip.
601
-
602
595
  Examples:
603
596
  >>> from ultralytics.data.utils import HUBDatasetStats
604
597
  >>> stats = HUBDatasetStats("path/to/coco8.zip", task="detect") # detect dataset
@@ -608,6 +601,10 @@ class HUBDatasetStats:
608
601
  >>> stats = HUBDatasetStats("path/to/imagenet10.zip", task="classify") # classification dataset
609
602
  >>> stats.get_json(save=True)
610
603
  >>> stats.process_images()
604
+
605
+ Notes:
606
+ Download *.zip files from https://github.com/ultralytics/hub/tree/main/example_datasets
607
+ i.e. https://github.com/ultralytics/hub/raw/main/example_datasets/coco8.zip for coco8.zip.
611
608
  """
612
609
 
613
610
  def __init__(self, path: str = "coco8.yaml", task: str = "detect", autodownload: bool = False):
@@ -742,11 +739,10 @@ class HUBDatasetStats:
742
739
  return self.im_dir
743
740
 
744
741
 
745
- def compress_one_image(f: str, f_new: str = None, max_dim: int = 1920, quality: int = 50):
746
- """
747
- Compress a single image file to reduced size while preserving its aspect ratio and quality using either the Python
748
- Imaging Library (PIL) or OpenCV library. If the input image is smaller than the maximum dimension, it will not be
749
- resized.
742
+ def compress_one_image(f: str, f_new: str | None = None, max_dim: int = 1920, quality: int = 50):
743
+ """Compress a single image file to reduced size while preserving its aspect ratio and quality using either the
744
+ Python Imaging Library (PIL) or OpenCV library. If the input image is smaller than the maximum dimension, it
745
+ will not be resized.
750
746
 
751
747
  Args:
752
748
  f (str): The path to the input image file.
@@ -799,4 +795,4 @@ def save_dataset_cache_file(prefix: str, path: Path, x: dict, version: str):
799
795
  np.save(file, x)
800
796
  LOGGER.info(f"{prefix}New cache created: {path}")
801
797
  else:
802
- LOGGER.warning(f"{prefix}Cache directory {path.parent} is not writeable, cache not saved.")
798
+ LOGGER.warning(f"{prefix}Cache directory {path.parent} is not writable, cache not saved.")