InsightSoftwareConsortium / ITKColorNormalization

Structure preserving color normalization on H&E images using a reference image
Apache License 2.0
18 stars 5 forks source link

[Feature request] Provide python wrapper / implementation to obtain stain matrix and concentrations only from image #39

Open guillermojp opened 2 years ago

guillermojp commented 2 years ago

Hi all,

First of all, great work with this package! It is amazing how fast it can work and produce stain normalization, great work!

A bit of background: I have been working on H&E stain images with large TIFF files, and I've found that, in my case, I need a more convolved preprocessing for my images. The preprocessing I want to apply consists in obtaining the stain matrix from each individual patch in a large TIFF file, and using these partial stain matrices to obtain a global stain matrix to obtain the final concentrations. The issue with usual preprocessing is that neighboring patches (or windows) are mapped to the same target image but have different characteristics in terms of distribution of tissue (e.g. some patch might have a larger nuclei count, which is bound to have an impact on the stain matrix and produce some artifacts when normalizing neighboring patches):

download (4)

However, all implementations I could find "hide" these intermediate steps in other functions, as they usually have wrappers that take a source and a target image and produce the final output without a chance to obtain the intermediate results: the concentration maps before going back to the RGB space and the stain matrix associated to a specific image patch.

I think it would be useful to "expose" these methods to be public (i.e. the result from the dictionary learning for obtaining the stain matrix and the lasso implementation to obtain the concentration maps). Still have the function / filter structure_preserving_color_normalization_filter but also provide two extra functions:

1) A function which takes an image and obtains a stain matrix (e.g. def structure_preserving_stain_matrix_extractor(image: np.ndarray) -> np.ndarray) 2) A function which takes an image and a stain matrix and obtains the concentration maps (e.g. def structure_preserving_concentration_extractor(image: np.ndarray, stain_matrix: np.ndarray, index_hematoxylin: int = 0, index_eosin: int = 1) -> Tuple[np.ndarray, np.ndarray]

I truly believe this would be useful, as your implementation is extremely fast and efficient (again, great work!).

Thanks, Guille

dzenanz commented 2 years ago

This feature request seems somewhat related to #32 (its superset).

Leengit commented 2 years ago

@guillermojp Thank you for your comment. Yes, I think this would make a nice addition to the current functionality. Unfortunately, I don't have the resources to pursue this at this time. However, if you or another wants to embark on this, I'd gladly offer advice and reviews.