-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.py
110 lines (79 loc) · 3.18 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
"""Collection of functions for data augmentation of PIL images"""
import numpy as np
import numpy.random as random
from PIL import Image, ImageFilter
from skimage import color
import skimage
class RandomHEStain(object):
"""Transfer the given PIL.Image from rgb to HE, perturbate, transfer back to rgb """
def __call__(self, img):
img_he = skimage.color.rgb2hed(img)
img_he[:, :, 0] = img_he[:, :, 0] * random.normal(1.0, 0.02, 1) # H
img_he[:, :, 1] = img_he[:, :, 1] * random.normal(1.0, 0.02, 1) # E
img_rgb = np.clip(skimage.color.hed2rgb(img_he), 0, 1)
img = Image.fromarray(np.uint8(img_rgb*255.999))
return img
class RandomGaussianNoise(object):
"""Transfer the given PIL.Image from rgb to HE, perturbate, transfer back to rgb """
def __call__(self, img):
img = img.filter(ImageFilter.GaussianBlur(random.normal(0.0, 0.5, 1)))
return img
class HistoNormalize(object):
"""Normalizes the given PIL.Image"""
def __call__(self, img):
img_arr = np.array(img)
img_norm = normalize(img_arr)
img = Image.fromarray(img_norm)
return img
def normalize(image, target=None):
"""Normalizing function we got from the cedars-sinai medical center"""
if target is None:
target = np.array([[57.4, 15.84], [39.9, 9.14], [-22.34, 6.58]])
whitemask = color.rgb2gray(image)
whitemask = whitemask > (215 / 255)
imagelab = color.rgb2lab(image)
imageL, imageA, imageB = [imagelab[:, :, i] for i in range(3)]
# mask is valid when true
imageLM = np.ma.MaskedArray(imageL, whitemask)
imageAM = np.ma.MaskedArray(imageA, whitemask)
imageBM = np.ma.MaskedArray(imageB, whitemask)
## Sometimes STD is near 0, or 0; add epsilon to avoid div by 0 -NI
epsilon = 1e-11
imageLMean = imageLM.mean()
imageLSTD = imageLM.std() + epsilon
imageAMean = imageAM.mean()
imageASTD = imageAM.std() + epsilon
imageBMean = imageBM.mean()
imageBSTD = imageBM.std() + epsilon
# normalization in lab
imageL = (imageL - imageLMean) / imageLSTD * target[0][1] + target[0][0]
imageA = (imageA - imageAMean) / imageASTD * target[1][1] + target[1][0]
imageB = (imageB - imageBMean) / imageBSTD * target[2][1] + target[2][0]
imagelab = np.zeros(image.shape)
imagelab[:, :, 0] = imageL
imagelab[:, :, 1] = imageA
imagelab[:, :, 2] = imageB
# Back to RGB space
returnimage = color.lab2rgb(imagelab)
returnimage = np.clip(returnimage, 0, 1)
returnimage *= 255
# Replace white pixels
returnimage[whitemask] = image[whitemask]
return returnimage.astype(np.uint8)
def get_files(data_txt, check=None):
# get the contents of a file. i.e. train.txt to list
try:
files = []
with open(data_txt, "r") as f:
for item in f:
item = item.split("\n")[0]
if check:
if check in item:
files.append(item)
else:
files.append(item)
wsi_files = sorted(files)
return wsi_files
except IOError as e:
print("ERROR loading File {}".format(data_txt), e)
return