-
Notifications
You must be signed in to change notification settings - Fork 31
/
augmentation.py
238 lines (200 loc) · 7.69 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
import imgaug.augmenters as iaa
import numpy as np
from imgaug.augmenters import Affine
def applyAugmentation(images):
"""
Apply augmentations to the images. Augmentation are : vertical flipping, horzontal flipping, rotation, cropping,
shearing, scaling, blurring, contrast adjusting, adding noise and hue and saturation change. They are aplied with a
certain probability.
:param images: RGB matrixes of two images and the corresponding mask
:return: RGB matrixes of two images and the corresponding mask with modification applied.
"""
# HYPER-PARAMETERS
# rotation
rotate_bounds = (0, 10)
# cropping
crop_bounds = (0, 0.15)
# shearing
tuple = (0.15, 6.0)
# scale
scalex_bound = (1.0, 1.3)
scaley_bound = (1.0, 1.3)
# blur
sigma = (np.random.uniform(0.2, 2.5), np.random.uniform(0.2, 2.5))
# contrast
gamma = (0.75, 1.1)
# noise
scale_noise = (10, 30)
# hue
hue_range = (-30, 50)
output = images
'''
# shear and rotate
dice = np.random.randint(0,10) / 10.0
if dice < 0.3 :
output = shear(images, tuple)
if dice < 0.3 :
output = rotate(output, rotate_bounds)
'''
# flip
dice = np.random.randint(0, 10) / 10.0
if dice < 0:
output = horizontal_flip(output)
dice = np.random.randint(0, 10) / 10.0
if dice < 10:
output = vertical_flip(output)
'''
# crop
dice = np.random.randint(0, 10) / 10.0
if dice < 0.3:
output = crop(output, crop_bounds)
# scale
dice = np.random.randint(0, 10) / 10.0
if dice > 0.9:
output = scale(output, scalex_bound, scaley_bound)
# blur
dice = np.random.randint(0, 10) / 10.0
if dice <=0.4:
output = gaussian_blur(output, sigma)
# contrast
dice = np.random.randint(0, 10) / 10.0
if dice >0.5:
output = contrast(output, gamma)
'''
# hue and saturation
dice = np.random.randint(0, 10) / 10.0
if dice > 0.5:
output = hue_and_saturation(output, hue_range)
'''
# noise
dice = np.random.randint(0, 10) / 10.0
if dice > 0.7:
output = gaussian_noise(output, scale_noise)
'''
return convert_back_to_uint(output)
def vertical_flip(image):
"""
Perform a vertical flip on the three images given in input
:param image: The three input images in one matrix 650x650x(3+3+3)
:return: The three input images in one matrix 650x650x(3+3+3) flipped on a vertical axis
"""
flipped = np.zeros(image.shape)
for index, img in enumerate(image):
for index2 in [0, 1, 2]:
array = img[:, :, index2]
flipped[index, :, :, index2] = np.flip(array, 0)
return convert_back_to_uint(flipped)
def horizontal_flip(image):
"""
Perform a horizontal flip on the three images given as input
:param image: The three input images in one matrix 650x650x(3+3+3)
:return: The three input images in one matrix 650x650x(3+3+3) flipped on a horizontal axis
"""
flipped = np.zeros(image.shape)
for index, img in enumerate(image):
for index2 in [0, 1, 2]:
array = img[:, :, index2]
flipped[index, :, :, index2] = np.flip(array, 1)
return convert_back_to_uint(flipped)
def shear(image, shear_bounds):
"""
Shear the images
:param image: RGB matrix of 3 input images
:param shear_bounds: tuple with min and max bound of the shearing
:return: RGB matrix of the sheared images
"""
shear_value = np.random.randint(shear_bounds[0], shear_bounds[1])
seq = iaa.Sequential([iaa.Affine(shear=(shear_value, shear_value))])
images_aug = seq(images=image)
return convert_back_to_uint(images_aug)
def gaussian_blur(image, strength):
"""
Blur an image with a Gautian Blur
:param image: the image(s) to be blurred. Can be multiple, blurring is independent of the number of images
:param strength: tuple contain min valu and max value of the sigma. True value will be random between values.
:return: RGB matrix of the input with blur
"""
res = image.copy()
gauss = iaa.Sequential([iaa.GaussianBlur(sigma=strength)])
images_to_modified = image[0:2]
res[0:2] = convert_back_to_uint(gauss(images=images_to_modified))
return res
def hue_and_saturation(image, hue_range):
"""
Change hue and saturation by value in range given
:param image: RGB matrix of the two images. (uselles augmentation on a mask)
:param hue_range: range of hue and saturation modification (-255, 255)
:return: RGB matrix
"""
res = image.copy()
modifier = iaa.AddToHueAndSaturation(hue_range, per_channel=True)
res[0:2] = modifier(images=convert_back_to_uint(image[0:2]))
return res
def rotate(images, bounds):
"""
Rotate the image by a random angle between the min and max value of the bounds given
:param images: RGB matrix of all images
:param bounds: min, max value of the rotating angle
:return: RGB matrixes of all images rotated
"""
rotate_value = np.random.randint(bounds[0], bounds[1])
rotating = iaa.Affine(rotate=(rotate_value, rotate_value))
rotated_image = rotating(images=images)
return convert_back_to_uint(rotated_image)
def gaussian_noise(images, bounds):
"""
adding gaussian noise to images. Different noise for each image.
:param images: RGB matrix of two input images. Nois on mask is useless
:param bounds: min and max of the gaussian noise
:return: RGB matrix with gaussian Noise
"""
noisy_images = images.copy()
gaussian_noise_adder = iaa.AdditiveGaussianNoise(loc=0, scale=bounds, per_channel=0.5)
noisy_images[0:2] = gaussian_noise_adder(images=convert_back_to_uint(images[0:2]))
return noisy_images
def crop(images, bounds):
"""
:param images: RGB matrixes of input images including mask
:param bounds: min and max of percetnage of cropping
:return:
"""
crop_value = np.random.uniform(bounds[0], bounds[1])
croper = iaa.Crop(percent=(crop_value, crop_value))
cropped_images = croper(images=images)
return convert_back_to_uint(cropped_images)
def contrast(images, gamma):
"""
Modifie the contrast of an image by a gamma distribution.
:param images: RGB matrixes of two images. contrast on mask is useless
:param gamma: value of gamma parameter (constraint to 0.8 and 1.05) If too high or low, the image is either black or
overly saturated
:return: RBG matrix with contrast changed
"""
contrasted_images = images.copy()
contraster = iaa.GammaContrast(gamma=gamma)
contrasted_images[0:2] = contraster(images=images[0:2])
return convert_back_to_uint(contrasted_images)
def scale(images, boundx, boundy):
"""
Scale the image on the x axis by a random value between boundx and on the y axis by a random value between boundy
:param images: RGB matrixes of all images including mask
:param boundx: min and max of the distance moved in x
:param boundy: min and max of the distance moved in y
:return: RGB matrixes scaled
"""
scalex = np.random.uniform(boundx[0], boundx[1])
scaley = np.random.uniform(boundy[0], boundy[1])
scaler = iaa.Affine(scale={"x": (scalex, scalex), "y": (scaley, scaley)})
scaled_images = scaler(images=images)
return convert_back_to_uint(scaled_images)
def convert_back_to_uint(matrix):
"""
Helper functiun to turn a matrix back into a uint matrix. Applied to the RGB matrixes after modification. Changes
applied ususally result into a float matrix.
:param matrix: A 650 x650 matrix of float
:return: the matrix with all value rounded to uint.
"""
matrix = matrix.astype(np.float64) / 255
data = 255 * matrix
img = data.astype(np.uint8)
return img