Cell Count without hematoxylin staining

I have 3 colour stained IHC without hematoxylin staining, and would like to do cell quantification but I cannot get it work. I think there is a way to detect cells by colours and not sure how to ad script for it. I am quiet new to this and any suggestion would be much appreciated.
Thanks Ayse

There is an Optical Density option during cell detection, but without some sort of sample image showing what you are looking at, it is hard to make any specific recommendations. Too many different kinds of cells, stains, tissue, etc.

test high.tif (1.6 MB)
Thank you.
I have tried optical density as well but it does not segment cells properly. Attach is a sample that i will need to quantify each colours

Ah, no. Without some kind of nuclear stain, you don’t have a way to create cells. I think even CellProfiler with it’s greater amount of options would struggle with this. Cell membranes tend to touch, and so it is always difficult to find edges. That means you need some kind of nuclear signal to separate a “seed” for each cell.
QuPath is especially dependent on a nuclear signal, as that is what the Cell Detection command is based off of. The cytoplasmic expansion is blind.

Pixel classification is probably possible (assuming you are using the newest version) which will get you percentages of area positive for each stain.

Ahh ok, it will be challenging. How do you register the image type and is there any way that the number of colours can be quantified? Looks pretty good separated.

The image type, as long as it is some sort of brightfield, is irrelevant for the pixel classifier. I chose HDAB, but the classifier uses the base RGB values of the image. Don’t choose Fluorescence :slight_smile:
The number of colors is chosen by you and your training set. Essentially, N+1. In this case I chose three classes for annotations (bluish, DAB and purple) and the +1 is “Ignore*” which is a special class that gets ignored by the classifier.


One more note, I chose my regions rather haphazardly, and the ignore areas are much larger than my other training areas. It can be important to balance classes in the advanced menu.

Does this provide any number and also will this allow to do spatial analysis? Whenever I try pixel classification QuPath gets freeze. I use QuPath 0.0.2-m9 on mac.
Is there anyway that annotating some cell types and then QuPath does automatically?

When you are running the model, the numbers show up in the annotation tab if you have nothing selected. Alternatively, you can create objects based on the staining area with the “Create objects” button.

The pixel classifier can be slow and it is memory intensive. You may need to give QuPath more available memory or run it on a different computer. If you are getting error messages in your log (View->Show log) that might tell you more.

Not sure what your last line means.

Looks like if i set the image type as other and detecting cells in red channel does pretty good job. I wanted to modify the script that I saw in the previous correspondence of 5 colour ihc topic. I tried to change the Qupath language ( Groovy) to Javascript but there is not any option, any suggestion?

You can change the language to Javascript in the Script Editor in earlier versions, though I don’t recall any scripts being written that way. It doesn’t seem to exist in M9. I have never used it, so I’m not sure when it was removed.

Hi I have below error message and would appreciate with your sugesstions?

ERROR: Script error (MissingMethodException)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.callGlobal(GroovyScriptEngineImpl.java:399)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.access$100(GroovyScriptEngineImpl.java:90)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl$3.invokeMethod(GroovyScriptEngineImpl.java:303)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl$3.invokeMethod(GroovyScriptEngineImpl.java:292)
at groovy.lang.GroovyObjectSupport.invokeMethod(GroovyObjectSupport.java:44)
at groovy.lang.Script.invokeMethod(Script.java:77)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:70)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:156)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:184)
at Script1.run(Script1.groovy:117)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:155)
at qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:800)
at qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:734)
at qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:714)
at qupath.lib.gui.scripting.DefaultScriptEditor$2.run(DefaultScriptEditor.java:1130)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)

Most likely something in the script you are using does not match with the version you are using it in. Impossible for me to tell without more information.

I am quiet new to script… What sort of info you need and also is there any way detecting cells by colour for the above image?

If you copy/paste your script here, we can help you fix it!
You can use the ‘Preformatted text’ option in your post to format it to code (e.g. ‘this’ instead if ‘this’).

Thank you, here is the one that I wanted to use for detecting cells by colors.

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))

        else if (isPurple(r,g,b)) 

        else if (isTeal(r,g,b))

        else if (isRed(r,g,b)) 


isPurple, isBrown, etc… are not defined in your code, hence the error message.
You can either define them somewhere in your code:

boolean isBrown(double r, double g, double b) {
        return (r == 150 && g == 75 && b == 0)

boolean isPurple(double r, double g, double b) {
    return (r == 128 && g == 0 && b == 128)

boolean isTeal(double r, double g, double b) {
    return (r == 0 && g == 128 && b == 128)

boolean isRed(double r, double g, double b) {
    return (r == 255 && g == 0 && b == 0)

Note that I defined rgb values myself, so you probably will want to change them (in each return statement).

The other option is to simply put the values directly in your existing code (changing rgb values again from what I’ve written here to whatever you want):

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 (r == 150 && g == 75 && b == 0)

    else if (r == 128 && g == 0 && b == 128)

    else if (r == 0 && g == 128 && b == 128)

    else if (r == 255 && g == 0 && b == 0)
1 Like

Daniel Schmolze specifically stated in his post that he did not include the full script or the functions necessary for the script to run. You would need to create those on your own.

Link for others: https://github.com/qupath/qupath/issues/155#issuecomment-371327542

Also important to note that that script does not allow you to detect cells by color. Rather it classified cells based on their color… roughly speaking.

Thank you, it is what i would like to do. I have three colour staining and would like to classify them based on the colour that used for staining.

If it is only three colors, it is probably easiest to use Brightfield(OTHER) as your image type and define three color vectors representing your three colors.

Once you swap to Brightfield Other, you won’t be able to use Estimate stain vectors; you will have to use small annotations to target the specific colors and set them that way (Or figure out the stain vectors in Brightfield-HDAB and enter them manually, by text).