Export cell boundaries

There’s lots of information in the docs, but lots more we haven’t had time to write up. A good starting point from the coding side is https://qupath.readthedocs.io/en/latest/docs/scripting/overview.html

1 Like

One thing you might consider then is using the ImageJ function for the Feret angle.


https://imagej.nih.gov/ij/docs/menus/analyze.html

Feret’s Diameter - The longest distance between any two points along the selection boundary, also known as maximum caliper. Uses the Feret heading. FeretAngle (0-180 degrees) is the angle between the Feret’s diameter and a line parallel to the x-axis of the image. MinFeret is the minimum caliper diameter. The starting coordinates of the Feret’s diameter ( FeretX and FeretY ) are also displayed. The DrawFeretDiameter macro draws the Feret’s diameter of the current selection.

Which can be applied in QuPath using a macro like:
https://gist.github.com/Svidro/68dd668af64ad91b2f76022015dd8a45#file-angles-for-cells-groovy

You can also get access to other ImageJ type Measurements through similar means, or other Feret values using positions in the list other than .getFeretValues()[1]. Make sure you read about what the angle actually means, as the fact that it is relative to the X axis means that almost horizontal cells can have angles of either ~0 or ~180, which can make analysis… weird.

//from Pete

import qupath.imagej.objects.*

getCellObjects().each {
    def ml = it.getMeasurementList()
    def roi = it.getNucleusROI()
    //for 0.1.2
    //def roiIJ = ROIConverterIJ.convertToIJRoi(roi, 0, 0, 1)
    roiIJ = IJTools.convertToIJRoi(roi, 0, 0, 1)
    def angle = roiIJ.getFeretValues()[1]
    ml.putMeasurement('Nucleus angle', angle)
    ml.close()
}
fireHierarchyUpdate()
print "done"

LuCa image with some arrows showing similarly aligned cell areas being the same color.

The results are also very heavily dependent on accurate nuclear segmentation, and in this case using StarDist for the nuclear segmentation was much more accurate (not shown, image above is normal Cell Detection segmentation).

1 Like

This looks very relevant! Thank you for pointing it out, I will definitely check this feature out. Thank you!

1 Like

Using StarDist to do segmentation is very inspiring. I spent some time building the QuPath, then add the tensorflow-cpu parameter. It’s all appear to be successful. However, in the script, when I tried to import qupath.tensorflow.stardist.StarDist2D, an error occured saying that the class doesn’t exist…why is that?

Please provide the exact error message and copy and paste in the script as you have it. Generally you would get that if you mistype the name somehow, or add an extra character.

Sometimes extra characters can be added when code is transferred in different ways. I just ran into a case of emailing a script where the email client adjusted the script “for safety.”

It is also possible that you did not run the version of QuPath that you think you did; can you verify that the extension exists in the Help menu?

Interesting, the extension does not exist in the Help menu. I do followed the instructions here: https://qupath.readthedocs.io/en/latest/docs/advanced/stardist.html. Maybe I missed something?

Are you sure you went and found the folder with the new version of QuPath, as per the instructions for building from Gradle? https://qupath.readthedocs.io/en/latest/docs/reference/building.html

1 Like

That’s the case…I do found and opened the new QuPath but I am actually operating on another one…thank you!

1 Like

Hi! as now I am able to implement Stardist to do segmentation, but the speed seems very slow when it comes to multiple TMA cores. I first selected all annotations and then run the script provided in the instruction, then my computer went crazy and I could not even kill the script…

@HAOYANG_MI it is certainly rather processor-intensive… do keep in mind all the warnings and caveats on the documentation page, and adapt your expectations for it accordingly :wink:

1 Like

And it looks like if you do have a GPU and gputools enabled, you will see a significant increase in speed (some other thread mentioned something like 30x faster). So very much computer and setup dependent.

Ah, here is the post: Training StarDist with gputools support

@petebankhead @Research_Associate Thank you. Also, looks like StarDist also capable of H-DAB image segmentation, how to achieve this? My though is to specifify the channel but failed.

1 Like

General cases for hematoxylin staining should be covered in the StarDist readthedocs page that you linked. You would need to give more details if you are having problems.

Other details of how to use the startdist scripts can be found on the forum if you search for stardist. For example:

I was trying to segment positive cells from H-DAB images just as this indicates:


But looks like I need to change some parameters or add some lines in the script mentioned in the readthedoc page, otherwise Stardist will segment all cells not only the positive cells.

Most cell detection algorithms are designed to detect all of the cells, so it sounds like it is doing what it is supposed to. If you want to later classify and remove detections, that is up to you, but most users will want all of the cells.

@HAOYANG_MI in that example, I only ran the pre-trained H&E model for StarDist – there’s nothing special in it for H-DAB, and no discrimination of positive/negative cells. It’s just robust enough to ‘see’ the nuclei anyway – but not in all cases.

1 Like

@petebankhead @Research_Associate Sorry to trouble again. In QuPath, is the boundary coordinate defined as the real ROI boundary coordinate or it’s actually the coordinate of the convex hull of the ROI?

What precisely do you mean with ‘boundary coordinate’?

Hi, I mean the coordinate can be found in the JSON file:

The coordinates you show should be from the ROI, not its convex hull.

2 Likes