Package: itk-spcn
ITKColorNormalizationOverviewThisInsight Toolkit (ITK)module performs Structure Preserving Color Normalization on anH & Eimage using a reference image.  The module is in C++ and is also packaged forPython.H & E (hematoxylinandeosin) 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 inVahadane et al., 2016and modified inRamakrishnan 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 factorizationis 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 inArora et al., 2013and modified inNewberg 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 isLee Newberg.Try it onlineWe have set up a demonstration of this usingBinderthat anyone can try.  Click here:Installation for PythonITKColorNormalization and all its dependencies can be easily installed withPython wheels.  Wheels have been generated for macOS, Linux, and Windows and several versions of Python, 3.6, 3.7, 3.8, and 3.9.  If you do not want the installation to be to your current Python environment, you should first create and activate aPython virtual environment (venv)to work in.  Then, run the following from the command-line:pip install itk-spcnLaunchpython, import the itk package, and set variable names for the input imagesimportitkinput_image_filename="path/to/image_to_be_normalized"reference_image_filename="path/to/image_to_be_used_as_color_reference"Usage in PythonThe following example transforms this input imageusing the color scheme of this reference imageto produce this output imageFunctional interface to ITKYou can use the functional, eager interface to ITK to choose when each step will be executed as follows.  Theinput_imageandreference_imageare processed to producenormalized_image, which is theinput_imagewith the color scheme of thereference_image.  Thecolor_index_suppressed_by_hematoxylinandcolor_index_suppressed_by_eosinarguments are optional if theinput_imagepixel 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 interfaceAlternatively, you can use the ITK pipeline infrastructure that waits until a call toUpdate()orWrite()before executing the pipeline.  The functionitk.StructurePreservingColorNormalizationFilter.New()uses its argument to determine the pixel type for the filter; the actual image is not used there but is supplied with thespcn_filter.SetInput(0, input_reader.GetOutput())call.  As above, the calls toSetColorIndexSuppressedByHematoxylinandSetColorIndexSuppressedByEosinare 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 ifspcn_filteris used again with a differentinput_image, for example from a different reader,spcn_filter.SetInput(0,input_reader2.GetOutput())but thereference_imageis unchanged then the filter will use its cached analysis of thereference_image, which saves about half the processing time.