ultralytics 8.3.88__py3-none-any.whl → 8.3.90__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.
- tests/conftest.py +2 -2
- tests/test_cli.py +13 -11
- tests/test_cuda.py +10 -1
- tests/test_integrations.py +1 -5
- tests/test_python.py +16 -16
- tests/test_solutions.py +9 -9
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/__init__.py +3 -1
- ultralytics/cfg/models/11/yolo11-cls.yaml +5 -5
- ultralytics/cfg/models/11/yolo11-obb.yaml +5 -5
- ultralytics/cfg/models/11/yolo11-pose.yaml +5 -5
- ultralytics/cfg/models/11/yolo11-seg.yaml +5 -5
- ultralytics/cfg/models/11/yolo11.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8-ghost.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8-obb.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8-p6.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8-world.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8-worldv2.yaml +5 -5
- ultralytics/cfg/models/v8/yolov8.yaml +5 -5
- ultralytics/cfg/models/v9/yolov9c-seg.yaml +1 -1
- ultralytics/cfg/models/v9/yolov9c.yaml +1 -1
- ultralytics/cfg/models/v9/yolov9e-seg.yaml +1 -1
- ultralytics/cfg/models/v9/yolov9e.yaml +1 -1
- ultralytics/cfg/models/v9/yolov9m.yaml +1 -1
- ultralytics/cfg/models/v9/yolov9s.yaml +1 -1
- ultralytics/cfg/models/v9/yolov9t.yaml +1 -1
- ultralytics/data/annotator.py +9 -14
- ultralytics/data/base.py +125 -39
- ultralytics/data/build.py +63 -24
- ultralytics/data/converter.py +34 -33
- ultralytics/data/dataset.py +207 -53
- ultralytics/data/loaders.py +1 -0
- ultralytics/data/split_dota.py +39 -12
- ultralytics/data/utils.py +33 -47
- ultralytics/engine/exporter.py +19 -17
- ultralytics/engine/model.py +69 -90
- ultralytics/engine/predictor.py +106 -21
- ultralytics/engine/trainer.py +32 -23
- ultralytics/engine/tuner.py +31 -38
- ultralytics/engine/validator.py +75 -41
- ultralytics/hub/__init__.py +21 -26
- ultralytics/hub/auth.py +9 -12
- ultralytics/hub/session.py +76 -21
- ultralytics/hub/utils.py +19 -17
- ultralytics/models/fastsam/model.py +23 -17
- ultralytics/models/fastsam/predict.py +36 -16
- ultralytics/models/fastsam/utils.py +5 -5
- ultralytics/models/fastsam/val.py +6 -6
- ultralytics/models/nas/model.py +29 -24
- ultralytics/models/nas/predict.py +14 -11
- ultralytics/models/nas/val.py +11 -13
- ultralytics/models/rtdetr/model.py +20 -11
- ultralytics/models/rtdetr/predict.py +21 -21
- ultralytics/models/rtdetr/train.py +25 -24
- ultralytics/models/rtdetr/val.py +47 -14
- ultralytics/models/sam/__init__.py +1 -1
- ultralytics/models/sam/amg.py +50 -4
- ultralytics/models/sam/model.py +8 -14
- ultralytics/models/sam/modules/decoders.py +18 -21
- ultralytics/models/sam/modules/encoders.py +25 -46
- ultralytics/models/sam/modules/memory_attention.py +19 -15
- ultralytics/models/sam/modules/sam.py +18 -25
- ultralytics/models/sam/modules/tiny_encoder.py +19 -29
- ultralytics/models/sam/modules/transformer.py +35 -57
- ultralytics/models/sam/modules/utils.py +15 -15
- ultralytics/models/sam/predict.py +0 -3
- ultralytics/models/utils/loss.py +87 -36
- ultralytics/models/utils/ops.py +26 -31
- ultralytics/models/yolo/classify/predict.py +30 -12
- ultralytics/models/yolo/classify/train.py +83 -19
- ultralytics/models/yolo/classify/val.py +45 -23
- ultralytics/models/yolo/detect/predict.py +29 -19
- ultralytics/models/yolo/detect/train.py +90 -23
- ultralytics/models/yolo/detect/val.py +150 -29
- ultralytics/models/yolo/model.py +1 -2
- ultralytics/models/yolo/obb/predict.py +18 -13
- ultralytics/models/yolo/obb/train.py +12 -8
- ultralytics/models/yolo/obb/val.py +35 -22
- ultralytics/models/yolo/pose/predict.py +28 -15
- ultralytics/models/yolo/pose/train.py +21 -8
- ultralytics/models/yolo/pose/val.py +51 -31
- ultralytics/models/yolo/segment/predict.py +27 -16
- ultralytics/models/yolo/segment/train.py +11 -8
- ultralytics/models/yolo/segment/val.py +110 -29
- ultralytics/models/yolo/world/train.py +43 -16
- ultralytics/models/yolo/world/train_world.py +61 -36
- ultralytics/nn/autobackend.py +28 -14
- ultralytics/nn/modules/__init__.py +12 -12
- ultralytics/nn/modules/activation.py +12 -3
- ultralytics/nn/modules/block.py +587 -84
- ultralytics/nn/modules/conv.py +418 -54
- ultralytics/nn/modules/head.py +3 -4
- ultralytics/nn/modules/transformer.py +320 -34
- ultralytics/nn/modules/utils.py +17 -3
- ultralytics/nn/tasks.py +226 -79
- ultralytics/solutions/ai_gym.py +2 -2
- ultralytics/solutions/analytics.py +4 -4
- ultralytics/solutions/heatmap.py +4 -4
- ultralytics/solutions/instance_segmentation.py +10 -4
- ultralytics/solutions/object_blurrer.py +2 -2
- ultralytics/solutions/object_counter.py +2 -2
- ultralytics/solutions/object_cropper.py +2 -2
- ultralytics/solutions/parking_management.py +9 -9
- ultralytics/solutions/queue_management.py +1 -1
- ultralytics/solutions/region_counter.py +2 -2
- ultralytics/solutions/security_alarm.py +7 -7
- ultralytics/solutions/solutions.py +7 -4
- ultralytics/solutions/speed_estimation.py +2 -2
- ultralytics/solutions/streamlit_inference.py +6 -6
- ultralytics/solutions/trackzone.py +9 -2
- ultralytics/solutions/vision_eye.py +4 -4
- ultralytics/trackers/basetrack.py +1 -1
- ultralytics/trackers/bot_sort.py +23 -22
- ultralytics/trackers/byte_tracker.py +4 -4
- ultralytics/trackers/track.py +2 -1
- ultralytics/trackers/utils/gmc.py +26 -27
- ultralytics/trackers/utils/kalman_filter.py +31 -29
- ultralytics/trackers/utils/matching.py +7 -7
- ultralytics/utils/__init__.py +37 -35
- ultralytics/utils/autobatch.py +5 -5
- ultralytics/utils/benchmarks.py +111 -18
- ultralytics/utils/callbacks/base.py +3 -3
- ultralytics/utils/callbacks/clearml.py +11 -11
- ultralytics/utils/callbacks/comet.py +35 -22
- ultralytics/utils/callbacks/dvc.py +11 -10
- ultralytics/utils/callbacks/hub.py +8 -8
- ultralytics/utils/callbacks/mlflow.py +1 -1
- ultralytics/utils/callbacks/neptune.py +12 -10
- ultralytics/utils/callbacks/raytune.py +1 -1
- ultralytics/utils/callbacks/tensorboard.py +6 -6
- ultralytics/utils/callbacks/wb.py +16 -16
- ultralytics/utils/checks.py +139 -68
- ultralytics/utils/dist.py +15 -2
- ultralytics/utils/downloads.py +37 -56
- ultralytics/utils/files.py +12 -13
- ultralytics/utils/instance.py +117 -52
- ultralytics/utils/loss.py +28 -33
- ultralytics/utils/metrics.py +246 -181
- ultralytics/utils/ops.py +65 -61
- ultralytics/utils/patches.py +8 -6
- ultralytics/utils/plotting.py +72 -59
- ultralytics/utils/tal.py +88 -57
- ultralytics/utils/torch_utils.py +202 -64
- ultralytics/utils/triton.py +13 -3
- ultralytics/utils/tuner.py +13 -25
- {ultralytics-8.3.88.dist-info → ultralytics-8.3.90.dist-info}/METADATA +2 -2
- ultralytics-8.3.90.dist-info/RECORD +250 -0
- ultralytics-8.3.88.dist-info/RECORD +0 -250
- {ultralytics-8.3.88.dist-info → ultralytics-8.3.90.dist-info}/LICENSE +0 -0
- {ultralytics-8.3.88.dist-info → ultralytics-8.3.90.dist-info}/WHEEL +0 -0
- {ultralytics-8.3.88.dist-info → ultralytics-8.3.90.dist-info}/entry_points.txt +0 -0
- {ultralytics-8.3.88.dist-info → ultralytics-8.3.90.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,7 @@
|
|
3
3
|
# YOLOv9e object detection model with P3/8 - P5/32 outputs
|
4
4
|
# Model docs: https://docs.ultralytics.com/models/yolov9
|
5
5
|
# Task docs: https://docs.ultralytics.com/tasks/detect
|
6
|
-
#
|
6
|
+
# 721 layers, 58206592 parameters, 193.0 GFLOPs
|
7
7
|
|
8
8
|
# Parameters
|
9
9
|
nc: 80 # number of classes
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# YOLOv9m object detection model with P3/8 - P5/32 outputs
|
4
4
|
# Model docs: https://docs.ultralytics.com/models/yolov9
|
5
5
|
# Task docs: https://docs.ultralytics.com/tasks/detect
|
6
|
-
#
|
6
|
+
# 348 layers, 20216160 parameters, 77.9 GFLOPs
|
7
7
|
|
8
8
|
# Parameters
|
9
9
|
nc: 80 # number of classes
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# YOLOv9s object detection model with P3/8 - P5/32 outputs
|
4
4
|
# Model docs: https://docs.ultralytics.com/models/yolov9
|
5
5
|
# Task docs: https://docs.ultralytics.com/tasks/detect
|
6
|
-
#
|
6
|
+
# 544 layers, 7318368 parameters, 27.6 GFLOPs
|
7
7
|
|
8
8
|
# Parameters
|
9
9
|
nc: 80 # number of classes
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# YOLOv9t object detection model with P3/8 - P5/32 outputs
|
4
4
|
# Model docs: https://docs.ultralytics.com/models/yolov9
|
5
5
|
# Task docs: https://docs.ultralytics.com/tasks/detect
|
6
|
-
#
|
6
|
+
# 544 layers, 2128720 parameters, 8.5 GFLOPs
|
7
7
|
|
8
8
|
# Parameters
|
9
9
|
nc: 80 # number of classes
|
ultralytics/data/annotator.py
CHANGED
@@ -18,31 +18,26 @@ def auto_annotate(
|
|
18
18
|
output_dir=None,
|
19
19
|
):
|
20
20
|
"""
|
21
|
-
Automatically
|
21
|
+
Automatically annotate images using a YOLO object detection model and a SAM segmentation model.
|
22
22
|
|
23
23
|
This function processes images in a specified directory, detects objects using a YOLO model, and then generates
|
24
24
|
segmentation masks using a SAM model. The resulting annotations are saved as text files.
|
25
25
|
|
26
26
|
Args:
|
27
|
-
data (str): Path to a folder containing images to be annotated.
|
27
|
+
data (str | Path): Path to a folder containing images to be annotated.
|
28
28
|
det_model (str): Path or name of the pre-trained YOLO detection model.
|
29
29
|
sam_model (str): Path or name of the pre-trained SAM segmentation model.
|
30
30
|
device (str): Device to run the models on (e.g., 'cpu', 'cuda', '0').
|
31
|
-
conf (float): Confidence threshold for detection model
|
32
|
-
iou (float): IoU threshold for filtering overlapping boxes in detection results
|
33
|
-
imgsz (int): Input image resize dimension
|
34
|
-
max_det (int):
|
35
|
-
classes (
|
36
|
-
output_dir (str | None): Directory to save the annotated results. If None, a default directory is created.
|
31
|
+
conf (float): Confidence threshold for detection model.
|
32
|
+
iou (float): IoU threshold for filtering overlapping boxes in detection results.
|
33
|
+
imgsz (int): Input image resize dimension.
|
34
|
+
max_det (int): Maximum number of detections per image.
|
35
|
+
classes (List[int] | None): Filter predictions to specified class IDs, returning only relevant detections.
|
36
|
+
output_dir (str | Path | None): Directory to save the annotated results. If None, a default directory is created.
|
37
37
|
|
38
38
|
Examples:
|
39
39
|
>>> from ultralytics.data.annotator import auto_annotate
|
40
40
|
>>> auto_annotate(data="ultralytics/assets", det_model="yolo11n.pt", sam_model="mobile_sam.pt")
|
41
|
-
|
42
|
-
Notes:
|
43
|
-
- The function creates a new directory for output if not specified.
|
44
|
-
- Annotation results are saved as text files with the same names as the input images.
|
45
|
-
- Each line in the output text file represents a detected object with its class ID and segmentation points.
|
46
41
|
"""
|
47
42
|
det_model = YOLO(det_model)
|
48
43
|
sam_model = SAM(sam_model)
|
@@ -61,7 +56,7 @@ def auto_annotate(
|
|
61
56
|
if class_ids:
|
62
57
|
boxes = result.boxes.xyxy # Boxes object for bbox outputs
|
63
58
|
sam_results = sam_model(result.orig_img, bboxes=boxes, verbose=False, save=False, device=device)
|
64
|
-
segments = sam_results[0].masks.xyn
|
59
|
+
segments = sam_results[0].masks.xyn
|
65
60
|
|
66
61
|
with open(f"{Path(output_dir) / Path(result.path).stem}.txt", "w", encoding="utf-8") as f:
|
67
62
|
for i, s in enumerate(segments):
|
ultralytics/data/base.py
CHANGED
@@ -22,28 +22,45 @@ class BaseDataset(Dataset):
|
|
22
22
|
"""
|
23
23
|
Base dataset class for loading and processing image data.
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
imgsz (int, optional): Image size. Defaults to 640.
|
28
|
-
cache (bool, optional): Cache images to RAM or disk during training. Defaults to False.
|
29
|
-
augment (bool, optional): If True, data augmentation is applied. Defaults to True.
|
30
|
-
hyp (dict, optional): Hyperparameters to apply data augmentation. Defaults to None.
|
31
|
-
prefix (str, optional): Prefix to print in log messages. Defaults to ''.
|
32
|
-
rect (bool, optional): If True, rectangular training is used. Defaults to False.
|
33
|
-
batch_size (int, optional): Size of batches. Defaults to None.
|
34
|
-
stride (int, optional): Stride. Defaults to 32.
|
35
|
-
pad (float, optional): Padding. Defaults to 0.0.
|
36
|
-
single_cls (bool, optional): If True, single class training is used. Defaults to False.
|
37
|
-
classes (list): List of included classes. Default is None.
|
38
|
-
fraction (float): Fraction of dataset to utilize. Default is 1.0 (use all data).
|
25
|
+
This class provides core functionality for loading images, caching, and preparing data for training and inference
|
26
|
+
in object detection tasks.
|
39
27
|
|
40
28
|
Attributes:
|
41
|
-
|
42
|
-
|
29
|
+
img_path (str): Path to the folder containing images.
|
30
|
+
imgsz (int): Target image size for resizing.
|
31
|
+
augment (bool): Whether to apply data augmentation.
|
32
|
+
single_cls (bool): Whether to treat all objects as a single class.
|
33
|
+
prefix (str): Prefix to print in log messages.
|
34
|
+
fraction (float): Fraction of dataset to utilize.
|
35
|
+
im_files (List[str]): List of image file paths.
|
36
|
+
labels (List[Dict]): List of label data dictionaries.
|
43
37
|
ni (int): Number of images in the dataset.
|
44
|
-
|
45
|
-
|
38
|
+
rect (bool): Whether to use rectangular training.
|
39
|
+
batch_size (int): Size of batches.
|
40
|
+
stride (int): Stride used in the model.
|
41
|
+
pad (float): Padding value.
|
42
|
+
buffer (List): Buffer for mosaic images.
|
43
|
+
max_buffer_length (int): Maximum buffer size.
|
44
|
+
ims (List): List of loaded images.
|
45
|
+
im_hw0 (List): List of original image dimensions (h, w).
|
46
|
+
im_hw (List): List of resized image dimensions (h, w).
|
47
|
+
npy_files (List[Path]): List of numpy file paths.
|
48
|
+
cache (str): Cache images to RAM or disk during training.
|
46
49
|
transforms (callable): Image transformation function.
|
50
|
+
|
51
|
+
Methods:
|
52
|
+
get_img_files: Read image files from the specified path.
|
53
|
+
update_labels: Update labels to include only specified classes.
|
54
|
+
load_image: Load an image from the dataset.
|
55
|
+
cache_images: Cache images to memory or disk.
|
56
|
+
cache_images_to_disk: Save an image as an *.npy file for faster loading.
|
57
|
+
check_cache_disk: Check image caching requirements vs available disk space.
|
58
|
+
check_cache_ram: Check image caching requirements vs available memory.
|
59
|
+
set_rectangle: Set the shape of bounding boxes as rectangles.
|
60
|
+
get_image_and_label: Get and return label information from the dataset.
|
61
|
+
update_labels_info: Custom label format method to be implemented by subclasses.
|
62
|
+
build_transforms: Build transformation pipeline to be implemented by subclasses.
|
63
|
+
get_labels: Get labels method to be implemented by subclasses.
|
47
64
|
"""
|
48
65
|
|
49
66
|
def __init__(
|
@@ -62,7 +79,24 @@ class BaseDataset(Dataset):
|
|
62
79
|
classes=None,
|
63
80
|
fraction=1.0,
|
64
81
|
):
|
65
|
-
"""
|
82
|
+
"""
|
83
|
+
Initialize BaseDataset with given configuration and options.
|
84
|
+
|
85
|
+
Args:
|
86
|
+
img_path (str): Path to the folder containing images.
|
87
|
+
imgsz (int, optional): Image size for resizing.
|
88
|
+
cache (bool | str, optional): Cache images to RAM or disk during training.
|
89
|
+
augment (bool, optional): If True, data augmentation is applied.
|
90
|
+
hyp (dict, optional): Hyperparameters to apply data augmentation.
|
91
|
+
prefix (str, optional): Prefix to print in log messages.
|
92
|
+
rect (bool, optional): If True, rectangular training is used.
|
93
|
+
batch_size (int, optional): Size of batches.
|
94
|
+
stride (int, optional): Stride used in the model.
|
95
|
+
pad (float, optional): Padding value.
|
96
|
+
single_cls (bool, optional): If True, single class training is used.
|
97
|
+
classes (List, optional): List of included classes.
|
98
|
+
fraction (float, optional): Fraction of dataset to utilize.
|
99
|
+
"""
|
66
100
|
super().__init__()
|
67
101
|
self.img_path = img_path
|
68
102
|
self.imgsz = imgsz
|
@@ -104,7 +138,18 @@ class BaseDataset(Dataset):
|
|
104
138
|
self.transforms = self.build_transforms(hyp=hyp)
|
105
139
|
|
106
140
|
def get_img_files(self, img_path):
|
107
|
-
"""
|
141
|
+
"""
|
142
|
+
Read image files from the specified path.
|
143
|
+
|
144
|
+
Args:
|
145
|
+
img_path (str | List[str]): Path or list of paths to image directories or files.
|
146
|
+
|
147
|
+
Returns:
|
148
|
+
(List[str]): List of image file paths.
|
149
|
+
|
150
|
+
Raises:
|
151
|
+
FileNotFoundError: If no images are found or the path doesn't exist.
|
152
|
+
"""
|
108
153
|
try:
|
109
154
|
f = [] # image files
|
110
155
|
for p in img_path if isinstance(img_path, list) else [img_path]:
|
@@ -130,7 +175,12 @@ class BaseDataset(Dataset):
|
|
130
175
|
return im_files
|
131
176
|
|
132
177
|
def update_labels(self, include_class: Optional[list]):
|
133
|
-
"""
|
178
|
+
"""
|
179
|
+
Update labels to include only specified classes.
|
180
|
+
|
181
|
+
Args:
|
182
|
+
include_class (List, optional): List of classes to include. If None, all classes are included.
|
183
|
+
"""
|
134
184
|
include_class_array = np.array(include_class).reshape(1, -1)
|
135
185
|
for i in range(len(self.labels)):
|
136
186
|
if include_class is not None:
|
@@ -149,7 +199,21 @@ class BaseDataset(Dataset):
|
|
149
199
|
self.labels[i]["cls"][:, 0] = 0
|
150
200
|
|
151
201
|
def load_image(self, i, rect_mode=True):
|
152
|
-
"""
|
202
|
+
"""
|
203
|
+
Load an image from dataset index 'i'.
|
204
|
+
|
205
|
+
Args:
|
206
|
+
i (int): Index of the image to load.
|
207
|
+
rect_mode (bool, optional): Whether to use rectangular resizing.
|
208
|
+
|
209
|
+
Returns:
|
210
|
+
(np.ndarray): Loaded image.
|
211
|
+
(tuple): Original image dimensions (h, w).
|
212
|
+
(tuple): Resized image dimensions (h, w).
|
213
|
+
|
214
|
+
Raises:
|
215
|
+
FileNotFoundError: If the image file is not found.
|
216
|
+
"""
|
153
217
|
im, f, fn = self.ims[i], self.im_files[i], self.npy_files[i]
|
154
218
|
if im is None: # not cached in RAM
|
155
219
|
if fn.exists(): # load npy
|
@@ -187,7 +251,7 @@ class BaseDataset(Dataset):
|
|
187
251
|
return self.ims[i], self.im_hw0[i], self.im_hw[i]
|
188
252
|
|
189
253
|
def cache_images(self):
|
190
|
-
"""Cache images to memory or disk."""
|
254
|
+
"""Cache images to memory or disk for faster training."""
|
191
255
|
b, gb = 0, 1 << 30 # bytes of cached images, bytes per gigabytes
|
192
256
|
fcn, storage = (self.cache_images_to_disk, "Disk") if self.cache == "disk" else (self.load_image, "RAM")
|
193
257
|
with ThreadPool(NUM_THREADS) as pool:
|
@@ -203,13 +267,21 @@ class BaseDataset(Dataset):
|
|
203
267
|
pbar.close()
|
204
268
|
|
205
269
|
def cache_images_to_disk(self, i):
|
206
|
-
"""
|
270
|
+
"""Save an image as an *.npy file for faster loading."""
|
207
271
|
f = self.npy_files[i]
|
208
272
|
if not f.exists():
|
209
273
|
np.save(f.as_posix(), cv2.imread(self.im_files[i]), allow_pickle=False)
|
210
274
|
|
211
275
|
def check_cache_disk(self, safety_margin=0.5):
|
212
|
-
"""
|
276
|
+
"""
|
277
|
+
Check if there's enough disk space for caching images.
|
278
|
+
|
279
|
+
Args:
|
280
|
+
safety_margin (float, optional): Safety margin factor for disk space calculation.
|
281
|
+
|
282
|
+
Returns:
|
283
|
+
(bool): True if there's enough disk space, False otherwise.
|
284
|
+
"""
|
213
285
|
import shutil
|
214
286
|
|
215
287
|
b, gb = 0, 1 << 30 # bytes of cached images, bytes per gigabytes
|
@@ -237,7 +309,15 @@ class BaseDataset(Dataset):
|
|
237
309
|
return True
|
238
310
|
|
239
311
|
def check_cache_ram(self, safety_margin=0.5):
|
240
|
-
"""
|
312
|
+
"""
|
313
|
+
Check if there's enough RAM for caching images.
|
314
|
+
|
315
|
+
Args:
|
316
|
+
safety_margin (float, optional): Safety margin factor for RAM calculation.
|
317
|
+
|
318
|
+
Returns:
|
319
|
+
(bool): True if there's enough RAM, False otherwise.
|
320
|
+
"""
|
241
321
|
b, gb = 0, 1 << 30 # bytes of cached images, bytes per gigabytes
|
242
322
|
n = min(self.ni, 30) # extrapolate from 30 random images
|
243
323
|
for _ in range(n):
|
@@ -259,7 +339,7 @@ class BaseDataset(Dataset):
|
|
259
339
|
return True
|
260
340
|
|
261
341
|
def set_rectangle(self):
|
262
|
-
"""
|
342
|
+
"""Set the shape of bounding boxes for YOLO detections as rectangles."""
|
263
343
|
bi = np.floor(np.arange(self.ni) / self.batch_size).astype(int) # batch index
|
264
344
|
nb = bi[-1] + 1 # number of batches
|
265
345
|
|
@@ -284,11 +364,19 @@ class BaseDataset(Dataset):
|
|
284
364
|
self.batch = bi # batch index of image
|
285
365
|
|
286
366
|
def __getitem__(self, index):
|
287
|
-
"""
|
367
|
+
"""Return transformed label information for given index."""
|
288
368
|
return self.transforms(self.get_image_and_label(index))
|
289
369
|
|
290
370
|
def get_image_and_label(self, index):
|
291
|
-
"""
|
371
|
+
"""
|
372
|
+
Get and return label information from the dataset.
|
373
|
+
|
374
|
+
Args:
|
375
|
+
index (int): Index of the image to retrieve.
|
376
|
+
|
377
|
+
Returns:
|
378
|
+
(dict): Label dictionary with image and metadata.
|
379
|
+
"""
|
292
380
|
label = deepcopy(self.labels[index]) # requires deepcopy() https://github.com/ultralytics/ultralytics/pull/1948
|
293
381
|
label.pop("shape", None) # shape is for rect, remove it
|
294
382
|
label["img"], label["ori_shape"], label["resized_shape"] = self.load_image(index)
|
@@ -301,7 +389,7 @@ class BaseDataset(Dataset):
|
|
301
389
|
return self.update_labels_info(label)
|
302
390
|
|
303
391
|
def __len__(self):
|
304
|
-
"""
|
392
|
+
"""Return the length of the labels list for the dataset."""
|
305
393
|
return len(self.labels)
|
306
394
|
|
307
395
|
def update_labels_info(self, label):
|
@@ -312,15 +400,13 @@ class BaseDataset(Dataset):
|
|
312
400
|
"""
|
313
401
|
Users can customize augmentations here.
|
314
402
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
return Compose([])
|
323
|
-
```
|
403
|
+
Examples:
|
404
|
+
>>> if self.augment:
|
405
|
+
... # Training transforms
|
406
|
+
... return Compose([])
|
407
|
+
>>> else:
|
408
|
+
... # Val transforms
|
409
|
+
... return Compose([])
|
324
410
|
"""
|
325
411
|
raise NotImplementedError
|
326
412
|
|
ultralytics/data/build.py
CHANGED
@@ -29,26 +29,37 @@ class InfiniteDataLoader(dataloader.DataLoader):
|
|
29
29
|
"""
|
30
30
|
Dataloader that reuses workers.
|
31
31
|
|
32
|
-
|
32
|
+
This dataloader extends the PyTorch DataLoader to provide infinite recycling of workers, which improves efficiency
|
33
|
+
for training loops that need to iterate through the dataset multiple times.
|
34
|
+
|
35
|
+
Attributes:
|
36
|
+
batch_sampler (_RepeatSampler): A sampler that repeats indefinitely.
|
37
|
+
iterator (Iterator): The iterator from the parent DataLoader.
|
38
|
+
|
39
|
+
Methods:
|
40
|
+
__len__: Returns the length of the batch sampler's sampler.
|
41
|
+
__iter__: Creates a sampler that repeats indefinitely.
|
42
|
+
__del__: Ensures workers are properly terminated.
|
43
|
+
reset: Resets the iterator, useful when modifying dataset settings during training.
|
33
44
|
"""
|
34
45
|
|
35
46
|
def __init__(self, *args, **kwargs):
|
36
|
-
"""
|
47
|
+
"""Initialize the InfiniteDataLoader with the same arguments as DataLoader."""
|
37
48
|
super().__init__(*args, **kwargs)
|
38
49
|
object.__setattr__(self, "batch_sampler", _RepeatSampler(self.batch_sampler))
|
39
50
|
self.iterator = super().__iter__()
|
40
51
|
|
41
52
|
def __len__(self):
|
42
|
-
"""
|
53
|
+
"""Return the length of the batch sampler's sampler."""
|
43
54
|
return len(self.batch_sampler.sampler)
|
44
55
|
|
45
56
|
def __iter__(self):
|
46
|
-
"""
|
57
|
+
"""Create an iterator that yields indefinitely from the underlying iterator."""
|
47
58
|
for _ in range(len(self)):
|
48
59
|
yield next(self.iterator)
|
49
60
|
|
50
61
|
def __del__(self):
|
51
|
-
"""Ensure that workers are terminated."""
|
62
|
+
"""Ensure that workers are properly terminated when the dataloader is deleted."""
|
52
63
|
try:
|
53
64
|
if not hasattr(self.iterator, "_workers"):
|
54
65
|
return
|
@@ -60,11 +71,7 @@ class InfiniteDataLoader(dataloader.DataLoader):
|
|
60
71
|
pass
|
61
72
|
|
62
73
|
def reset(self):
|
63
|
-
"""
|
64
|
-
Reset iterator.
|
65
|
-
|
66
|
-
This is useful when we want to modify settings of dataset while training.
|
67
|
-
"""
|
74
|
+
"""Reset the iterator to allow modifications to the dataset during training."""
|
68
75
|
self.iterator = self._get_iterator()
|
69
76
|
|
70
77
|
|
@@ -72,29 +79,32 @@ class _RepeatSampler:
|
|
72
79
|
"""
|
73
80
|
Sampler that repeats forever.
|
74
81
|
|
75
|
-
|
82
|
+
This sampler wraps another sampler and yields its contents indefinitely, allowing for infinite iteration
|
83
|
+
over a dataset.
|
84
|
+
|
85
|
+
Attributes:
|
76
86
|
sampler (Dataset.sampler): The sampler to repeat.
|
77
87
|
"""
|
78
88
|
|
79
89
|
def __init__(self, sampler):
|
80
|
-
"""
|
90
|
+
"""Initialize the _RepeatSampler with a sampler to repeat indefinitely."""
|
81
91
|
self.sampler = sampler
|
82
92
|
|
83
93
|
def __iter__(self):
|
84
|
-
"""
|
94
|
+
"""Iterate over the sampler indefinitely, yielding its contents."""
|
85
95
|
while True:
|
86
96
|
yield from iter(self.sampler)
|
87
97
|
|
88
98
|
|
89
99
|
def seed_worker(worker_id): # noqa
|
90
|
-
"""Set dataloader worker seed
|
100
|
+
"""Set dataloader worker seed for reproducibility across worker processes."""
|
91
101
|
worker_seed = torch.initial_seed() % 2**32
|
92
102
|
np.random.seed(worker_seed)
|
93
103
|
random.seed(worker_seed)
|
94
104
|
|
95
105
|
|
96
106
|
def build_yolo_dataset(cfg, img_path, batch, data, mode="train", rect=False, stride=32, multi_modal=False):
|
97
|
-
"""Build YOLO
|
107
|
+
"""Build and return a YOLO dataset based on configuration parameters."""
|
98
108
|
dataset = YOLOMultiModalDataset if multi_modal else YOLODataset
|
99
109
|
return dataset(
|
100
110
|
img_path=img_path,
|
@@ -116,7 +126,7 @@ def build_yolo_dataset(cfg, img_path, batch, data, mode="train", rect=False, str
|
|
116
126
|
|
117
127
|
|
118
128
|
def build_grounding(cfg, img_path, json_file, batch, mode="train", rect=False, stride=32):
|
119
|
-
"""Build
|
129
|
+
"""Build and return a GroundingDataset based on configuration parameters."""
|
120
130
|
return GroundingDataset(
|
121
131
|
img_path=img_path,
|
122
132
|
json_file=json_file,
|
@@ -137,7 +147,19 @@ def build_grounding(cfg, img_path, json_file, batch, mode="train", rect=False, s
|
|
137
147
|
|
138
148
|
|
139
149
|
def build_dataloader(dataset, batch, workers, shuffle=True, rank=-1):
|
140
|
-
"""
|
150
|
+
"""
|
151
|
+
Create and return an InfiniteDataLoader or DataLoader for training or validation.
|
152
|
+
|
153
|
+
Args:
|
154
|
+
dataset (Dataset): Dataset to load data from.
|
155
|
+
batch (int): Batch size for the dataloader.
|
156
|
+
workers (int): Number of worker threads for loading data.
|
157
|
+
shuffle (bool): Whether to shuffle the dataset.
|
158
|
+
rank (int): Process rank in distributed training. -1 for single-GPU training.
|
159
|
+
|
160
|
+
Returns:
|
161
|
+
(InfiniteDataLoader): A dataloader that can be used for training or validation.
|
162
|
+
"""
|
141
163
|
batch = min(batch, len(dataset))
|
142
164
|
nd = torch.cuda.device_count() # number of CUDA devices
|
143
165
|
nw = min(os.cpu_count() // max(nd, 1), workers) # number of workers
|
@@ -158,7 +180,24 @@ def build_dataloader(dataset, batch, workers, shuffle=True, rank=-1):
|
|
158
180
|
|
159
181
|
|
160
182
|
def check_source(source):
|
161
|
-
"""
|
183
|
+
"""
|
184
|
+
Check the type of input source and return corresponding flag values.
|
185
|
+
|
186
|
+
Args:
|
187
|
+
source (str | int | Path | List | Tuple | np.ndarray | PIL.Image | torch.Tensor): The input source to check.
|
188
|
+
|
189
|
+
Returns:
|
190
|
+
(tuple): A tuple containing:
|
191
|
+
- source: The processed source.
|
192
|
+
- webcam (bool): Whether the source is a webcam.
|
193
|
+
- screenshot (bool): Whether the source is a screenshot.
|
194
|
+
- from_img (bool): Whether the source is an image or list of images.
|
195
|
+
- in_memory (bool): Whether the source is an in-memory object.
|
196
|
+
- tensor (bool): Whether the source is a torch.Tensor.
|
197
|
+
|
198
|
+
Raises:
|
199
|
+
TypeError: If the source type is unsupported.
|
200
|
+
"""
|
162
201
|
webcam, screenshot, from_img, in_memory, tensor = False, False, False, False, False
|
163
202
|
if isinstance(source, (str, int, Path)): # int for local usb camera
|
164
203
|
source = str(source)
|
@@ -185,16 +224,16 @@ def check_source(source):
|
|
185
224
|
|
186
225
|
def load_inference_source(source=None, batch=1, vid_stride=1, buffer=False):
|
187
226
|
"""
|
188
|
-
|
227
|
+
Load an inference source for object detection and apply necessary transformations.
|
189
228
|
|
190
229
|
Args:
|
191
|
-
source (str
|
192
|
-
batch (int, optional): Batch size for dataloaders.
|
193
|
-
vid_stride (int, optional): The frame interval for video sources.
|
194
|
-
buffer (bool, optional):
|
230
|
+
source (str | Path | torch.Tensor | PIL.Image | np.ndarray, optional): The input source for inference.
|
231
|
+
batch (int, optional): Batch size for dataloaders.
|
232
|
+
vid_stride (int, optional): The frame interval for video sources.
|
233
|
+
buffer (bool, optional): Whether stream frames will be buffered.
|
195
234
|
|
196
235
|
Returns:
|
197
|
-
|
236
|
+
(Dataset): A dataset object for the specified input source with attached source_type attribute.
|
198
237
|
"""
|
199
238
|
source, stream, screenshot, from_img, in_memory, tensor = check_source(source)
|
200
239
|
source_type = source.source_type if in_memory else SourceTypes(stream, screenshot, from_img, tensor)
|
ultralytics/data/converter.py
CHANGED
@@ -21,7 +21,7 @@ def coco91_to_coco80_class():
|
|
21
21
|
Converts 91-index COCO class IDs to 80-index COCO class IDs.
|
22
22
|
|
23
23
|
Returns:
|
24
|
-
(
|
24
|
+
(List): A list of 91 class IDs where the index represents the 80-index class ID and the value is the
|
25
25
|
corresponding 91-index class ID.
|
26
26
|
"""
|
27
27
|
return [
|
@@ -124,15 +124,16 @@ def coco80_to_coco91_class():
|
|
124
124
|
Converts 80-index (val2014) to 91-index (paper).
|
125
125
|
For details see https://tech.amikelive.com/node-718/what-object-categories-labels-are-in-coco-dataset/.
|
126
126
|
|
127
|
-
|
128
|
-
|
129
|
-
|
127
|
+
Examples:
|
128
|
+
>>> import numpy as np
|
129
|
+
>>> a = np.loadtxt("data/coco.names", dtype="str", delimiter="\n")
|
130
|
+
>>> b = np.loadtxt("data/coco_paper.names", dtype="str", delimiter="\n")
|
131
|
+
|
132
|
+
Convert the darknet to COCO format
|
133
|
+
>>> x1 = [list(a[i] == b).index(True) + 1 for i in range(80)]
|
130
134
|
|
131
|
-
|
132
|
-
|
133
|
-
x1 = [list(a[i] == b).index(True) + 1 for i in range(80)] # darknet to coco
|
134
|
-
x2 = [list(b[i] == a).index(True) if any(b[i] == a) else None for i in range(91)] # coco to darknet
|
135
|
-
```
|
135
|
+
Convert the COCO to darknet format
|
136
|
+
>>> x2 = [list(b[i] == a).index(True) if any(b[i] == a) else None for i in range(91)]
|
136
137
|
"""
|
137
138
|
return [
|
138
139
|
1,
|
@@ -227,7 +228,7 @@ def convert_coco(
|
|
227
228
|
lvis=False,
|
228
229
|
):
|
229
230
|
"""
|
230
|
-
Converts COCO dataset annotations to a YOLO annotation format
|
231
|
+
Converts COCO dataset annotations to a YOLO annotation format suitable for training YOLO models.
|
231
232
|
|
232
233
|
Args:
|
233
234
|
labels_dir (str, optional): Path to directory containing COCO dataset annotation files.
|
@@ -237,15 +238,20 @@ def convert_coco(
|
|
237
238
|
cls91to80 (bool, optional): Whether to map 91 COCO class IDs to the corresponding 80 COCO class IDs.
|
238
239
|
lvis (bool, optional): Whether to convert data in lvis dataset way.
|
239
240
|
|
240
|
-
|
241
|
-
|
242
|
-
|
241
|
+
Examples:
|
242
|
+
>>> from ultralytics.data.converter import convert_coco
|
243
|
+
|
244
|
+
Convert COCO annotations to YOLO format
|
245
|
+
>>> convert_coco("../datasets/coco/annotations/", use_segments=True, use_keypoints=False, cls91to80=False)
|
243
246
|
|
244
|
-
|
245
|
-
convert_coco(
|
246
|
-
|
247
|
-
|
248
|
-
|
247
|
+
Convert LVIS annotations to YOLO format
|
248
|
+
>>> convert_coco(
|
249
|
+
>>> "../datasets/lvis/annotations/",
|
250
|
+
... use_segments=True,
|
251
|
+
... use_keypoints=False,
|
252
|
+
... cls91to80=False,
|
253
|
+
... lvis=True
|
254
|
+
... )
|
249
255
|
|
250
256
|
Output:
|
251
257
|
Generates output files in the specified output directory.
|
@@ -353,13 +359,11 @@ def convert_segment_masks_to_yolo_seg(masks_dir, output_dir, classes):
|
|
353
359
|
output_dir (str): The path to the directory where the converted YOLO segmentation masks will be stored.
|
354
360
|
classes (int): Total classes in the dataset i.e. for COCO classes=80
|
355
361
|
|
356
|
-
|
357
|
-
|
358
|
-
from ultralytics.data.converter import convert_segment_masks_to_yolo_seg
|
362
|
+
Examples:
|
363
|
+
>>> from ultralytics.data.converter import convert_segment_masks_to_yolo_seg
|
359
364
|
|
360
|
-
|
361
|
-
convert_segment_masks_to_yolo_seg("path/to/masks_directory", "path/to/output/directory", classes=80)
|
362
|
-
```
|
365
|
+
The classes here is the total classes in the dataset, for COCO dataset we have 80 classes
|
366
|
+
>>> convert_segment_masks_to_yolo_seg("path/to/masks_directory", "path/to/output/directory", classes=80)
|
363
367
|
|
364
368
|
Notes:
|
365
369
|
The expected directory structure for the masks is:
|
@@ -429,12 +433,9 @@ def convert_dota_to_yolo_obb(dota_root_path: str):
|
|
429
433
|
Args:
|
430
434
|
dota_root_path (str): The root directory path of the DOTA dataset.
|
431
435
|
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
convert_dota_to_yolo_obb("path/to/DOTA")
|
437
|
-
```
|
436
|
+
Examples:
|
437
|
+
>>> from ultralytics.data.converter import convert_dota_to_yolo_obb
|
438
|
+
>>> convert_dota_to_yolo_obb("path/to/DOTA")
|
438
439
|
|
439
440
|
Notes:
|
440
441
|
The directory structure assumed for the DOTA dataset:
|
@@ -588,9 +589,9 @@ def yolo_bbox2segment(im_dir, save_dir=None, sam_model="sam_b.pt", device=None):
|
|
588
589
|
Args:
|
589
590
|
im_dir (str | Path): Path to image directory to convert.
|
590
591
|
save_dir (str | Path): Path to save the generated labels, labels will be saved
|
591
|
-
into `labels-segment` in the same directory level of `im_dir` if save_dir is None.
|
592
|
-
sam_model (str): Segmentation model to use for intermediate segmentation data
|
593
|
-
device (int | str): The specific device to run SAM models.
|
592
|
+
into `labels-segment` in the same directory level of `im_dir` if save_dir is None.
|
593
|
+
sam_model (str): Segmentation model to use for intermediate segmentation data.
|
594
|
+
device (int | str): The specific device to run SAM models.
|
594
595
|
|
595
596
|
Notes:
|
596
597
|
The input directory structure assumed for dataset:
|