Difficulty with HE cell detection on QuPath

Hi all,

I am trying to do some cell detection of hippocampal granule cells on H&E slides and could use some suggestions. Despite endless fiddling with cell detection parameters, thresholds, and stain separation, I am continuously getting back very rough and jagged outlines of the individual granule cells, that is if they are even detected at all against background. I have attached some images of the cell detections and set parameters, if anyone has any wisdom as to how to get a smoother cell outline (as I am interested in nucleus circularity and area data), it would be greatly appreciated.

Thank you!

Did you try the nuclei detection with StarDist?

Here is what I get on the image you attached.

You can probably cleanup the false nuclei with a few parameters via script.

Here is a link to information about using StarDist in QuPath, you will need to build the QuPath with TensorFlow.
https://qupath.readthedocs.io/en/latest/docs/advanced/stardist.html

2 Likes

I’ll second stardist, but want to point out (since you mentioned circularity) that stardist preferentially finds rounded objects, which may bias your data. The default model is something like 32 or 64 points smoothed around a roundish structure. I never did get around to training a version with a more detailed outline, though I kept thinking about it from time to time.

*Alternatively, H&E may not be the best option for something like this, and you may want to go with a histone marker, or collection of histone markers using IHC.

2 Likes

Yes, I do remember seeing your discussion somewhere.
Is this it?

1 Like

Great, thanks so much! I will give this a try

1 Like

I have been able to successfully use StarDist for cell detection and it is working quite well, however, when I look at the cell detection measurements there aren’t any. I added an “add shape measurements” script, however I am still not seeing any cell detection measurement data. Nuclear circularity and area are what I am after. Any advice?

You added shape but not intensity.

    .measureShape()              // Add shape measurements
    .measureIntensity()          // Add cell measurements (in all compartments)

Oh wait, I read too fast. Is that the whole script for what you are doing?

Also, if you are simply doing nuclei and not cells (nuclei plus a cytoplasm), try adding the shape measurements after. Analyze->Calculate Features->Add shape features.
You will need to select detections prior to doing this as this particular function will happily run on nothing without asking you to select something.
@petebankhead Was it intentional to omit the “select annotations/select detections/etc” popup dialog options for the new Add shape features?

1 Like

I don’t have a good answer for this – I don’t know what I was thinking when I wrote the command, but it does indeed seem like that popup should appear.

However, I’d try to avoid relying on Add shape features. I don’t understand why measureShape() isn’t enough to generate them – it works for me.

1 Like

measureShape() works for me as well.

1 Like

Yep, I have never had any problems with it either, but I am not sure about what steps were taken prior, or what the image tab might look like. I see that it is an SVS file, and I just saw another post where some percentage of SVS file were missing pixel metadata. I am wondering if there is some new version of SVS files that is causing weird problems intermittently.

Without a sample, hard to tell though.

There is also a random “s” at the end of the shown script, but I am guessing that was accidentally introduced later.

2 Likes

Not quite sure why measureShape() isn’t working, but add shape features is doing the job for now.

Also yes thank you ignore that accidental “s”.

1 Like

Final question (hopefully) to get this running to perfection- is there an addition I can make to the script to limit the cell detection to nuclei within a certain size range?

You can remove them afterwards.
https://gist.github.com/Svidro/33558ac3bd9f68a5ec2428f74550831f
Few examples there, but you will likely want something like

toRemove = getDetectionObjects().findAll{measurement(it, "Area µm^2") <10 || measurement(it, "Area µm^2")  > 500}
removeObjects(toRemove,true)

The text of the measurement you want to use needs to be exact, I was just guessing based on your initial image.

3 Likes

Amazing! Thanks so much for all your help.

3 Likes