Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding color deconvolution for tissue slides stained with H&E (haematoxylin and eosin) #7334

Open
GParolini opened this issue Mar 5, 2024 · 1 comment

Comments

@GParolini
Copy link
Contributor

Description:

The issue I am opening relates to the discussion in "Enhance gallery example on colour separation of stained tissues" #6333
I am working on tissue slides stained with H&E and I would welcome the opportunity to use the colour deconvolution module in scikit-image to separate the stains.
I looked into the code already available in scikit-image to separate H, E, and DAB and the example in the scikit-image gallery and tried to reproduce the case for just two stains. I used both the colour vectors for H&E given in Landini et al. and the colour vectors I could read in QuPath (H, E, Residual) to have a comparison. I do not have any biological training and I am unable to say which choice of H&E colour vector would lead in principle to better results in object detection, which is my ultimate goal. I would appreciate feedback and suggestions.
output2
output3
output4

One comment perhaps worth making is that currently the colour deconvolution module does not allow users to set their own colour vectors (at least this is my impression). Given the discussions by Landini, it would be useful for advanced users to have this option, at least for the H&E stains, I think.

# IMPLEMENTATION WITH H&E ONLY COLOUR VECTOR AVAILABLE IN FIJI COLOUR DECONVOLUTION JAR
from skimage._shared.utils import identity
from skimage.color.colorconv import separate_stains
from skimage.color.colorconv import combine_stains


rgb_from_he = np.array([[0.644211000, 0.716556000, 0.266844000],
                         [0.09278900, 0.95411100, 0.28311100],
                         [0.00000000, 0.00000000, 0.00000000]])
rgb_from_he = np.round(rgb_from_he, 3)

rgb_from_he[2, :] = np.cross(rgb_from_he[0, :], rgb_from_he[1, :])

he_from_rgb = linalg.inv(rgb_from_he)

rgb=identity(he_image)

def rgb2he(rgb, *, channel_axis=-1):
    return separate_stains(rgb, he_from_rgb)

def he2rgb(he, *, channel_axis=-1):
    return combine_stains(he, rgb_from_he)

# Example IHC image
ihc_rgb = he_image

# Separate the stains from the IHC image

ihc_he = rgb2he(ihc_rgb)


# Create an RGB image for each of the stains
null = np.zeros_like(ihc_he[:, :, 0])
ihc_h = he2rgb(np.stack((ihc_he[:, :, 0], null, null), axis=-1))
ihc_e = he2rgb(np.stack((null, ihc_he[:, :, 1], null), axis=-1))

# Display
fig, axes = plt.subplots(2, 2, figsize=(7, 6), sharex=True, sharey=True)
ax = axes.ravel()

ax[0].imshow(ihc_rgb)
ax[0].set_title("Original image")

ax[1].imshow(ihc_h)
ax[1].set_title("Hematoxylin (Fiji col. vect.)")

ax[2].imshow(ihc_e)
ax[2].set_title("Eosin (Fiji col. vect.)")  


for a in ax.ravel():
    a.axis('off')

fig.tight_layout()
@mkcor
Copy link
Member

mkcor commented Mar 13, 2024

Thanks for raising this issue, @GParolini! Unfortunately, I don't have a substantial background in biology either. Would you mind clarifying what you mean by "set their own colour vectors?" If we consider the separate_stains function, the second parameter is described as "The stain separation matrix as described by G. Landini [1]." Wouldn't this be somewhat related?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants