Classify touching cells

Hi all,

I have a QuPath script finding cells in Channel 1 and cells in Channel 2 using the cell detection. Result is something like here (sorry I don’t have any real data with me currently):


Is there a way to classify if the cells in C1 are overlapping the ones in C2 ? And calculate how much is overlapping ?

Like for example the black one on the left would be positive and the black one on the right negative ?

Thanks a lot.

If you search this page for references to Java Topology Suite, you should find a way to convert a QuPath ROI into a Geometry. Then you have access to all the methods there, including ‘overlaps’.*

*-JTS is fantastically useful, although I do find it occasionally surprising… such as the behavior of ‘contains’ and ‘covers’ for objects that contains holes, and the fact that Geometries can be either valid or invalid. As far as I can tell, QuPath always converts to valid Geometries (I hope so… after some work to make this happen, I haven’t yet found a failing example) - but it’s good to check the validity, especially if you see something that looks weird.

There are also two scripts here that involve using “intersect.” I am not sure if this is worse now that Geometry is available (efficiency, etc), but I have never used those and I usually find it easier to go off of an example script I understand. However, I am guessing you would need to intersect every single cell from your red class and sum the results, or something like that, and then divide by the black cell area. And that is making the assumption that your red cells do not overlap.


And I just noticed, on the link to Pete’s blog, Thomas has created a script using Java Topology Suite in the comments, so maybe that would help.

Thanks Pete, I will try to use this now.

I guess Geometry corresponds to one annotation. Do you know if there’s a simple way to do it without loop through all the ROIs twice (one for the reference and then check with all other ROIs if overlap) ?

Thanks a lot as well to @Research_Associate, I guess the question also applies for intersect ? :slight_smile:

Thanks !

JTS allows you to create a spatial index containing lots of geometries, and then to query which ones overlap a specific bounding box (‘Envelope’).

You can do it yourself (for maximum confidence & control) or via QuPath’s hierarchy here - although I don’t recall off hand if this uses the full ROI for detections or just for annotations (and you’d definitely need to make sure the hierarchy is up-to-date… easiest way is to fire a hierarchy update event in your script before you need to do this).

However I should admit that since writing this I learned of some strangeness in the conversion to JTS Geometries, specifically whenever ROIs have holes or self-intersections (see here). My attempted workaround will be in the next milestone…

But this means that this is a fixed box and I would still need to loop through the object to each time create that box ?

You’d loop through the objects once to add all the envelopes to the spatial index first, then query the index as much you like afterwards. Thanks to the indexing, the query should generally be much more efficient than a loop that checks every possible object for overlaps… but you will still need to do your detailed overlap check for anything the query returns (because it may conservatively return close-but-not-quite-overlapping ROIs).

You can see my attempts to use a spatial index in PathObjectTileCache. This creates a separate index for different types of object (annotations, detections, cells…).

If you do get it working more efficiently in 0.2.0 I would be interested to see the results! In 0.1.2/3 it does sound a lot like this thread, which uses the less efficient (but already existing in script form) N^2 method.


I got it working with the slow and not optimal way thanks to the link you sent because of time constraint but if somebody ever has a working example using the spatial indexes, I’d also be interested in having a look.

Thanks both for your help !