Defining ROI and measuring the area of ROI

Hi, I’m writing a script to define cells labeled by two different markers in fluorescence, the original question in Google group is here!msg/qupath-users/ThpSjmKF8xw/REa80DVQBwAJ Now I can detect the overlapped ROI in two different detections, but some of them are too small to be a real signal. I want to filter these ROIs based on their areas. But I cannot define the ROIs and I cannot measure them. Do you know if there is a good way to define the ROIs? You also can show me in python.

Here is the script:

// Load required packages
import qupath.lib.common.GeneralTools
import qupath.lib.objects.PathAnnotationObject
import qupath.lib.objects.PathDetectionObject;
import qupath.lib.roi.PathROIToolsAwt
import java.awt.Rectangle
import java.awt.geom.Area

// Remove all object in the annotation
getAnnotationObjects().each{it.each{ removeObjects(it.getChildObjects(), true) }}

// Detect cells of the first type
runPlugin(‘qupath.imagej.detect.cells.WatershedCellDetection’, ‘{“detectionImageFluorescence”: 1, “backgroundRadius”: 15.0, “medianRadius”: 0.0, “sigma”: 3.0, “minArea”: 200.0, “maxArea”: 900.0, “threshold”: 10.0, “watershedPostProcess”: true, “cellExpansion”: 0.1, “includeNuclei”: true, “smoothBoundaries”: true, “makeMeasurements”: true}’);
def detections1 = getCellObjects()
print ‘Detection 1 Done’

// Detect cells of the second type
// The displayed results will overwrite results from the first detection.
runPlugin(‘qupath.imagej.detect.cells.WatershedCellDetection’, ‘{“detectionImageFluorescence”: 2, “backgroundRadius”: 15.0, “medianRadius”: 0.0, “sigma”: 4.0, “minArea”: 100.0, “maxArea”: 900.0, “threshold”: 10.0, “watershedPostProcess”: true, “cellExpansion”: 0.1, “includeNuclei”: true, “smoothBoundaries”: true, “makeMeasurements”: true}’);
def detections2 = getCellObjects()
print ‘Detection 2 Done!’

// For each cell in the first detection group, check whether
// the cell interacts with cells from the second detection group.
intersected_cells =

for (cell1 in detections1) {
def cell1_roi = cell1.getROI()

for (cell2 in detections2) {
    def cell1_area = PathROIToolsAwt.getArea(cell1_roi)
    def cell2_roi = cell2.getROI()
    def cell2_area = PathROIToolsAwt.getArea(cell2_roi)

    def intersected_roi = PathROIToolsAwt.getShapeROI(cell1_area, cell1_roi.getC(), cell1_roi.getZ(), cell1_roi.getT())
    def intersected_cell = new PathDetectionObject(intersected_roi)
    intersected_cells << intersected_cell

// print measurement(intersected_cell, “Cell: Area”)

// Show the overlapping cells
getAnnotationObjects().each{it.each{ removeObjects(it.getChildObjects(), true) }}
print intersected_cells.size()


It looks like you are defining the overlap between any two cell objects. “interesected_roi” should have an area value if you use
though to make it more meaningful you will want to multiply that by the pixel size, since it is returned in pixels.

You can then use an if statement to check if it is over a certain um^2 before adding it to the intersected_cells list. Or handle things in pixels.

It also looks like you are returning the rois as blank detection objects. It might make it easier down the line to do something like

new PathDetectionObject(intersected_roi, getPathClass("Overlap"))

Not 100% sure if that was what you were asking for, but hopefully it is in the right ballpark.

Thank you for your help! Now I can define the intersected ROI and extract the ROI I need! That means, I can detect the cells expressing two markers at the same time, this saves a lot of time! Many thanks! Now I have a small question, since now I can process the pictures in batch, can you tell me how to use code to open the images and select the annotations in batch(I just need to select the whole picture as one annotation all the time)?

Thanks again! I really appreciate your help!

If you mean something like a large rectangle around the entire image that is pre-selected, you can use:
True means that it is selected, so you could immediately run cell detection after this line.

You can also use clearAllObjects() to sanitize the hierarchy if you plan on running the script multiple times.