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

multiplex ihc (5 colors), suggestions appreciated #155

Closed
schmolze opened this issue Mar 7, 2018 · 10 comments
Closed

multiplex ihc (5 colors), suggestions appreciated #155

schmolze opened this issue Mar 7, 2018 · 10 comments

Comments

@schmolze
Copy link

schmolze commented Mar 7, 2018

I'm working with some multiplex (brightfield) immunohistochemistry whole slide images that are stained with five colors (brown, purple, teal, red, black). Here's an example:

penta qupath 1

Analyze -> Cell analysis -> Cell detection does an acceptable job of identifying cells:

penta qupath 2

I would like to classify them by color, ideally with a script. I'm aware that QuPath doesn't have built-in support for multiple colors at this time. Also aware that Estimate stain vectors can be used to change what colors QuPath considers to be, for example, DAB. However, I don't think this would work for 5 colors.

I can loop through the detected cells no problem. Is it possible to extract mean pixel intensity separately for the red, green, and blue channels? Something like:

for (def cell: getCellObjects()) {

	double r = cell.getMeasurementList().getMeasurementValue("Cell: Mean Red Intensity")
	double g = cell.getMeasurementList().getMeasurementValue("Cell: Mean Green Intensity")
	double b = cell.getMeasurementList().getMeasurementValue("Cell: Mean Blue Intensity")
	
	if (isBrown(r,g,b)) {
		cell.setPathClass(Brown)
	}
	...
}

From getAvailableFeatures(getCellObjects()) it doesn't seem like it. Any other suggestions are much appreciated!

@petebankhead
Copy link
Member

That's a very nice image... not entirely sure how to work with it, but it looks great.

You could try using Analyze → Calculate features → Add intensity features (experimental).

For the parameters, I guess you would keep the region as ROI and possibly decrease the Preferred pixel size value because the ROIs will be small. (From memory, I believe the actual ROI used will be that of the cell, not the nucleus.)

You can then choose the features and color transforms you want, and can reuse these in an interactively-trained classifier if necessary.

Out of interest: do you know where the positive staining for each color is expected to be localized within the cell in each case, and do you expect double/triple etc. positive cells?

@petebankhead
Copy link
Member

One reason I ask is that, depending upon the expected localization, there might be an argument for making the intensity measurements in a very small circular/rectangular region at the highest resolution, so as to make a measurement just around the cell centroid - not across the full region.

The other reason is that I'm currently quite interested in adding the ability to detect different stains by providing sample colors - without any color deconvolution step. I'm not sure how relevant or helpful it would be here though.

@schmolze
Copy link
Author

schmolze commented Mar 7, 2018

Thanks Pete, I'll give that a shot.

They're all cytoplasmic stains, without any expected overlapping (thankfully!). I have quite a few of these multiplexed whole slide images, I can share if you think they would be useful for development testing.

@petebankhead
Copy link
Member

They certainly could be useful... I'd be interested to explore a bit if sharing is not a problem.

Under Brightness/Contrast, the Normalized OD color transform looks borderline helpful, but unfortunately not for black.

Optimistic question: Would area measurements of each individual stain be of any value? Or to be meaningful must the final readout be classified cell counts (or something else that's more difficult)?

@schmolze
Copy link
Author

schmolze commented Mar 7, 2018

Normalized OD color looks like it might be useful. Black is the least important and will be the hardest to accurately count I think (they are follicular dendritic cells with tentacle-like extensions, not a typical cell shape).

The final readout has to be classified cell counts unfortunately.

@schmolze
Copy link
Author

schmolze commented Mar 7, 2018

I've made some progress. After cell detection, I did Analyze → Calculate features → Add intensity features (experimental)., with a pixel size of 1 um. I chose Red, Green, and Blue, and Mean. Then the following code:

import qupath.lib.objects.classes.PathClass
import qupath.lib.objects.classes.PathClassFactory

def Brown = PathClassFactory.getPathClass("Brown")
def Red = PathClassFactory.getPathClass("Red")
def Purple = PathClassFactory.getPathClass("Purple")
def Teal = PathClassFactory.getPathClass("Teal")

def rmean = "ROI: 1.00 µm per pixel: Red:  Mean"
def gmean = "ROI: 1.00 µm per pixel: Green:  Mean"
def bmean = "ROI: 1.00 µm per pixel: Blue:  Mean"

for (def cell :getCellObjects()) {
        
        double r = cell.getMeasurementList().getMeasurementValue(rmean)
        double g = cell.getMeasurementList().getMeasurementValue(gmean)
        double b = cell.getMeasurementList().getMeasurementValue(bmean)
        
        if (isBrown(r,g,b))
            cell.setPathClass(Brown)

        else if (isPurple(r,g,b)) 
            cell.setPathClass(Purple)

        else if (isTeal(r,g,b))
            cell.setPathClass(Teal)

        else if (isRed(r,g,b)) 
            cell.setPathClass(Red)

}

the isBrown(), etc. functions just do some simple thresholding of the r,g,b values to decide what color a cell is stained. I'm still tweaking those functions, but it's working pretty well (white outlines are unclassified cells, the rest are outlined in the appropriate color):

5-plex snapshot

I think this will work well enough for my application (we'll be presenting this data as a platform presentation at USCAP in Vancouver in a couple weeks, if anyone is interested in multiplex IHC).

@Svidro
Copy link

Svidro commented Mar 8, 2018

As a side note, I don't know if Pete has already adjusted it in the new version, but I generally replace the micrometer symbol with
"ROI: 2.00 " + qupath.lib.common.GeneralTools.micrometerSymbol() + " per pixel: OD Sum: Mean"
since the mu symbol had problems in the scripting window for my (Windows) system upon closing and re-opening QuPath.

I have handled a few multicolor brightfield images, and heartily recommend having fun with more than just the RGB values using the estimated stain vectors. You can create as many measurements as you want to help distinguish your cells, and I have found this quite helpful at times to isolate one color (or eliminate red blood cells). If the RGB values are working for you, though, great! I would love to see what you end up with, or play with one of the images myself if you were willing to host it somewhere.

@schmolze
Copy link
Author

schmolze commented Mar 8, 2018

Thanks for the tips Svidro, I will definitely continue to play with these images. I'll try to get one uploaded somewhere soon as well.

@AAkarca
Copy link

AAkarca commented Apr 21, 2020

Hi, I have an image to analyse but do not have hematoxylin and wonder if I can do cell segmentation by using other colour detection? If yes then how can I change the script

@petebankhead
Copy link
Member

@AAkarca please use http://forum.image.sc/tag/qupath for questions.

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

4 participants