Pixel Classifier and Cell detection

I am looking for an efficient way of detecting positive cells and running a pixelclassifier in a script. This works fine and sets every detection class to positive or negative:

runPlugin('qupath.imagej.detect.cells.PositiveCellDetection', '<big command>');

But it also detects in regions that are folds in my TMA-core. So I trained a pixel classifier that distinguishes tissue/fold/background. After this command:

def classifiers = project.getPixelClassifiers()
def classifier = classifiers.get('tissue_folds_ann_mlp')
imageData = getCurrentImageData()
PixelClassifierTools.classifyDetectionsByCentroid(imageData, classifier)

The positive/negative class is overwritten by the pixel classifier.
Is there a way to keep both?

At the moment I go over each detection after the pixelclassifier has ran and for the ones with the class ‘tissue’ I compare the DAB OD mean intensity of the cell with a threshold to redo what the celldetection already did before.

Is it possible to have more than one class?

There’s no easy way to change the behaviour of using a pixel classifier to classify objects at the moment.

However, if you can use the pixel classifier to define annotations before you detect your cells, then you can create annotations that exclude folds from the start. That way you don’t have to detect cells within the folds in the first place.

Alternatively, you might try using the ‘Measure’ option with the pixel classifier rather than ‘Classify’. That will add some information about the pixel classification to the cells themselves, so you could potentially incorporate that into object classification to distinguish the ‘cells’ that shouldn’t be there.

The second approach would be scriptable using something like this

def toRemove = getCellObjects().findAll {measurement(it, 'Classifier: Fold %') >= 50}
removeObjects(toRemove, true)

Hi Pete,

Thanks! Those are two good solutions for me.


1 Like

It seems I accidentally found a third way to do it that works after using StarDist for detection of the cells:

import qupath.opencv.ml.pixel.PixelClassifierTools
PixelClassifierTools.classifyDetectionsByCentroid(imageData, classifier)
def hierarchy = imageData.getHierarchy()
def detObjects = hierarchy.getDetectionObjects()
PathClassifierTools.setIntensityClassifications(detObjects, "DAB: Mean", threshold)

After running this script my detections have classes like:
‘Tissue: Positive’, ‘Tissue: Negative’, ‘Fold: Positive’, ‘Fold: Negative’

1 Like

@petebankhead Maybe I should make a seperate topic, but I got stuck on the next step.
When I click on Hierarchy my TMAcores have a set of Key-Value pairs.
Keys: [‘Image’, ‘Name’, ‘Missing’, etc.]
One of the keys is ‘Tissue: Positive %’ and I want to have that value in my script. But somehow I cannot find out how to do it. This is what I tried

def tmaCore = QP.getSelectedObject()
def measurementList = tmaCore.getMeasurementList()

But that returns an empty list.

I went for:

def childObjects=tmaCore.getChildObjects()
def p = childObjects.findAll{it.getPathClass().toString() == 'Tissue: Positive'}.size()
def n = childObjects.findAll{it.getPathClass().toString() == 'Tissue: Negative'}.size()

But is there a better way?