H&E Histology Color Normalization Instructions
Manual color assignment using colorassign_manual.m
Process
colorassign_manual.m train_classifier.m color_classify.m color_normalize.m
Overview
The manual color assignment function is the first stage in the normalization process. Use a cropped sample of full size histological image that contains a good representation of each tissue structure. Using kmeans clustering, the sample will be reduced to 10 colors (this is a default but can be changed within the program). The user must then map each color to one of four tissue structures. The result is an indexed image and variables mapping each indexed value to one of the structures.
Inputs
rgb - A multidimensional array of size [MxNx3] where M and N represent the height and width of the image respectively. The third dimension of the data represents each color value (RGB).
Outputs
The function returns an array of size [MxN] where M and N represent the width and height of the image respectively. Each cell of the array contains an index of the color mapped to that pixel following a reduction down to a set number of colors, C.
In addition to the indexed image map, the function also returns arrays representing the color indexes associated with each histologic element. For example:
lumen = [1, 2]
stroma = [3, 4]
cytoplasm = [5, 6]
nuclei = [9, 10]
Explanation
The color assignment is the only function that requires manual human intervention. The goal of this function is to reduce the original image to a map that associates a subset of pixels in the image to a histologic element (like cell nuclei or stroma) using image indexing.
The function first reduces the number of colors in the input image to N using k-means clustering. By default, we’ve used 10 colors, a setting that usually captures most of the histologic information we need in most H&E images. But there may be some images that can benefit from more than 10 colors.

 
The reduced-color image is then presented in a GUI alongside a selection box for each of the ten colors.

 
Each color has a toggle-able "view" button. Enabling this will convert the chosen color to bright green in the slide in order to aid in identifying various patterns and shapes within the image. If a color proves to be too difficult to discern or represents multiple structures in the image, it is best to select "No response" as this will prevent structures from being misclassified.

The purpose of this GUI is to allow the user to associate each color with a histologic element. It is important to note that each structure (lumen/white, cytoplasm, stroma, and nuclei) must be associated with at least one color. Some histologic elements can be represented by multiple colors. Some colors, however, represent a mixture of histologic elements, so "No response" should be chosen.
N.B. The GUI has an option for RBC but a modification to the TREE value (see train_classifier.m) must be performed before it can be used.
Free Parameters
NCLUST = 10; % number of clusters
NCLUST represents the number of colors used in the color downsampling. 10 colors was arbitrarily picked as a reasonable number of colors to achieve classification of structures while retaining sufficient image detail. In some image sets more colors may be desirable. Altering this constant will require changes to the GUI in order to properly classify the image.
CLUSTERITER = 1e5; % maximum k-means iterations
Kmeans clustering is a heuristic that uses a random seed to begin working towards suitable planes to separate data in space. Each iteration improves the accuracy of the heuristic solution. The number of iterations, set by CLUSTERITER, has been chosen to be 100,000. This number can be changed without having to make other changes to the program though accuracy may not be significantly improved.
Example Usage
Using a saved tiff image
>> loadedImage = imread('/path/to/histology/image.tif')
>> [structureMap, lumen, nuclei, stroma, cytoplasm] = colorassign_manual(loadedImage)
Using Openslide
>> id = openslide_open('/path/to/histology/image.tif');
>> loadedimage = openslide_read_region(id,0);
>> loadedimage = loadedimage(:,:,1:3);
Timing
When processing a 1mm2 sample image of 2000x2000 pixels on a 2Ghz Intel i7 processor running with 8GB RAM, 1 minute and 43 seconds elapsed before the GUI presented.