This performs structure preserving color normalization on an image using a reference image.
Project description
ITKColorNormalization
Overview
This Insight Toolkit (ITK) module performs Structure Preserving Color Normalization on an H & E image using a reference image. The module is in C++ and is also packaged for Python.
H & E (hematoxylin and eosin) are stains used to color parts of cells in a histological image, often for medical diagnosis. Hematoxylin is a compound that stains cell nuclei a purple-blue color. Eosin is a compound that stains extracellular matrix and cytoplasm pink. However, the exact color of purple-blue or pink can vary from image to image, and this can make comparison of images difficult. This routine addresses the issue by re-coloring one image (the first image supplied to the routine) using the color scheme of a reference image (the second image supplied to the routine). The technique requires that the images have at least 3 colors, such as red, green, and blue (RGB).
Structure Preserving Color Normalization is a technique described in Vahadane et al., 2016 and modified in Ramakrishnan et al., 2019. The idea is to model the color of an image pixel as something close to pure white, which is reduced in intensity in a color-specific way via an optical absorption model that depends upon the amounts of hematoxylin and eosin that are present. Non-negative matrix factorization is used on each analyzed image to simultaneously derive the amount of hematoxylin and eosin stain at each pixel and the image-wide effective colors of each stain.
The implementation in ITK accelerates the non-negative matrix factorization by choosing the initial estimate for the color absorption characteristics using a technique mimicking that presented in Arora et al., 2013 and modified in Newberg et al., 2018. This approach finds a good solution for a non-negative matrix factorization by first transforming it to the problem of finding a convex hull for a set of points in a cloud.
The lead developer of InsightSoftwareConsortium/ITKColorNormalization is Lee Newberg.
Installation for Python
ITKColorNormalization and all its dependencies can be easily installed with Python wheels. Wheels have been generated for macOS, Linux, and Windows and several versions of Python, 3.5, 3.6, 3.7, and 3.8. If you do not want the installation to be to your current Python environment, you should first create and activate a Python virtual environment (venv) to work in. Then, run the following from the command-line:
pip install itk-spcn
Launch python
, import the itk package, and set variable names for the input images
import itk
input_image_filename = 'path/to/image_to_be_normalized'
reference_image_filename = 'path/to/image_to_be_used_as_color_reference'
Usage in Python
The following example transforms this input image
using the color scheme of this reference image
to produce this output image
Functional interface to ITK
You can use the functional, eager interface to ITK to choose when each step will be executed as follows. The
input_image
and reference_image
are processed to produce normalized_image
, which is the input_image
with the
color scheme of the reference_image
. The color_index_suppressed_by_hematoxylin
and
color_index_suppressed_by_eosin
arguments are optional if the input_image
pixel type is RGB or RGBA. Here you are
indicating that the color channel most suppressed by hematoxylin is 0 (which is red for RGB and RGBA pixels) and that
the color most suppressed by eosin is 1 (which is green for RGB and RGBA pixels); these are the defaults for RGB and
RGBA pixels.
input_image = itk.imread(input_image_filename)
reference_image = itk.imread(reference_image_filename)
eager_normalized_image = itk.structure_preserving_color_normalization_filter(
input_image,
reference_image,
color_index_suppressed_by_hematoxylin=0,
color_index_suppressed_by_eosin=1)
itk.imwrite(eager_normalized_image, output_image_filename)
ITK pipeline interface
Alternatively, you can use the ITK pipeline infrastructure that waits until a call to Update()
or Write()
before
executing the pipeline. The function itk.StructurePreservingColorNormalizationFilter.New()
uses its argument to
determine the pixel type for the filter; the actual image is not used there but is supplied with the
spcn_filter.SetInput(0, input_reader.GetOutput())
call. As above, the calls to
SetColorIndexSuppressedByHematoxylin
and SetColorIndexSuppressedByEosin
are optional if the pixel type is RGB or
RGBA.
input_reader = itk.ImageFileReader.New(FileName=input_image_filename)
reference_reader = itk.ImageFileReader.New(FileName=reference_image_filename)
spcn_filter = itk.StructurePreservingColorNormalizationFilter.New(Input=input_reader.GetOutput())
spcn_filter.SetColorIndexSuppressedByHematoxylin(0)
spcn_filter.SetColorIndexSuppressedByEosin(1)
spcn_filter.SetInput(0, input_reader.GetOutput())
spcn_filter.SetInput(1, reference_reader.GetOutput())
output_writer = itk.ImageFileWriter.New(spcn_filter.GetOutput())
output_writer.SetInput(spcn_filter.GetOutput())
output_writer.SetFileName(output_image_filename)
output_writer.Write()
Note that if spcn_filter
is used again with a different input_image
, for example from a different reader,
spcn_filter.SetInput(0, input_reader2.GetOutput())
but the reference_image
is unchanged then the filter will use its cached analysis of the reference_image
, which
saves about half the processing time.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Hashes for itk_spcn-0.1.2-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 59f7497c55c7d07debcd0819c7972d28542c2a22201c8449c4b63923d0476f02 |
|
MD5 | 57d9d8c6860366fe1c851613dad3940e |
|
BLAKE2b-256 | cfbba71031bde5f98f7c85c72014373f64b6e51cde6bf347b4d5d0d714183d58 |
Hashes for itk_spcn-0.1.2-cp38-cp38-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3af1772e1e726c57088a477985cf590a0f8d9ffce2f88a725278106db89f3232 |
|
MD5 | 03d5ccf242a44e032624aab1d5000530 |
|
BLAKE2b-256 | 6631ed7c68b26238185d1896b3c16a586ef0454dcfa3c06a3ce8f6397d2d22aa |
Hashes for itk_spcn-0.1.2-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 084173e790652330caef764641d940488172207f5041699c560fc413f87a868a |
|
MD5 | 4137dc3919d2f5583f72319c3395ba4a |
|
BLAKE2b-256 | d4cc241a293caafccb11b539d2cf0579ccef2305c463eb3890322e23939a7fa0 |
Hashes for itk_spcn-0.1.2-cp37-cp37m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9005f9cb9e688592b55e3059b0402392c14fc5bfb9cfce7981ead55537dcd385 |
|
MD5 | 5c6d79af39ef6351394fc38d3af516be |
|
BLAKE2b-256 | f0d4b555bf107df1606f58ce28aeaf0cee745a2e50e1e4e6dce25b6d3dc847e1 |
Hashes for itk_spcn-0.1.2-cp37-cp37m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 40c69c0ca9878c4edae88e5de2c685f818885214f1904b874ff2723ff3add8c4 |
|
MD5 | 2cbb7850364baf8b8dfd4947d5466f5b |
|
BLAKE2b-256 | 5b984630c214fc86e074e09fca61edb6f3a84ffe0382577dea999394da3e37a5 |
Hashes for itk_spcn-0.1.2-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | eb9ef4d919dae7ba56157c60dc4000f59a98f905ec08acb6b843677fee8ed542 |
|
MD5 | c48f811e99841c6522aa7b126d0059cc |
|
BLAKE2b-256 | b00f3ddc8af16da8b4023ac0624b42bb83138b1c98bf2011ff135710de511ebf |
Hashes for itk_spcn-0.1.2-cp36-cp36m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fd846048c5df0818c890bf1fb78d325e347e7e352bd1a46dc4d6e24307373133 |
|
MD5 | 144f0b7b977c558b8057651171ae454c |
|
BLAKE2b-256 | ce97bc175c16c814ed5fef11db2a3e9a2f5d48dbde020bfcab71f254444dee70 |
Hashes for itk_spcn-0.1.2-cp36-cp36m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 082824dc551bcbc1e0fe12bff23d32c64b99fc2aeff1ae43245038659bbd7192 |
|
MD5 | 722081914adeea655d39f598cfb721d6 |
|
BLAKE2b-256 | 7044a144a697aff0380c3e8e2f7f257749372146c34686ea1a2b18126c9c4ad5 |
Hashes for itk_spcn-0.1.2-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e42460a0b4d1c971e39b1d24cc23cc13213a10712002f5232eb99568a6ad7e27 |
|
MD5 | 71c0d5d3287f7339e7d2c1dbc8b44098 |
|
BLAKE2b-256 | 9df4ccdcb592b810ce6f0434a2434ac1b105ac1a5550c28ba97f8aa0d993f69a |
Hashes for itk_spcn-0.1.2-cp35-cp35m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a9f33e28b3c6e11115f8ae3df661f18c0ab35ffe820c5401fe7af0671c647647 |
|
MD5 | a910810c90985bcf3a1a5bd8adbc58bc |
|
BLAKE2b-256 | bf37d18078b7fcea713de0b6ea0993f827b49c731dd1245bfba729bb1114ecd9 |
Hashes for itk_spcn-0.1.2-cp35-cp35m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f14bcd78b179bd87476969ada279c120c6722c0ef7ab18c2eb11e227c0f1fe05 |
|
MD5 | 35ced09292297163d9ecd573f8df7216 |
|
BLAKE2b-256 | 0f2c2c7aa0decf857c01ee50e15df9ab8c05a07bacce79388e532f21e21d4ce9 |
Hashes for itk_spcn-0.1.2-cp35-cp35m-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1124bd6e3dd827cb5f37440226c4bb5d2797930c1824f198225f789b8f35a289 |
|
MD5 | 0377cf4be2d23b3e0d14da630c8de2cc |
|
BLAKE2b-256 | 502bbaa9a322fc6b8fa86d81ef81ad21dde6d61edbe5bd715e97a5d5e0a6c56a |