-
Notifications
You must be signed in to change notification settings - Fork 36
/
processing_utils.py
399 lines (329 loc) · 14.9 KB
/
processing_utils.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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
'''
utility function package for image processing
by Sibo Zhu, Kieran Xiao Wang
2017.08.24
'''
import numpy as np
import cv2
import random
from PIL import Image
import PIL
from natsort import natsorted
import os, os.path
def save_image(image_np_array, image_save_path):
'''
!!! Sibo, Please complete this function !!!
:param image_np_array: 3-D numpy array
:param image_save_path: string
:return:
'''
im = Image.fromarray(image_np_array)
im.save(image_save_path)
def patch_merge_to_one_from_folder(patch_dir):
'''
merge patches into a whole image
!!! Sibo, please complete this function !!!
!!! now you are using naming for indicating patch location and blur/no blur, which is fine
!!! the patch_dir is supposed to contain all patches of an image(no matter blured or not)
!!! you may want to use os.walk
!!! if so avoid to have any other .jpg file except image patches(e.g. do not save the whole image in .jpg in that folder)
:param patch_dir: [string] directory to the folder that contains all patches(of an image)
:return: [3-d array] whole image in np array
'''
patch_dir = patch_dir
pi_imgs = []
valid_images = [".jpg"]
for f in os.listdir(patch_dir):
ext = os.path.splitext(f)[1]
if ext.lower() not in valid_images:
continue
pi_imgs.append(Image.open(os.path.join(patch_dir, f)))
total = len(pi_imgs)
print(str(len(pi_imgs)) + " patches in total")
#######################################################
"""Loading all the images from directory"""
dir = []
valid_images = [".jpg"]
for f in os.listdir(patch_dir):
ext = os.path.splitext(f)[1]
if ext.lower() not in valid_images:
continue
dir.append(os.path.join(patch_dir, f))
#####################################################
"""concat images with numpy"""
def concat_img_horizon(list_imgs):
imgs = [PIL.Image.open(i) for i in list_imgs]
# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)
min_shape = sorted([(np.sum(i.size), i.size) for i in imgs])[0][1]
#
imgs_comb = np.hstack((np.asarray(i.resize(min_shape)) for i in imgs))
imgs_comb = PIL.Image.fromarray(imgs_comb)
return imgs_comb
def concat_img_vertical(list_imgs):
imgs = [PIL.Image.open(i) for i in list_imgs]
# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)
min_shape = sorted([(np.sum(i.size), i.size) for i in imgs])[0][1]
imgs_comb = np.hstack((np.asarray(i.resize(min_shape)) for i in imgs))
# for a vertical stacking it is simple: use vstack
imgs_comb = np.vstack((np.asarray(i.resize(min_shape)) for i in imgs))
imgs_comb = PIL.Image.fromarray(imgs_comb)
return imgs_comb
def concat_temp_horizon(list_imgs):
imgs_comb = np.hstack((np.asarray(i) for i in list_imgs))
imgs_comb = PIL.Image.fromarray(imgs_comb)
return imgs_comb
#########################################################
"""counting number of whole pictures in the folder"""
max_index = 0
for i in range(len(dir)):
flag = int(dir[i].split("/")[-1].split(",")[0].split("_")[0])
if flag > max_index:
max_index = flag
#############################################
"""placing patches to their certain picture"""
pic_index = {}
for elem in range(max_index + 1):
pic_index[elem] = []
for j in range(len(dir)):
for k in range(len(pic_index)):
if int(dir[j].split("/")[-1].split(",")[0].split("_")[0]) == k:
pic_index[k].append(dir[j])
print('the first picture contains ' + str(len(pic_index[0])) + ' patches')
##########################################
"""getting the total columns of picture"""
def get_total_column(list):
max_col = 0
for l in range(len(list)):
col_flag = int(pic_index[0][l].split("/")[-1].split(",")[0].split("_")[1])
if col_flag > max_col:
max_col = col_flag
return max_col
print ("this picture's total column is " + str(get_total_column(pic_index[0])))
#########################################
"""getting the total rows of picture"""
def get_total_row(list):
max_row = 0
for o in range(len(list)):
row_flag = int(list[o].split("/")[-1].split(",")[0].split("_")[2])
if row_flag > max_row:
max_row = row_flag
return max_row
print ("this picture's total row is " + str(get_total_row(pic_index[0])))
########################################
"""sorting this picture's patches with order of name"""
def sort_picture_patches(list):
return natsorted(list)
#####################################
"""doing global merging"""
for a in range(len(pic_index)):
max_col = get_total_column(pic_index[a])
max_row = get_total_row(pic_index[a])
pic_index[a] = sort_picture_patches(pic_index[a])
col_index = {}
for elem in range(max_col + 1):
col_index[elem] = []
for j in range(len(pic_index[a])):
for k in range(max_col):
if int(pic_index[a][j].split("/")[-1].split(",")[0].split("_")[1]) == k:
col_index[k].append(pic_index[a][j])
saver = []
for i in range(max_col - 1):
flag = concat_img_vertical(col_index[i])
saver.append(flag)
res = concat_temp_horizon(saver)
img = PIL.Image.open(res).convert("L")
arr = np.array(img)
return arr
def mass_patch_merge_to_one_from_folder(patch_dir,save_dir):
'''
After implementing the merging patches back to a whole image,
we can also do that same thing to a folder that contains several patches that
come from different images and merge and save them back to those original images (with partially
blurry) based on the naming habit of slicing images.
:param patch_dir: [string] directory to the folder that contains all patches(of an image)
:param save_dir: [string] directory to the folder that used to save all those merged images
:return: This time there's no return
'''
patch_dir = patch_dir
result_dir = save_dir
pi_imgs = []
valid_images = [".jpg"]
for f in os.listdir(patch_dir):
ext = os.path.splitext(f)[1]
if ext.lower() not in valid_images:
continue
pi_imgs.append(Image.open(os.path.join(patch_dir, f)))
total = len(pi_imgs)
print(str(len(pi_imgs)) + " patches in total")
#######################################################
"""Loading all the images from directory"""
dir = []
valid_images = [".jpg"]
for f in os.listdir(patch_dir):
ext = os.path.splitext(f)[1]
if ext.lower() not in valid_images:
continue
dir.append(os.path.join(patch_dir, f))
#####################################################
"""concat images with numpy"""
def concat_img_horizon(list_imgs):
imgs = [PIL.Image.open(i) for i in list_imgs]
# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)
min_shape = sorted([(np.sum(i.size), i.size) for i in imgs])[0][1]
#
imgs_comb = np.hstack((np.asarray(i.resize(min_shape)) for i in imgs))
imgs_comb = PIL.Image.fromarray(imgs_comb)
return imgs_comb
def concat_img_vertical(list_imgs):
imgs = [PIL.Image.open(i) for i in list_imgs]
# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)
min_shape = sorted([(np.sum(i.size), i.size) for i in imgs])[0][1]
imgs_comb = np.hstack((np.asarray(i.resize(min_shape)) for i in imgs))
# for a vertical stacking it is simple: use vstack
imgs_comb = np.vstack((np.asarray(i.resize(min_shape)) for i in imgs))
imgs_comb = PIL.Image.fromarray(imgs_comb)
return imgs_comb
def concat_temp_horizon(list_imgs):
imgs_comb = np.hstack((np.asarray(i) for i in list_imgs))
imgs_comb = PIL.Image.fromarray(imgs_comb)
return imgs_comb
#########################################################
"""counting number of whole pictures in the folder"""
max_index = 0
for i in range(len(dir)):
flag = int(dir[i].split("/")[-1].split(",")[0].split("_")[0])
if flag > max_index:
max_index = flag
#############################################
"""placing patches to their certain picture"""
pic_index = {}
for elem in range(max_index + 1):
pic_index[elem] = []
for j in range(len(dir)):
for k in range(len(pic_index)):
if int(dir[j].split("/")[-1].split(",")[0].split("_")[0]) == k:
pic_index[k].append(dir[j])
print('the first picture contains ' + str(len(pic_index[0])) + ' patches')
##########################################
"""getting the total columns of picture"""
def get_total_column(list):
max_col = 0
for l in range(len(list)):
col_flag = int(pic_index[0][l].split("/")[-1].split(",")[0].split("_")[1])
if col_flag > max_col:
max_col = col_flag
return max_col
print ("this picture's total column is " + str(get_total_column(pic_index[0])))
#########################################
"""getting the total rows of picture"""
def get_total_row(list):
max_row = 0
for o in range(len(list)):
row_flag = int(list[o].split("/")[-1].split(",")[0].split("_")[2])
if row_flag > max_row:
max_row = row_flag
return max_row
print ("this picture's total row is " + str(get_total_row(pic_index[0])))
########################################
"""sorting this picture's patches with order of name"""
def sort_picture_patches(list):
return natsorted(list)
#####################################
"""doing global merging"""
for a in range(len(pic_index)):
max_col = get_total_column(pic_index[a])
max_row = get_total_row(pic_index[a])
pic_index[a] = sort_picture_patches(pic_index[a])
col_index = {}
for elem in range(max_col + 1):
col_index[elem] = []
for j in range(len(pic_index[a])):
for k in range(max_col):
if int(pic_index[a][j].split("/")[-1].split(",")[0].split("_")[1]) == k:
col_index[k].append(pic_index[a][j])
saver = []
for i in range(max_col - 1):
flag = concat_img_vertical(col_index[i])
saver.append(flag)
res = concat_temp_horizon(saver)
res.save(result_dir + str(a) + '.jpg')
def image_to_patch(image_path, patch_size, patch_dir):
'''
cut an image into patch with certain size
!!! Sibo, please complete this function !!!
:param image_path: [string] path to the image(e.g. ./whole_image.jpg)
:param patch_size: [tuple] i.g. (30(length),30(witch))
:param patch_dir: [string] dir where to save the patch dir.(patch dir is defined to be the folder that contains all
image patches of an image)
:return:
'''
img = Image.open(image_path)
(imageWidth, imageHeight) = img.size
gridx = patch_size
gridy = patch_size
rangex = img.width / gridx
rangey = img.height / gridy
print rangex * rangey
for x in xrange(rangex):
for y in xrange(rangey):
bbox = (x * gridx, y * gridy, x * gridx + gridx, y * gridy + gridy)
slice_bit = img.crop(bbox)
slice_bit.save(patch_dir + str(x) + '_' + str(y) + '.jpg', optimize=True,
bits=6)
print(patch_dir + str(x) + '_' + str(y) + '.jpg')
print(imageWidth)
def directory_to_patch(patch_size,original_path,no_blur_path,blur_path,all_img_path):
'''
We take a directory that contains several whole pictures and cut then into custom size of patches,
then apply 50% chance blur and non-blur to those patches, save them into blurry folder, non-blurry folder,
and a folder that contains all blurry and non-blurry patches with order.
:param patch_size: [integer] The custom patch size we want, e.g:for 30x30 patch, enter '30'
:param original_path: [string] The original path that contains all the original pictures without any modification
:param no_blur_path: [string] The destination path that contains all the non-blurry patches with order
:param blur_path: [string] The destination path that contains all the blurry patches with order
:param all_img_path: [string] The destination path that contains all the patches with order
:return: There's no return in this function, all the modified patches are saved into the destination path
'''
#motion blur preset
size = 15
gridx = patch_size
gridy = patch_size
kernel_motion_blur = np.zeros((size, size))
kernel_motion_blur[int((size - 1) / 2), :] = np.ones(size)
kernel_motion_blur = kernel_motion_blur / size
# go through every image in source folder
print('begin loading images')
pi_imgs = []
cv_imgs = []
valid_images = [".jpg"]
for f in os.listdir(original_path):
ext = os.path.splitext(f)[1]
if ext.lower() not in valid_images:
continue
pi_imgs.append(Image.open(os.path.join(original_path, f)))
cv_imgs.append(cv2.imread(os.path.join(original_path, f)))
print('finished loading images')
#
# looping to create blurry and non-blurry images in 50% chance
for i in range(len(pi_imgs)):
img = pi_imgs[i]
(imageWidth, imageHeight) = img.size
rangex = imageWidth / gridx
rangey = imageHeight / gridy
for x in xrange(rangex):
for y in xrange(rangey):
bbox = (x * gridx, y * gridy, x * gridx + gridx, y * gridy + gridy)
slice_bit = img.crop(bbox)
if random.randrange(2) == 0:
slice_bit.save(no_blur_path + str(i) + '_' + str(x) + '_' + str(y) + ',noblur.jpg', optimize=True,
bits=6)
slice_bit.save(all_img_path + str(i) + '_' + str(x) + '_' + str(y) + ',noblur.jpg', optimize=True,
bits=6)
print(str(i))
else:
slice_bit.save(blur_path + str(i) + '_' + str(x) + '_' + str(y) + ',blur.jpg', optimize=True, bits=6)
img1 = cv2.imread(blur_path + str(i) + '_' + str(x) + '_' + str(y) + ',blur.jpg')
output = cv2.filter2D(img1, -1, kernel_motion_blur)
cv2.imwrite(blur_path + str(i) + '_' + str(x) + '_' + str(y) + ',blur.jpg', output)
cv2.imwrite(all_img_path + str(i) + '_' + str(x) + '_' + str(y) + ',blur.jpg', output)
print(str(i))