ultralytics 8.0.159__py3-none-any.whl → 8.0.161__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.

Potentially problematic release.


This version of ultralytics might be problematic. Click here for more details.

Files changed (30) hide show
  1. ultralytics/__init__.py +2 -3
  2. ultralytics/data/dataset.py +74 -20
  3. ultralytics/data/utils.py +39 -5
  4. ultralytics/engine/trainer.py +4 -1
  5. ultralytics/hub/__init__.py +2 -25
  6. ultralytics/hub/auth.py +2 -22
  7. ultralytics/models/fastsam/predict.py +8 -11
  8. ultralytics/models/nas/predict.py +5 -5
  9. ultralytics/models/rtdetr/predict.py +5 -5
  10. ultralytics/models/sam/modules/sam.py +21 -35
  11. ultralytics/models/sam/predict.py +4 -4
  12. ultralytics/models/yolo/classify/predict.py +4 -5
  13. ultralytics/models/yolo/classify/train.py +1 -1
  14. ultralytics/models/yolo/classify/val.py +1 -1
  15. ultralytics/models/yolo/detect/predict.py +5 -7
  16. ultralytics/models/yolo/pose/predict.py +6 -11
  17. ultralytics/models/yolo/segment/predict.py +8 -13
  18. ultralytics/nn/modules/conv.py +6 -1
  19. ultralytics/trackers/utils/kalman_filter.py +71 -95
  20. ultralytics/utils/callbacks/tensorboard.py +3 -3
  21. ultralytics/utils/checks.py +6 -5
  22. ultralytics/utils/downloads.py +12 -13
  23. ultralytics/utils/metrics.py +0 -11
  24. ultralytics/utils/ops.py +84 -117
  25. {ultralytics-8.0.159.dist-info → ultralytics-8.0.161.dist-info}/METADATA +1 -1
  26. {ultralytics-8.0.159.dist-info → ultralytics-8.0.161.dist-info}/RECORD +30 -30
  27. {ultralytics-8.0.159.dist-info → ultralytics-8.0.161.dist-info}/WHEEL +1 -1
  28. {ultralytics-8.0.159.dist-info → ultralytics-8.0.161.dist-info}/LICENSE +0 -0
  29. {ultralytics-8.0.159.dist-info → ultralytics-8.0.161.dist-info}/entry_points.txt +0 -0
  30. {ultralytics-8.0.159.dist-info → ultralytics-8.0.161.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- import torch
4
-
5
3
  from ultralytics.engine.results import Results
6
4
  from ultralytics.models.yolo.detect.predict import DetectionPredictor
7
5
  from ultralytics.utils import DEFAULT_CFG, ops
@@ -27,7 +25,6 @@ class SegmentationPredictor(DetectionPredictor):
27
25
  self.args.task = 'segment'
28
26
 
29
27
  def postprocess(self, preds, img, orig_imgs):
30
- """TODO: filter by classes."""
31
28
  p = ops.non_max_suppression(preds[0],
32
29
  self.args.conf,
33
30
  self.args.iou,
@@ -36,22 +33,20 @@ class SegmentationPredictor(DetectionPredictor):
36
33
  nc=len(self.model.names),
37
34
  classes=self.args.classes)
38
35
  results = []
36
+ is_list = isinstance(orig_imgs, list) # input images are a list, not a torch.Tensor
39
37
  proto = preds[1][-1] if len(preds[1]) == 3 else preds[1] # second output is len 3 if pt, but only 1 if exported
40
38
  for i, pred in enumerate(p):
41
- orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs
42
- path = self.batch[0]
43
- img_path = path[i] if isinstance(path, list) else path
39
+ orig_img = orig_imgs[i] if is_list else orig_imgs
40
+ img_path = self.batch[0][i]
44
41
  if not len(pred): # save empty boxes
45
- results.append(Results(orig_img=orig_img, path=img_path, names=self.model.names, boxes=pred[:, :6]))
46
- continue
47
- if self.args.retina_masks:
48
- if not isinstance(orig_imgs, torch.Tensor):
42
+ masks = None
43
+ elif self.args.retina_masks:
44
+ if is_list:
49
45
  pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape)
