forked from wanghao14/Stain_Normalization
-
Notifications
You must be signed in to change notification settings - Fork 0
/
stainNorm_Vahadane.py
69 lines (53 loc) · 2.06 KB
/
stainNorm_Vahadane.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
"""
Stain normalization inspired by method of:
A. Vahadane et al., ‘Structure-Preserving Color Normalization and Sparse Stain Separation for Histological Images’, IEEE Transactions on Medical Imaging, vol. 35, no. 8, pp. 1962–1971, Aug. 2016.
Uses the spams package:
http://spams-devel.gforge.inria.fr/index.html
Use with python via e.g https://anaconda.org/conda-forge/python-spams
"""
from __future__ import division
import spams
import numpy as np
import stain_utils as ut
def get_stain_matrix(I, threshold=0.8, lamda=0.1):
"""
Get 2x3 stain matrix. First row H and second row E
:param I:
:param threshold:
:param lamda:
:return:
"""
mask = ut.notwhite_mask(I, thresh=threshold).reshape((-1,))
OD = ut.RGB_to_OD(I).reshape((-1, 3))
OD = OD[mask]
dictionary = spams.trainDL(OD.T, K=2, lambda1=lamda, mode=2, modeD=0, posAlpha=True, posD=True, verbose=False).T
if dictionary[0, 0] < dictionary[1, 0]:
dictionary = dictionary[[1, 0], :]
dictionary = ut.normalize_rows(dictionary)
return dictionary
###
class Normalizer(object):
"""
A stain normalization object
"""
def __init__(self):
self.stain_matrix_target = None
def fit(self, target):
target = ut.standardize_brightness(target)
self.stain_matrix_target = get_stain_matrix(target)
def target_stains(self):
return ut.OD_to_RGB(self.stain_matrix_target)
def transform(self, I):
I = ut.standardize_brightness(I)
stain_matrix_source = get_stain_matrix(I)
source_concentrations = ut.get_concentrations(I, stain_matrix_source)
return (255 * np.exp(-1 * np.dot(source_concentrations, self.stain_matrix_target).reshape(I.shape))).astype(
np.uint8)
def hematoxylin(self, I):
I = ut.standardize_brightness(I)
h, w, c = I.shape
stain_matrix_source = get_stain_matrix(I)
source_concentrations = ut.get_concentrations(I, stain_matrix_source)
H = source_concentrations[:, 0].reshape(h, w)
H = np.exp(-1 * H)
return H