glenn-jocher commited on
Commit
b3dabdc
1 Parent(s): 41fdf9f

Update `probability` to `p` (#3980)

Browse files
Files changed (3) hide show
  1. models/common.py +2 -2
  2. utils/augmentations.py +32 -33
  3. utils/datasets.py +3 -4
models/common.py CHANGED
@@ -215,7 +215,7 @@ class NMS(nn.Module):
215
 
216
 
217
  class AutoShape(nn.Module):
218
- # input-robust model wrapper for passing cv2/np/PIL/torch inputs. Includes preprocessing, inference and NMS
219
  conf = 0.25 # NMS confidence threshold
220
  iou = 0.45 # NMS IoU threshold
221
  classes = None # (optional list) filter by class
@@ -287,7 +287,7 @@ class AutoShape(nn.Module):
287
 
288
 
289
  class Detections:
290
- # detections class for YOLOv5 inference results
291
  def __init__(self, imgs, pred, files, times=None, names=None, shape=None):
292
  super(Detections, self).__init__()
293
  d = pred[0].device # device
 
215
 
216
 
217
  class AutoShape(nn.Module):
218
+ # YOLOv5 input-robust model wrapper for passing cv2/np/PIL/torch inputs. Includes preprocessing, inference and NMS
219
  conf = 0.25 # NMS confidence threshold
220
  iou = 0.45 # NMS IoU threshold
221
  classes = None # (optional list) filter by class
 
287
 
288
 
289
  class Detections:
290
+ # YOLOv5 detections class for inference results
291
  def __init__(self, imgs, pred, files, times=None, names=None, shape=None):
292
  super(Detections, self).__init__()
293
  d = pred[0].device # device
utils/augmentations.py CHANGED
@@ -50,12 +50,12 @@ def augment_hsv(im, hgain=0.5, sgain=0.5, vgain=0.5):
50
  lut_sat = np.clip(x * r[1], 0, 255).astype(dtype)
51
  lut_val = np.clip(x * r[2], 0, 255).astype(dtype)
52
 
53
- img_hsv = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val)))
54
- cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR, dst=im) # no return needed
55
 
56
 
57
  def hist_equalize(im, clahe=True, bgr=False):
58
- # Equalize histogram on BGR image 'img' with img.shape(n,m,3) and range 0-255
59
  yuv = cv2.cvtColor(im, cv2.COLOR_BGR2YUV if bgr else cv2.COLOR_RGB2YUV)
60
  if clahe:
61
  c = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
@@ -76,7 +76,7 @@ def replicate(im, labels):
76
  bh, bw = y2b - y1b, x2b - x1b
77
  yc, xc = int(random.uniform(0, h - bh)), int(random.uniform(0, w - bw)) # offset x, y
78
  x1a, y1a, x2a, y2a = [xc, yc, xc + bw, yc + bh]
79
- im[y1a:y2a, x1a:x2a] = im[y1b:y2b, x1b:x2b] # img4[ymin:ymax, xmin:xmax]
80
  labels = np.append(labels, [[labels[i, 0], x1a, y1a, x2a, y2a]], axis=0)
81
 
82
  return im, labels
