glenn-jocher
commited on
Commit
•
b3dabdc
1
Parent(s):
41fdf9f
Update `probability` to `p` (#3980)
Browse files- models/common.py +2 -2
- utils/augmentations.py +32 -33
- 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
|
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 |
-
|
54 |
-
cv2.cvtColor(
|
55 |
|
56 |
|
57 |
def hist_equalize(im, clahe=True, bgr=False):
|
58 |
-
# Equalize histogram on BGR image '
|
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] #
|
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(
|
166 |
-
# ax[1].imshow(
|
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,
|
208 |
# Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy)
|
209 |
n = len(segments)
|
210 |
-
if
|
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(
|
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',
|
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 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
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 |
-
#
|
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,
|
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'],
|