-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathutils.py
110 lines (94 loc) · 3.14 KB
/
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
import os
import time
import random
import numpy as np
import cv2
from tqdm import tqdm
import torch
from sklearn.utils import shuffle
""" Seeding the randomness. """
def seeding(seed):
random.seed(seed)
os.environ["PYTHONHASHSEED"] = str(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.backends.cudnn.deterministic = True
""" Create a directory. """
def create_dir(path):
if not os.path.exists(path):
os.makedirs(path)
""" Load the Kvasir-SEG dataset """
def load_data(path):
def load_names(path, file_path):
f = open(file_path, "r")
data = f.read().split("\n")[:-1]
images = [os.path.join(path,"images", name) + ".jpg" for name in data]
masks = [os.path.join(path,"masks", name) + ".jpg" for name in data]
return images, masks
train_names_path = f"{path}/train.txt"
valid_names_path = f"{path}/val.txt"
train_x, train_y = load_names(path, train_names_path)
valid_x, valid_y = load_names(path, valid_names_path)
return (train_x, train_y), (valid_x, valid_y)
""" Shuffle the dataset. """
def shuffling(x, y):
x, y = shuffle(x, y, random_state=42)
return x, y
def epoch_time(start_time, end_time):
elapsed_time = end_time - start_time
elapsed_mins = int(elapsed_time / 60)
elapsed_secs = int(elapsed_time - (elapsed_mins * 60))
return elapsed_mins, elapsed_secs
def print_and_save(file_path, data_str):
print(data_str)
with open(file_path, "a") as file:
file.write(data_str)
file.write("\n")
def rle_encode(x):
'''
x: numpy array of shape (height, width), 1 - mask, 0 - background
Returns run length as list
'''
dots = np.where(x.T.flatten()==1)[0] # .T sets Fortran order down-then-right
run_lengths = []
prev = -2
for b in dots:
if (b>prev+1): run_lengths.extend((b+1, 0))
run_lengths[-1] += 1
prev = b
return run_lengths
def rle_decode(mask_rle, shape):
'''
mask_rle: run-length as string formated (start length)
shape: (height,width) of array to return
Returns numpy array, 1 - mask, 0 - background
'''
s = mask_rle.split()
starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]
starts -= 1
ends = starts + lengths
img = np.zeros(shape[0]*shape[1], dtype=np.uint8)
for lo, hi in zip(starts, ends):
img[lo:hi] = 1
return img.reshape(shape)
""" Initial mask build using Otsu thresholding. """
def init_mask(images, size):
def otsu_mask(image, size):
img = cv2.imread(image, cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, size)
blur = cv2.GaussianBlur(img,(5,5),0)
ret, th = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
th = th.astype(np.int32)
th = th/255.0
th = th > 0.5
th = th.astype(np.int32)
return img, th
mask = []
for image in tqdm(images, total=len(images)):
name = image.split("/")[-1]
i, m = otsu_mask(image, size)
# cv2.imwrite(f"mask/{name}", np.concatenate([i, m*255], axis=1))
m = rle_encode(m)
mask.append(m)
return mask