@@ -162,8 +162,8 @@ def random_perspective(im, targets=(), segments=(), degrees=10, translate=.1, sc
162
  # Visualize
163
  # import matplotlib.pyplot as plt
164
  # ax = plt.subplots(1, 2, figsize=(12, 6))[1].ravel()
165
- # ax[0].imshow(img[:, :, ::-1]) # base
166
- # ax[1].imshow(img2[:, :, ::-1]) # warped
167
 
168
  # Transform label coordinates
169
  n = len(targets)
@@ -204,13 +204,13 @@ def random_perspective(im, targets=(), segments=(), degrees=10, translate=.1, sc
204
  return im, targets
205
 
206
 
207
- def copy_paste(im, labels, segments, probability=0.5):
208
  # Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy)
209
  n = len(segments)
210
- if probability and n:
211
  h, w, c = im.shape # height, width, channels
212
  im_new = np.zeros(im.shape, np.uint8)
213
- for j in random.sample(range(n), k=round(probability * n)):
214
  l, s = labels[j], segments[j]
215
  box = w - l[3], l[2], w - l[1], l[4]
216
  ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area
@@ -223,35 +223,34 @@ def copy_paste(im, labels, segments, probability=0.5):
223
  result = cv2.flip(result, 1) # augment segments (flip left-right)
224
  i = result > 0 # pixels to replace
225
  # i[:, :] = result.max(2).reshape(h, w, 1) # act over ch
226
- im[i] = result[i] # cv2.imwrite('debug.jpg', img) # debug
227
 
228
  return im, labels, segments
229
 
230
 
231
- def cutout(im, labels):
232
  # Applies image cutout augmentation https://arxiv.org/abs/1708.04552
233
- h, w = im.shape[:2]
234
-
235
- # create random masks
236
- scales = [0.5] * 1 + [0.25] * 2 + [0.125] * 4 + [0.0625] * 8 + [0.03125] * 16 # image size fraction
237
- for s in scales:
238
- mask_h = random.randint(1, int(h * s))
239
- mask_w = random.randint(1, int(w * s))
240
-
241
- # box
242
- xmin = max(0, random.randint(0, w) - mask_w // 2)
243
- ymin = max(0, random.randint(0, h) - mask_h // 2)
244
- xmax = min(w, xmin + mask_w)
245
- ymax = min(h, ymin + mask_h)
246
-
247
- # apply random color mask
248
- im[ymin:ymax, xmin:xmax] = [random.randint(64, 191) for _ in range(3)]
249
-
250
- # return unobscured labels
251
- if len(labels) and s > 0.03:
252
- box = np.array([xmin, ymin, xmax, ymax], dtype=np.float32)
253
- ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area
254
- labels = labels[ioa < 0.60] # remove >60% obscured labels
255
 
256
  return labels
257
 
 
50
  lut_sat = np.clip(x * r[1], 0, 255).astype(dtype)
51
  lut_val = np.clip(x * r[2], 0, 255).astype(dtype)
52
 
53
+ im_hsv = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val)))
54
+ cv2.cvtColor(im_hsv, cv2.COLOR_HSV2BGR, dst=im) # no return needed
55
 
56
 
57
  def hist_equalize(im, clahe=True, bgr=False):
58
+ # Equalize histogram on BGR image 'im' with im.shape(n,m,3) and range 0-255
59
  yuv = cv2.cvtColor(im, cv2.COLOR_BGR2YUV if bgr else cv2.COLOR_RGB2YUV)
60
  if clahe:
61
  c = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
 
76
  bh, bw = y2b - y1b, x2b - x1b
77
  yc, xc = int(random.uniform(0, h - bh)), int(random.uniform(0, w - bw)) # offset x, y
78
  x1a, y1a, x2a, y2a = [xc, yc, xc + bw, yc + bh]
79
+ im[y1a:y2a, x1a:x2a] = im[y1b:y2b, x1b:x2b] # im4[ymin:ymax, xmin:xmax]
80
  labels = np.append(labels, [[labels[i, 0], x1a, y1a, x2a, y2a]], axis=0)
81
 
82
  return im, labels
 
162
  # Visualize
163
  # import matplotlib.pyplot as plt
164
  # ax = plt.subplots(1, 2, figsize=(12, 6))[1].ravel()
165
+ # ax[0].imshow(im[:, :, ::-1]) # base
166
+ # ax[1].imshow(im2[:, :, ::-1]) # warped
167
 
168
  # Transform label coordinates
169
  n = len(targets)
 
204
  return im, targets
205
 
206
 
207
+ def copy_paste(im, labels, segments, p=0.5):
208
  # Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy)
209
  n = len(segments)
210
+ if p and n:
211
  h, w, c = im.shape # height, width, channels
212
  im_new = np.zeros(im.shape, np.uint8)
213
+ for j in random.sample(range(n), k=round(p * n)):
214
  l, s = labels[j], segments[j]
215
  box = w - l[3], l[2], w - l[1], l[4]
216
  ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area
 
223
  result = cv2.flip(result, 1) # augment segments (flip left-right)
224
  i = result > 0 # pixels to replace
225
  # i[:, :] = result.max(2).reshape(h, w, 1) # act over ch
226
+ im[i] = result[i] # cv2.imwrite('debug.jpg', im) # debug
227
 
228
  return im, labels, segments
229
 
230
 
231
+ def cutout(im, labels, p=0.5):
232
  # Applies image cutout augmentation https://arxiv.org/abs/1708.04552
233
+ if random.random() < p:
234
+ h, w = im.shape[:2]
235
+ scales = [0.5] * 1 + [0.25] * 2 + [0.125] * 4 + [0.0625] * 8 + [0.03125] * 16 # image size fraction
236
+ for s in scales:
237
+ mask_h = random.randint(1, int(h * s)) # create random masks
238
+ mask_w = random.randint(1, int(w * s))
239
+
240
+ # box
241
+ xmin = max(0, random.randint(0, w) - mask_w // 2)
242
+ ymin = max(0, random.randint(0, h) - mask_h // 2)
243
+ xmax = min(w, xmin + mask_w)
244
+ ymax = min(h, ymin + mask_h)
245
+
246
+ # apply random color mask
247
+ im[ymin:ymax, xmin:xmax] = [random.randint(64, 191) for _ in range(3)]
248
+
249
+ # return unobscured labels
250
+ if len(labels) and s > 0.03:
251
+ box = np.array([xmin, ymin, xmax, ymax], dtype=np.float32)
252
+ ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area
253
+ labels = labels[ioa < 0.60] # remove >60% obscured labels
 
254
 
255
  return labels
256
 
utils/datasets.py CHANGED
@@ -22,7 +22,7 @@ from PIL import Image, ExifTags
22
  from torch.utils.data import Dataset
23
  from tqdm import tqdm
24
 
25
- from utils.augmentations import Albumentations, augment_hsv, copy_paste, letterbox, mixup, random_perspective
26
  from utils.general import check_requirements, check_file, check_dataset, xywh2xyxy, xywhn2xyxy, xyxy2xywhn, \
27
  xyn2xy, segments2boxes, clean_str
28
  from utils.torch_utils import torch_distributed_zero_first
@@ -572,8 +572,7 @@ class LoadImagesAndLabels(Dataset): # for training/testing
572
  labels[:, 1] = 1 - labels[:, 1]
573
 
574
  # Cutouts
575
- # if random.random() < 0.9:
576
- # labels = cutout(img, labels)
577
 
578
  labels_out = torch.zeros((nl, 6))
579
  if nl:
@@ -682,7 +681,7 @@ def load_mosaic(self, index):
682
  # img4, labels4 = replicate(img4, labels4) # replicate
683
 
684
  # Augment
685
- img4, labels4, segments4 = copy_paste(img4, labels4, segments4, probability=self.hyp['copy_paste'])
686
  img4, labels4 = random_perspective(img4, labels4, segments4,
687
  degrees=self.hyp['degrees'],
688
  translate=self.hyp['translate'],
 
22
  from torch.utils.data import Dataset
23
  from tqdm import tqdm
24
 
25
+ from utils.augmentations import Albumentations, augment_hsv, copy_paste, letterbox, mixup, random_perspective, cutout
26
  from utils.general import check_requirements, check_file, check_dataset, xywh2xyxy, xywhn2xyxy, xyxy2xywhn, \
27
  xyn2xy, segments2boxes, clean_str
28
  from utils.torch_utils import torch_distributed_zero_first
 
572
  labels[:, 1] = 1 - labels[:, 1]
573
 
574
  # Cutouts
575
+ # labels = cutout(img, labels, p=0.5)
 
576
 
577
  labels_out = torch.zeros((nl, 6))
578
  if nl:
 
681
  # img4, labels4 = replicate(img4, labels4) # replicate
682
 
683
  # Augment
684
+ img4, labels4, segments4 = copy_paste(img4, labels4, segments4, p=self.hyp['copy_paste'])
685
  img4, labels4 = random_perspective(img4, labels4, segments4,
686
  degrees=self.hyp['degrees'],
687
  translate=self.hyp['translate'],