50
46
  masks = ops.process_mask_native(proto[i], pred[:, 6:], pred[:, :4], orig_img.shape[:2]) # HWC
51
47
  else:
52
48
  masks = ops.process_mask(proto[i], pred[:, 6:], pred[:, :4], img.shape[2:], upsample=True) # HWC
53
- if not isinstance(orig_imgs, torch.Tensor):
49
+ if is_list:
54
50
  pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape)
55
- results.append(
56
- Results(orig_img=orig_img, path=img_path, names=self.model.names, boxes=pred[:, :6], masks=masks))
51
+ results.append(Results(orig_img, path=img_path, names=self.model.names, boxes=pred[:, :6], masks=masks))
57
52
  return results
@@ -9,7 +9,7 @@ import numpy as np
9
9
  import torch
10
10
  import torch.nn as nn
11
11
 
12
- __all__ = ('Conv', 'LightConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv',
12
+ __all__ = ('Conv', 'Conv2', 'LightConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv',
13
13
  'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'RepConv')
14
14
 
15
15
 
@@ -54,6 +54,10 @@ class Conv2(Conv):
54
54
  """Apply convolution, batch normalization and activation to input tensor."""
55
55
  return self.act(self.bn(self.conv(x) + self.cv2(x)))
56
56
 
57
+ def forward_fuse(self, x):
58
+ """Apply fused convolution, batch normalization and activation to input tensor."""
59
+ return self.act(self.bn(self.conv(x)))
60
+
57
61
  def fuse_convs(self):
58
62
  """Fuse parallel convolutions."""
59
63
  w = torch.zeros_like(self.conv.weight.data)
@@ -61,6 +65,7 @@ class Conv2(Conv):
61
65
  w[:, :, i[0]:i[0] + 1, i[1]:i[1] + 1] = self.cv2.weight.data.clone()
62
66
  self.conv.weight.data += w
63
67
  self.__delattr__('cv2')
68
+ self.forward = self.forward_fuse
64
69
 
65
70
 
66
71
  class LightConv(nn.Module):
@@ -6,20 +6,13 @@ import scipy.linalg
6
6
 
7
7
  class KalmanFilterXYAH:
8
8
  """
9
- For bytetrack
10
- A simple Kalman filter for tracking bounding boxes in image space.
9
+ For bytetrack. A simple Kalman filter for tracking bounding boxes in image space.
11
10
 
12
- The 8-dimensional state space
13
-
14
- x, y, a, h, vx, vy, va, vh
15
-
16
- contains the bounding box center position (x, y), aspect ratio a, height h,
17
- and their respective velocities.
18
-
19
- Object motion follows a constant velocity model. The bounding box location
20
- (x, y, a, h) is taken as direct observation of the state space (linear
21
- observation model).
11
+ The 8-dimensional state space (x, y, a, h, vx, vy, va, vh) contains the bounding box center position (x, y),
12
+ aspect ratio a, height h, and their respective velocities.
22
13
 
14
+ Object motion follows a constant velocity model. The bounding box location (x, y, a, h) is taken as direct
15
+ observation of the state space (linear observation model).
23
16
  """
24
17
 
25
18
  def __init__(self):
@@ -32,14 +25,14 @@ class KalmanFilterXYAH:
32
25
  self._motion_mat[i, ndim + i] = dt
33
26
  self._update_mat = np.eye(ndim, 2 * ndim)
34
27
 
35
- # Motion and observation uncertainty are chosen relative to the current
36
- # state estimate. These weights control the amount of uncertainty in
37
- # the model. This is a bit hacky.
28
+ # Motion and observation uncertainty are chosen relative to the current state estimate. These weights control
29
+ # the amount of uncertainty in the model. This is a bit hacky.
38
30
  self._std_weight_position = 1. / 20
39
31
  self._std_weight_velocity = 1. / 160
40
32
 
41
33
  def initiate(self, measurement):
42
- """Create track from unassociated measurement.
34
+ """
35
+ Create track from unassociated measurement.
43
36
 
44
37
  Parameters
45
38
  ----------
@@ -53,7 +46,6 @@ class KalmanFilterXYAH:
53
46
  Returns the mean vector (8 dimensional) and covariance matrix (8x8
54
47
  dimensional) of the new track. Unobserved velocities are initialized
55
48
  to 0 mean.
56
-
57
49
  """
58
50
  mean_pos = measurement
59
51
  mean_vel = np.zeros_like(mean_pos)
@@ -67,23 +59,21 @@ class KalmanFilterXYAH:
67
59
  return mean, covariance
68
60
 
69
61
  def predict(self, mean, covariance):
70
- """Run Kalman filter prediction step.
62
+ """
63
+ Run Kalman filter prediction step.
71
64
 
72
65
  Parameters
73
66
  ----------
74
67
  mean : ndarray
75
- The 8 dimensional mean vector of the object state at the previous
76
- time step.
68
+ The 8 dimensional mean vector of the object state at the previous time step.
77
69
  covariance : ndarray
78
- The 8x8 dimensional covariance matrix of the object state at the
79
- previous time step.
70
+ The 8x8 dimensional covariance matrix of the object state at the previous time step.
80
71
 
81
72
  Returns
82
73
  -------
83
74
  (ndarray, ndarray)
84
- Returns the mean vector and covariance matrix of the predicted
85
- state. Unobserved velocities are initialized to 0 mean.
86
-
75
+ Returns the mean vector and covariance matrix of the predicted state. Unobserved velocities are
76
+ initialized to 0 mean.
87
77
  """
88
78
  std_pos = [
89
79
  self._std_weight_position * mean[3], self._std_weight_position * mean[3], 1e-2,
@@ -100,7 +90,8 @@ class KalmanFilterXYAH:
100
90
  return mean, covariance
101
91
 
102
92
  def project(self, mean, covariance):
103
- """Project state distribution to measurement space.
93
+ """
94
+ Project state distribution to measurement space.
104
95
 
105
96
  Parameters
106
97
  ----------
@@ -112,9 +103,7 @@ class KalmanFilterXYAH:
112
103
  Returns
113
104
  -------
114
105
  (ndarray, ndarray)
115
- Returns the projected mean and covariance matrix of the given state
116
- estimate.
117
-
106
+ Returns the projected mean and covariance matrix of the given state estimate.
118
107
  """
119
108
  std = [
120
109
  self._std_weight_position * mean[3], self._std_weight_position * mean[3], 1e-1,
@@ -126,20 +115,21 @@ class KalmanFilterXYAH:
126
115
  return mean, covariance + innovation_cov
127
116
 
128
117
  def multi_predict(self, mean, covariance):
129
- """Run Kalman filter prediction step (Vectorized version).
118
+ """
119
+ Run Kalman filter prediction step (Vectorized version).
120
+
130
121
  Parameters
131
122
  ----------
132
123
  mean : ndarray
133
- The Nx8 dimensional mean matrix of the object states at the previous
134
- time step.
124
+ The Nx8 dimensional mean matrix of the object states at the previous time step.
135
125
  covariance : ndarray
136
- The Nx8x8 dimensional covariance matrix of the object states at the
137
- previous time step.
126
+ The Nx8x8 dimensional covariance matrix of the object states at the previous time step.
127
+
138
128
  Returns
139
129
  -------
140
130
  (ndarray, ndarray)
141
- Returns the mean vector and covariance matrix of the predicted
142
- state. Unobserved velocities are initialized to 0 mean.
131
+ Returns the mean vector and covariance matrix of the predicted state. Unobserved velocities are
132
+ initialized to 0 mean.
143
133
  """
144
134
  std_pos = [
145
135
  self._std_weight_position * mean[:, 3], self._std_weight_position * mean[:, 3],
@@ -159,7 +149,8 @@ class KalmanFilterXYAH:
159
149
  return mean, covariance
160
150
 
161
151
  def update(self, mean, covariance, measurement):
162
- """Run Kalman filter correction step.
152
+ """
153
+ Run Kalman filter correction step.
163
154
 
164
155
  Parameters
165
156
  ----------
@@ -168,15 +159,13 @@ class KalmanFilterXYAH:
168
159
  covariance : ndarray
169
160
  The state's covariance matrix (8x8 dimensional).
170
161
  measurement : ndarray
171
- The 4 dimensional measurement vector (x, y, a, h), where (x, y)
172
- is the center position, a the aspect ratio, and h the height of the
173
- bounding box.
162
+ The 4 dimensional measurement vector (x, y, a, h), where (x, y) is the center position, a the aspect
163
+ ratio, and h the height of the bounding box.
174
164
 
175
165
  Returns
176
166
  -------
177
167
  (ndarray, ndarray)
178
168
  Returns the measurement-corrected state distribution.
179
-
180
169
  """
181
170
  projected_mean, projected_cov = self.project(mean, covariance)
182
171
 
@@ -191,10 +180,11 @@ class KalmanFilterXYAH:
191
180
  return new_mean, new_covariance
192
181
 
193
182
  def gating_distance(self, mean, covariance, measurements, only_position=False, metric='maha'):
194
- """Compute gating distance between state distribution and measurements.
195
- A suitable distance threshold can be obtained from `chi2inv95`. If
196
- `only_position` is False, the chi-square distribution has 4 degrees of
183
+ """
184
+ Compute gating distance between state distribution and measurements. A suitable distance threshold can be
185
+ obtained from `chi2inv95`. If `only_position` is False, the chi-square distribution has 4 degrees of
197
186
  freedom, otherwise 2.
187
+
198
188
  Parameters
199
189
  ----------
200
190
  mean : ndarray
@@ -202,18 +192,16 @@ class KalmanFilterXYAH:
202
192
  covariance : ndarray
203
193
  Covariance of the state distribution (8x8 dimensional).
204
194
  measurements : ndarray
205
- An Nx4 dimensional matrix of N measurements, each in
206
- format (x, y, a, h) where (x, y) is the bounding box center
207
- position, a the aspect ratio, and h the height.
195
+ An Nx4 dimensional matrix of N measurements, each in format (x, y, a, h) where (x, y) is the bounding box
196
+ center position, a the aspect ratio, and h the height.
208
197
  only_position : Optional[bool]
209
- If True, distance computation is done with respect to the bounding
210
- box center position only.
198
+ If True, distance computation is done with respect to the bounding box center position only.
199
+
211
200
  Returns
212
201
  -------
213
202
  ndarray
214
- Returns an array of length N, where the i-th element contains the
215
- squared Mahalanobis distance between (mean, covariance) and
216
- `measurements[i]`.
203
+ Returns an array of length N, where the i-th element contains the squared Mahalanobis distance between
204
+ (mean, covariance) and `measurements[i]`.
217
205
  """
218
206
  mean, covariance = self.project(mean, covariance)
219
207
  if only_position:
@@ -233,38 +221,29 @@ class KalmanFilterXYAH:
233
221
 
234
222
  class KalmanFilterXYWH(KalmanFilterXYAH):
235
223
  """
236
- For BoT-SORT
237
- A simple Kalman filter for tracking bounding boxes in image space.
224
+ For BoT-SORT. A simple Kalman filter for tracking bounding boxes in image space.
238
225
 
239
- The 8-dimensional state space
240
-
241
- x, y, w, h, vx, vy, vw, vh
242
-
243
- contains the bounding box center position (x, y), width w, height h,
244
- and their respective velocities.
245
-
246
- Object motion follows a constant velocity model. The bounding box location
247
- (x, y, w, h) is taken as direct observation of the state space (linear
248
- observation model).
226
+ The 8-dimensional state space (x, y, w, h, vx, vy, vw, vh) contains the bounding box center position (x, y),
227
+ width w, height h, and their respective velocities.
249
228
 
229
+ Object motion follows a constant velocity model. The bounding box location (x, y, w, h) is taken as direct
230
+ observation of the state space (linear observation model).
250
231
  """
251
232
 
252
233
  def initiate(self, measurement):
253
- """Create track from unassociated measurement.
234
+ """
235
+ Create track from unassociated measurement.
254
236
 
255
237
  Parameters
256
238
  ----------
257
239
  measurement : ndarray
258
- Bounding box coordinates (x, y, w, h) with center position (x, y),
259
- width w, and height h.
240
+ Bounding box coordinates (x, y, w, h) with center position (x, y), width w, and height h.
260
241
 
261
242
  Returns
262
243
  -------
263
244
  (ndarray, ndarray)
264
- Returns the mean vector (8 dimensional) and covariance matrix (8x8
265
- dimensional) of the new track. Unobserved velocities are initialized
266
- to 0 mean.
267
-
245
+ Returns the mean vector (8 dimensional) and covariance matrix (8x8 dimensional) of the new track.
246
+ Unobserved velocities are initialized to 0 mean.
268
247
  """
269
248
  mean_pos = measurement
270
249
  mean_vel = np.zeros_like(mean_pos)
@@ -279,23 +258,21 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
279
258
  return mean, covariance
280
259
 
281
260
  def predict(self, mean, covariance):
282
- """Run Kalman filter prediction step.
261
+ """
262
+ Run Kalman filter prediction step.
283
263
 
284
264
  Parameters
285
265
  ----------
286
266
  mean : ndarray
287
- The 8 dimensional mean vector of the object state at the previous
288
- time step.
267
+ The 8 dimensional mean vector of the object state at the previous time step.
289
268
  covariance : ndarray
290
- The 8x8 dimensional covariance matrix of the object state at the
291
- previous time step.
269
+ The 8x8 dimensional covariance matrix of the object state at the previous time step.
292
270
 
293
271
  Returns
294
272
  -------
295
273
  (ndarray, ndarray)
296
- Returns the mean vector and covariance matrix of the predicted
297
- state. Unobserved velocities are initialized to 0 mean.
298
-
274
+ Returns the mean vector and covariance matrix of the predicted state. Unobserved velocities are
275
+ initialized to 0 mean.
299
276
  """
300
277
  std_pos = [
301
278
  self._std_weight_position * mean[2], self._std_weight_position * mean[3],
@@ -311,7 +288,8 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
311
288
  return mean, covariance
312
289
 
313
290
  def project(self, mean, covariance):
314
- """Project state distribution to measurement space.
291
+ """
292
+ Project state distribution to measurement space.
315
293
 
316
294
  Parameters
317
295
  ----------
@@ -323,9 +301,7 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
323
301
  Returns
324
302
  -------
325
303
  (ndarray, ndarray)
326
- Returns the projected mean and covariance matrix of the given state
327
- estimate.
328
-
304
+ Returns the projected mean and covariance matrix of the given state estimate.
329
305
  """
330
306
  std = [
331
307
  self._std_weight_position * mean[2], self._std_weight_position * mean[3],
@@ -337,20 +313,21 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
337
313
  return mean, covariance + innovation_cov
338
314
 
339
315
  def multi_predict(self, mean, covariance):
340
- """Run Kalman filter prediction step (Vectorized version).
316
+ """
317
+ Run Kalman filter prediction step (Vectorized version).
318
+
341
319
  Parameters
342
320
  ----------
343
321
  mean : ndarray
344
- The Nx8 dimensional mean matrix of the object states at the previous
345
- time step.
322
+ The Nx8 dimensional mean matrix of the object states at the previous time step.
346
323
  covariance : ndarray
347
- The Nx8x8 dimensional covariance matrix of the object states at the
348
- previous time step.
324
+ The Nx8x8 dimensional covariance matrix of the object states at the previous time step.
325
+
349
326
  Returns
350
327
  -------
351
328
  (ndarray, ndarray)
352
- Returns the mean vector and covariance matrix of the predicted
353
- state. Unobserved velocities are initialized to 0 mean.
329
+ Returns the mean vector and covariance matrix of the predicted state. Unobserved velocities are
330
+ initialized to 0 mean.
354
331
  """
355
332
  std_pos = [
356
333
  self._std_weight_position * mean[:, 2], self._std_weight_position * mean[:, 3],
@@ -370,7 +347,8 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
370
347
  return mean, covariance
371
348
 
372
349
  def update(self, mean, covariance, measurement):
373
- """Run Kalman filter correction step.
350
+ """
351
+ Run Kalman filter correction step.
374
352
 
375
353
  Parameters
376
354
  ----------
@@ -379,14 +357,12 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
379
357
  covariance : ndarray
380
358
  The state's covariance matrix (8x8 dimensional).
381
359
  measurement : ndarray
382
- The 4 dimensional measurement vector (x, y, w, h), where (x, y)
383
- is the center position, w the width, and h the height of the
384
- bounding box.
360
+ The 4 dimensional measurement vector (x, y, w, h), where (x, y) is the center position, w the width,
361
+ and h the height of the bounding box.
385
362
 
386
363
  Returns
387
364
  -------
388
365
  (ndarray, ndarray)
389
366
  Returns the measurement-corrected state distribution.
390
-
391
367
  """
392
368
  return super().update(mean, covariance, measurement)
@@ -32,9 +32,9 @@ def _log_tensorboard_graph(trainer):
32
32
  imgsz = trainer.args.imgsz
33
33
  imgsz = (imgsz, imgsz) if isinstance(imgsz, int) else imgsz
34
34
  p = next(trainer.model.parameters()) # for device, type
35
- im = torch.zeros((1, 3, *imgsz), device=p.device, dtype=p.dtype) # input (WARNING: must be zeros, not empty)
36
- with warnings.catch_warnings(category=UserWarning):
37
- warnings.simplefilter('ignore') # suppress jit trace warning
35
+ im = torch.zeros((1, 3, *imgsz), device=p.device, dtype=p.dtype) # input image (must be zeros, not empty)
36
+ with warnings.catch_warnings():
37
+ warnings.simplefilter('ignore', category=UserWarning) # suppress jit trace warning
38
38
  WRITER.add_graph(torch.jit.trace(de_parallel(trainer.model), im, strict=False), [])
39
39
  except Exception as e:
40
40
  LOGGER.warning(f'WARNING ⚠️ TensorBoard graph visualization failure {e}')
@@ -20,9 +20,9 @@ import requests
20
20
  import torch
21
21
  from matplotlib import font_manager
22
22
 
23
- from ultralytics.utils import (ASSETS, AUTOINSTALL, LOGGER, ONLINE, ROOT, USER_CONFIG_DIR, ThreadingLocked, TryExcept,
24
- clean_url, colorstr, downloads, emojis, is_colab, is_docker, is_jupyter, is_kaggle,
25
- is_online, is_pip_package, url2file)
23
+ from ultralytics.utils import (ASSETS, AUTOINSTALL, LINUX, LOGGER, ONLINE, ROOT, USER_CONFIG_DIR, ThreadingLocked,
24
+ TryExcept, clean_url, colorstr, downloads, emojis, is_colab, is_docker, is_jupyter,
25
+ is_kaggle, is_online, is_pip_package, url2file)
26
26
 
27
27
 
28
28
  def is_ascii(s) -> bool:
@@ -389,8 +389,9 @@ def check_yaml(file, suffix=('.yaml', '.yml'), hard=True):
389
389
  def check_imshow(warn=False):
390
390
  """Check if environment supports image displays."""
391
391
  try:
392
- assert not any((is_colab(), is_kaggle(), is_docker()))
393
- cv2.imshow('test', np.zeros((1, 1, 3)))
392
+ if LINUX:
393
+ assert 'DISPLAY' in os.environ and not is_docker() and not is_colab() and not is_kaggle()
394
+ cv2.imshow('test', np.zeros((8, 8, 3), dtype=np.uint8)) # show a small 8-pixel image
394
395
  cv2.waitKey(1)
395
396
  cv2.destroyAllWindows()
396
397
  cv2.waitKey(1)
@@ -39,16 +39,17 @@ def is_url(url, check=True):
39
39
  return False
40
40
 
41
41
 
42
- def delete_dsstore(path):
42
+ def delete_dsstore(path, files_to_delete=('.DS_Store', '__MACOSX')):
43
43
  """
44
44
  Deletes all ".DS_store" files under a specified directory.
45
45
 
46
46
  Args:
47
47
  path (str, optional): The directory path where the ".DS_store" files should be deleted.
48
+ files_to_delete (tuple): The files to be deleted.
48
49
 
49
50
  Example:
50
51
  ```python
51
- from ultralytics.data.utils import delete_dsstore
52
+ from ultralytics.utils.downloads import delete_dsstore
52
53
 
53
54
  delete_dsstore('path/to/dir')
54
55
  ```
@@ -58,10 +59,11 @@ def delete_dsstore(path):
58
59
  are hidden system files and can cause issues when transferring files between different operating systems.
59
60
  """
60
61
  # Delete Apple .DS_store files
61
- files = list(Path(path).rglob('.DS_store'))
62
- LOGGER.info(f'Deleting *.DS_store files: {files}')
63
- for f in files:
64
- f.unlink()
62
+ for file in files_to_delete:
63
+ matches = list(Path(path).rglob(file))
64
+ LOGGER.info(f'Deleting {file} files: {matches}')
65
+ for f in matches:
66
+ f.unlink()
65
67
 
66
68
 
67
69
  def zip_directory(directory, compress=True, exclude=('.DS_Store', '__MACOSX'), progress=True):
@@ -212,21 +214,18 @@ def get_google_drive_file_info(link):
212
214
  """
213
215
  file_id = link.split('/d/')[1].split('/view')[0]
214
216
  drive_url = f'https://drive.google.com/uc?export=download&id={file_id}'
217
+ filename = None
215
218
 
216
219
  # Start session
217
- filename = None
218
220
  with requests.Session() as session:
219
221
  response = session.get(drive_url, stream=True)
220
222
  if 'quota exceeded' in str(response.content.lower()):
221
223
  raise ConnectionError(
222
224
  emojis(f'❌ Google Drive file download quota exceeded. '
223
225
  f'Please try again later or download this file manually at {link}.'))
224
- token = None
225
- for key, value in response.cookies.items():
226
- if key.startswith('download_warning'):
227
- token = value
228
- if token:
229
- drive_url = f'https://drive.google.com/uc?export=download&confirm={token}&id={file_id}'
226
+ for k, v in response.cookies.items():
227
+ if k.startswith('download_warning'):
228
+ drive_url += f'&confirm={v}' # v is token
230
229
  cd = response.headers.get('content-disposition')
231
230
  if cd:
232
231
  filename = re.findall('filename="(.+)"', cd)[0]
@@ -15,12 +15,6 @@ from ultralytics.utils import LOGGER, SimpleClass, TryExcept, plt_settings
15
15
  OKS_SIGMA = np.array([.26, .25, .25, .35, .35, .79, .79, .72, .72, .62, .62, 1.07, 1.07, .87, .87, .89, .89]) / 10.0
16
16
 
17
17
 
18
- # Boxes
19
- def box_area(box):
20
- """Return box area, where box shape is xyxy(4,n)."""
21
- return (box[2] - box[0]) * (box[3] - box[1])
22
-
23
-
24
18
  def bbox_ioa(box1, box2, iou=False, eps=1e-7):
25
19
  """
26
20
  Calculate the intersection over box2 area given box1 and box2. Boxes are in x1y1x2y2 format.
@@ -869,11 +863,6 @@ class PoseMetrics(SegmentMetrics):
869
863
  self.pose = Metric()
870
864
  self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0}
871
865
 
872
- def __getattr__(self, attr):
873
- """Raises an AttributeError if an invalid attribute is accessed."""
874
- name = self.__class__.__name__
875
- raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
876
-
877
866
  def process(self, tp_b, tp_p, conf, pred_cls, target_cls):
878
867
  """
879
868
  Processes the detection and pose metrics over the given set of predictions.