Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Reconstructed RGB image with intensity values ranging from [0, 255],
suitable for display.
See Also
--------
histomicstk.preprocessing.color_deconvolution.complement_stain_matrix,
histomicstk.preprocessing.color_deconvolution.color_deconvolution
histomicstk.preprocessing.color_conversion.rgb_to_od
histomicstk.preprocessing.color_conversion.od_to_rgb
histomicstk.preprocessing.color_conversion.rgb_to_sda
histomicstk.preprocessing.color_conversion.sda_to_rgb
"""
# transform 3D input stain image to 2D stain matrix format
m = utils.convert_image_to_matrix(im_stains)
# transform input stains to optical density values, convolve and
# tfm back to stain
sda_fwd = color_conversion.rgb_to_sda(m, 255 if I_0 is not None else None,
allow_negatives=True)
sda_conv = np.dot(w, sda_fwd)
sda_inv = color_conversion.sda_to_rgb(sda_conv, I_0)
# reshape output, transform type
im_rgb = (utils.convert_matrix_to_image(sda_inv, im_stains.shape)
.clip(0, 255).astype(np.uint8))
return im_rgb
References
----------
.. [#] Van Eycke, Y. R., Allard, J., Salmon, I., Debeir, O., &
Decaestecker, C. (2017). Image processing in digital pathology: an
opportunity to solve inter-batch variability of immunohistochemical
staining. Scientific Reports, 7.
.. [#] Macenko, M., Niethammer, M., Marron, J. S., Borland, D.,
Woosley, J. T., Guan, X., ... & Thomas, N. E. (2009, June).
A method for normalizing histology slides for quantitative analysis.
In Biomedical Imaging: From Nano to Macro, 2009. ISBI'09.
IEEE International Symposium on (pp. 1107-1110). IEEE.
"""
# Image matrix
m = utils.exclude_nonfinite(utils.convert_image_to_matrix(im_sda))
# Principal components matrix
pcs = linalg.get_principal_components(m)
# Input pixels projected into the PCA plane
proj = pcs.T[:-1].dot(m)
# Pixels above the magnitude threshold
filt = proj[:, linalg.magnitude(proj) > minimum_magnitude]
# The "angles"
angles = _get_angles(filt)
# The stain vectors
def get_percentile_vector(p):
return pcs[:, :-1].dot(filt[:, argpercentile(angles, p)])
min_v = get_percentile_vector(min_angle_percentile)
max_v = get_percentile_vector(max_angle_percentile)
histomicstk.preprocessing.color_deconvolution.separate_stains_macenko_pca
References
----------
.. [#] Van Eycke, Y. R., Allard, J., Salmon, I., Debeir, O., &
Decaestecker, C. (2017). Image processing in digital pathology: an
opportunity to solve inter-batch variability of immunohistochemical
staining. Scientific Reports, 7.
.. [#] Xu, J., Xiang, L., Wang, G., Ganesan, S., Feldman, M., Shih, N. N.,
... & Madabhushi, A. (2015). Sparse Non-negative Matrix Factorization
(SNMF) based color unmixing for breast histopathological image
analysis. Computerized Medical Imaging and Graphics, 46, 20-29.
"""
# Image matrix
m = utils.convert_image_to_matrix(im_sda)
m = utils.exclude_nonfinite(m)
factorization = \
nimfa.Snmf(m, rank=m.shape[0] if w_init is None else w_init.shape[1],
W=w_init,
H=None if w_init is None else np_linalg.pinv(w_init).dot(m),
beta=beta)
factorization.factorize()
return htk_linalg.normalize(numpy.array(factorization.W))
"""
# complement stain matrix if needed
if numpy.linalg.norm(w[:, 2]) <= 1e-16:
wc = complement_stain_matrix(w)
else:
wc = w
# normalize stains to unit-norm
wc = normalize(wc)
# invert stain matrix
Q = numpy.linalg.inv(wc)
# transform 3D input image to 2D RGB matrix format
m = utils.convert_image_to_matrix(im_rgb)[:3]
# transform input RGB to optical density values and deconvolve,
# tfm back to RGB
sda_fwd = color_conversion.rgb_to_sda(m, I_0)
sda_deconv = numpy.dot(Q, sda_fwd)
sda_inv = color_conversion.sda_to_rgb(sda_deconv,
255 if I_0 is not None else None)
# reshape output
StainsFloat = utils.convert_matrix_to_image(sda_inv, im_rgb.shape)
# transform type
Stains = StainsFloat.clip(0, 255).astype(numpy.uint8)
# return
Unmixed = collections.namedtuple('Unmixed',
pathology." arXiv preprint arXiv:1902.06543 (2019).
.. [#] Implementation inspired by Peter Byfield StainTools repository. See
https://github.com/Peter554/StainTools/blob/master/LICENSE.txt
for copyright license (MIT license).
"""
# augment everything, otherwise only augment specific pixels
if mask_out is None:
keep_mask = np.zeros(StainsFloat.shape[:2]) == 0
else:
keep_mask = np.equal(mask_out, False)
keep_mask = np.tile(keep_mask[..., None], (1, 1, 3))
keep_mask = convert_image_to_matrix(keep_mask)
# transform 3D input stain image to 2D stain matrix format
m = convert_image_to_matrix(StainsFloat)
# transform input stains to optical density values
sda_fwd = rgb_to_sda(
m, 255 if I_0 is not None else None, allow_negatives=True)
# perturb concentrations in SDA space
augmented_sda = sda_fwd.copy()
for i in range(3):
alpha = np.random.uniform(1 - sigma1, 1 + sigma1)
beta = np.random.uniform(-sigma2, sigma2)
augmented_sda[i, keep_mask[i, :]] *= alpha
augmented_sda[i, keep_mask[i, :]] += beta
# convolve with stains column vectors and convert to RGB
sda_conv = np.dot(W, augmented_sda)
sda_inv = sda_to_rgb(sda_conv, I_0)
John-Melle Bokhorst, Francesco Ciompi, and Jeroen van der Laak.
"Quantifying the effects of data augmentation and stain color
normalization in convolutional neural networks for computational
pathology." arXiv preprint arXiv:1902.06543 (2019).
.. [#] Implementation inspired by Peter Byfield StainTools repository. See
https://github.com/Peter554/StainTools/blob/master/LICENSE.txt
for copyright license (MIT license).
"""
# augment everything, otherwise only augment specific pixels
if mask_out is None:
keep_mask = np.zeros(StainsFloat.shape[:2]) == 0
else:
keep_mask = np.equal(mask_out, False)
keep_mask = np.tile(keep_mask[..., None], (1, 1, 3))
keep_mask = convert_image_to_matrix(keep_mask)
# transform 3D input stain image to 2D stain matrix format
m = convert_image_to_matrix(StainsFloat)
# transform input stains to optical density values
sda_fwd = rgb_to_sda(
m, 255 if I_0 is not None else None, allow_negatives=True)
# perturb concentrations in SDA space
augmented_sda = sda_fwd.copy()
for i in range(3):
alpha = np.random.uniform(1 - sigma1, 1 + sigma1)
beta = np.random.uniform(-sigma2, sigma2)
augmented_sda[i, keep_mask[i, :]] *= alpha
augmented_sda[i, keep_mask[i, :]] += beta