Skip to content
This repository has been archived by the owner on May 8, 2021. It is now read-only.

Commit

Permalink
nearly done
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter554 committed Aug 1, 2018
1 parent 877abff commit d1d3072
Show file tree
Hide file tree
Showing 10 changed files with 450 additions and 665 deletions.
38 changes: 27 additions & 11 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ StainTools

Tools for tissue image stain normalization and augmentation in Python (tested on 3.5).

.. image:: https://i.imgur.com/sS8AKaV.png
:width: 95%
.. image:: https://i.imgur.com/PzY0fE7.png
:width: 95%

Install
========

Expand All @@ -16,26 +21,37 @@ Docs
Histology images are often stained with the Hematoxylin & Eosin (H&E) stains. These two chemicals typically stain: the nuclei a dark purple (Hematoxylin) and the cytoplasm a light pink (Eosin). Thus all pixels in a histology image are principally composed of two colors. These stain colors vary from image to image and may be summarised in a stain matrix:

.. math::
S = \left( \begin{array}{ccc}
S = \left(
\begin{array}{ccc}
H_R & H_G & H_B \\
E_R & E_G & E_B
\end{array} \right)
\end{array}
\right)
The first row of this matrix shows the Hematoxylin stain color in RGB. The second row of the matrix shows the Eosin stain color in RGB. Strictly speaking these RGB values should be interpreted in optical density space. We transform a normal RGB image to a RGB optical density image via the Beer-Lambert Law:

.. math::
I = 255 \times \exp(-OD)
If we flatten the OD image so that it is Npix x 3, with Npix = h x w and h and w the original image height and width, then we can relate the OD array and the stain matrix via the pixel concentration matrix C (a Npix x 2 array where the columns give the pixel concentration of H and E respectively):

The first
.. math::
OD_{flat} = C S
This package may be broken down as:
A :code:`StainExtractor` provides methods for estimating a stain matrix and a concentration matrix given an image. We implement:

**Stain Extraction**
- :code:`MacenkoStainExtractor`. Stain matrix estimation via method of *M. Macenko et al.,“A method for normalizing histology slides for quantitative analysis,”*. This method considers the projection of pixels onto the 2D plane defined by the two principle eigenvectors of the optical density covariance matrix. It then considers the extreme directions (in terms of angular polar coordinate) in this plane. See the paper for details.

A stain extractor provides methods for estimating a stain matrix and a concentration matrix given an image. We implement:
- :code:`VahadaneStainExtractor`. Stain matrix estimation via method of *A. Vahadane et al., “Structure-Preserving Color Normalization and Sparse Stain Separation for Histological Images,”*. This method takes a dictionary learning based approach to find the two basis stains that best fit the image. See the paper for details.

- Macenko stain extractor. Stain matrix estimation via method of *M. Macenko et al.,“A method for normalizing histology slides for quantitative analysis,”*. This method considers the projection of pixels onto the 2D plane defined by the two principle eigenvectors of the optical density covariance matrix. It then considers the extreme directions (in terms of angular polar coordinate) in this plane. See the paper for details.
In both cases the first step is to attempt to remove background pixels - pixels of the image where no tissue was present. In principle these should be just white light therefore we isolate tissue by a thresholding on the pixel luminosity. For some images that are dimly lit however the background is not bright enough and therefore it is recommended to standardize the brightness of any image first. For this we implement a :code:`BrightnessStandardizer`, which enforces an image to have at least 5% of pixels being luminosity saturated.
To understand this better it is recommended to see the demo notebook `demo_brightness_standardizer_and_luminosity_mask <https://github.com/Peter554/StainTools/blob/master/demo_brightness_standardizer_and_luminosity_mask.ipynb>`__.

- Vahadane stain extractor. Stain matrix estimation via method of *A. Vahadane et al., “Structure-Preserving Color Normalization and Sparse Stain Separation for Histological Images,”*. This method takes a dictionary learning based approach to find the two basis stains that best fit the image. See the paper for details.
Once we have the stain and concentration matrices we are able to easily carry out.

**Stain Normalizer**
- **Stain Normalization**. This basically involves casting one image in the stain colors of a target image. For this we basically decompose the images into the stain matrix S and the concentration matrix C, then replace the stain matrix of the image to be transformed with that of the target image. We then recombine to give the final stain normalized image. This is implemented in the class :code:`StainNormalizer`. See the demo notebook `demo_stain_normalizer <https://github.com/Peter554/StainTools/blob/master/demo_stain_normalizer.ipynb>`__ for an example.

A stain normalizer uses a stain extractor to transform one image to the staining of another target image.
- **Stain Augmentation**. For this we simply augment a single image by decomposing it into the stain matrix S and the concentration matrix C, perturbing the concentrations somewhat and the recombining to be get an augmented image. This is implemented in the class :code:`StainAugmentor`. See the demo notebook `demo_stain_augmentor <https://github.com/Peter554/StainTools/blob/master/demo_stain_augmentor.ipynb>`__ for an example.

For further examples of usage please see the demo notebooks (which serve also as tests by inspection).
We also implement a simpler color normalizer, the :code:`ReinhardColorNormalizer`, which normalizes images according to the method of *E. Reinhard, M. Adhikhmin, B. Gooch, and P. Shirley, ‘Color transfer between images’*. This method does not consider the details of stain matrices etc. Instead it simply maps the color distribution mean and standard deviation to match that of another target image. See the demo notebook `demo_reinhard_color_normalizer <https://github.com/Peter554/StainTools/blob/master/demo_reinhard_color_normalizer.ipynb>`__ for an example.

135 changes: 0 additions & 135 deletions demo_brightness_standardizer.ipynb

This file was deleted.

194 changes: 194 additions & 0 deletions demo_brightness_standardizer_and_luminosity_mask.ipynb

Large diffs are not rendered by default.

259 changes: 0 additions & 259 deletions demo_macenko_stain_normalizer.ipynb

This file was deleted.

227 changes: 227 additions & 0 deletions demo_stain_normalizer.ipynb

Large diffs are not rendered by default.

259 changes: 0 additions & 259 deletions demo_vahadane_stain_normalizer.ipynb

This file was deleted.

Empty file removed make_readme_pics.py
Empty file.
Binary file removed readme_pics/stain_matrix.png
Binary file not shown.
1 change: 1 addition & 0 deletions staintools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
from .reinhard_color_normalizer import ReinhardColorNormalizer

from .utils.brightness_standardizer import BrightnessStandardizer
from .utils.misc_utils import get_luminosity_mask
from .utils.visualization_utils import read_image, plot_image, \
plot_row_colors, make_image_stack, plot_image_stack
2 changes: 1 addition & 1 deletion staintools/reinhard_color_normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ReinhardColorNormalizer(object):
"""
Normalize a patch color to the target image using the method of:
E. Reinhard, M. Adhikhmin, B. Gooch, and P. Shirley,
‘Color transfer between images’, IEEE Computer Graphics and Applications, vol. 21, no. 5, pp. 34–41, Sep. 2001.
‘Color transfer between images’
"""

def __init__(self):
Expand Down

0 comments on commit d1d3072

Please sign in to comment.