-
Notifications
You must be signed in to change notification settings - Fork 118
/
augmentation.py
131 lines (102 loc) · 4.08 KB
/
augmentation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import random
import numbers
import math
import collections
from PIL import ImageOps, Image
import numpy as np
class Padding:
def __init__(self, pad):
self.pad = pad
def __call__(self, img):
return ImageOps.expand(img, border=self.pad, fill=0)
class Scale:
def __init__(self, size, interpolation=Image.NEAREST):
assert isinstance(size, int) or (isinstance(size, collections.Iterable) and len(size) == 2)
self.size = size
self.interpolation = interpolation
def __call__(self, imgmap):
img, target = imgmap
if isinstance(self.size, int):
w, h = img.size
if (w <= h and w == self.size) or (h <= w and h == self.size):
return img, target
if w < h:
ow = self.size
oh = int(self.size * h / w)
return img.resize((ow, oh), self.interpolation), target.resize((ow, oh), self.interpolation)
else:
oh = self.size
ow = int(self.size * w / h)
return img.resize((ow, oh), self.interpolation), target.resize((ow, oh), self.interpolation)
else:
return img.resize(self.size, self.interpolation), target.resize(self.size, self.interpolation)
class CenterCrop:
def __init__(self, size):
if isinstance(size, numbers.Number):
self.size = (int(size), int(size))
else:
self.size = size
def __call__(self, imgmap):
img, target = imgmap
w, h = img.size
th, tw = self.size
x1 = int(round((w - tw) / 2.))
y1 = int(round((h - th) / 2.))
return img.crop((x1, y1, x1 + tw, y1 + th)), target.crop((x1, y1, x1 + tw, y1 + th))
class RandomCrop:
def __init__(self, size):
if isinstance(size, numbers.Number):
self.size = (int(size), int(size))
else:
self.size = size
def __call__(self, imgmap):
img, target = imgmap
w, h = img.size
if self.size is not None:
th, tw = self.size
if w == tw and h == th:
return img, target
else:
x1 = random.randint(0, w - tw)
y1 = random.randint(0, h - th)
return img.crop((x1, y1, x1 + tw, y1 + th)), target.crop((x1, y1, x1 + tw, y1 + th))
else:
return img, target
class RandomSizedCrop:
def __init__(self, size, interpolation=Image.NEAREST):
self.size = size
self.interpolation = interpolation
def __call__(self, imgmap):
img, target = imgmap
for attempt in range(10):
area = img.size[0] * img.size[1]
target_area = random.uniform(0.5, 1.0) * area
aspect_ratio = random.uniform(3. / 4, 4. / 3)
w = int(round(math.sqrt(target_area * aspect_ratio)))
h = int(round(math.sqrt(target_area / aspect_ratio)))
if random.random() < 0.5:
w, h = h, w
if w <= img.size[0] and h <= img.size[1]:
x1 = random.randint(0, img.size[0] - w)
y1 = random.randint(0, img.size[1] - h)
img = img.crop((x1, y1, x1 + w, y1 + h))
target = target.crop((x1, y1, x1 + w, y1 + h))
assert(img.size == (w, h))
assert(target.size == (w, h))
return img.resize((self.size, self.size), self.interpolation), \
target.resize((self.size, self.size), self.interpolation)
# Fallback
scale = Scale(self.size, interpolation=self.interpolation)
crop = CenterCrop(self.size)
return crop(scale((img, target)))
class RandomHorizontalFlip:
def __call__(self, imgmap):
img, target = imgmap
if random.random() < 0.5:
return img.transpose(Image.FLIP_LEFT_RIGHT), target.transpose(Image.FLIP_LEFT_RIGHT)
return img, target
class RandomRotation:
def __call__(self, imgmap, degree=10):
img, target = imgmap
deg = np.random.randint(-degree, degree, 1)[0]
return img.rotate(deg), target.rotate(deg)