QuPath_StarDis tmodel

Hi All,
I am applying the Startdist_model he_heavy_augument script and it is making detection only for annotations that are very small. When I run it on bigger annotation, detections are not made. Is thgere a way I can go around this? below is the script I tried.
I I would like to know how I can modify this cript to be able to automatically select annotations for batch processing.


import qupath.tensorflow.stardist.StarDist2D

// Specify the model directory (you will need to change this!)
def pathModel = 'E:/_B/Scripts/StarDist/he_heavy_augment'

def stardist = StarDist2D.builder(pathModel)
        .threshold(0.1)              // Prediction threshold
        .normalizePercentiles(1, 99) // Percentile normalization
        .pixelSize(0.5)              // Resolution for detection
        .cellExpansion(0.5)          // Approximate cells based upon nucleus expansion
        .cellConstrainScale(1.5)     // Constrain cell expansion using nucleus size
        .measureShape()              // Add shape measurements
        .measureIntensity()          // Add cell measurements (in all compartments)
        .includeProbability(true)    // Include prediction probability as measurement
        .build()

// Run detection for the selected objects
def imageData = getCurrentImageData()
def pathObjects = getSelectedObjects()
if (pathObjects.isEmpty()) {
    Dialogs.showErrorMessage("StarDist", "Please select a parent object!")
    return
}
stardist.detectObjects(imageData, pathObjects)
println 'Done!'

Hi @Terfa, please do format your code as code when posting on the forum (</> option)! Also, it helps to explain more about what is going on.
I think your other question was answered in this thread: Save stardist detections back to project - #4 by Research_Associate

For example, @petebankhead
Using 0.3.0 snapshot (updated last week, so may not be the newest), and the code below

import qupath.tensorflow.stardist.StarDist2D

// Specify the model directory (you will need to change this!)
def pathModel = 'F:\\stardist\\QuPath Models\\he_heavy_augment'

def stardist = StarDist2D.builder(pathModel)
      .threshold(0.5)              // Prediction threshold
      .normalizePercentiles(1, 99) // Percentile normalization
      .pixelSize(0.5)              // Resolution for detection
      .build()

// Run detection for the selected objects
def imageData = getCurrentImageData()
def pathObject = getSelectedObject()
if (pathObject == null) {
  Dialogs.showErrorMessage("StarDist", "Please select a parent object!")
  return
}
stardist.detectObjects(imageData, pathObject, true)
println 'Done!'

On CMU-1.svs with the following area:
image

I am getting the following error

INFO: Starting script at Sat Apr 24 11:47:11 PDT 2021
INFO: TensorFlow version 2.4.1
INFO: Found SignatureDef: serving_default (method=tensorflow/serving/predict)
INFO: Loaded TensorFlow bundle: F:\stardist\QuPath Models\he_heavy_augment, (input=input:0 (-1, -1, -1, 3), output=concatenate_4/concat:0 (-1, -1, -1, 33))
ERROR: IllegalArgumentException at line 19: Points of LinearRing do not form a closed linestring

ERROR: org.locationtech.jts.geom.LinearRing.validateConstruction(LinearRing.java:93)
org.locationtech.jts.geom.LinearRing.(LinearRing.java:88)
org.locationtech.jts.geom.GeometryFactory.createLinearRing(GeometryFactory.java:382)
org.locationtech.jts.geom.GeometryFactory.createLinearRing(GeometryFactory.java:369)
org.locationtech.jts.geom.GeometryFactory.createPolygon(GeometryFactory.java:495)
qupath.tensorflow.stardist.StarDist2D.createNuclei(StarDist2D.java:890)
qupath.tensorflow.stardist.StarDist2D.detectObjectsForTile(StarDist2D.java:814)
qupath.tensorflow.stardist.StarDist2D.lambda$detectObjects$5(StarDist2D.java:687)
java.base/java.util.stream.ReferencePipeline$7$1.accept(Unknown Source)
java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(Unknown Source)
java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(Unknown Source)
java.base/java.util.stream.AbstractTask.compute(Unknown Source)
java.base/java.util.concurrent.CountedCompleter.exec(Unknown Source)
java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
java.base/java.util.concurrent.ForkJoinTask.doInvoke(Unknown Source)
java.base/java.util.concurrent.ForkJoinTask.invoke(Unknown Source)
java.base/java.util.stream.ReduceOps$ReduceOp.evaluateParallel(Unknown Source)
java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
qupath.tensorflow.stardist.StarDist2D.detectObjects(StarDist2D.java:688)
qupath.tensorflow.stardist.StarDist2D.detectObjectsImpl(StarDist2D.java:635)
qupath.tensorflow.stardist.StarDist2D.lambda$detectObjects$1(StarDist2D.java:574)
qupath.tensorflow.stardist.StarDist2D.runInPool(StarDist2D.java:600)
qupath.tensorflow.stardist.StarDist2D.detectObjects(StarDist2D.java:574)
qupath.tensorflow.stardist.StarDist2D$detectObjects$0.call(Unknown Source)
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:157)
Script7.run(Script7.groovy:20)
org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317)
org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:155)
qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:934)
qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:866)
qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:785)
qupath.lib.gui.scripting.DefaultScriptEditor$2.run(DefaultScriptEditor.java:1297)
java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
java.base/java.util.concurrent.FutureTask.run(Unknown Source)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
java.base/java.lang.Thread.run(Unknown Source)

I have tested a couple of times in the same area and got the same exact error… Also, the computer continues to utilize very high CPU % even after the script has apparently errored out.
image

Closing QuPath was necessary to free up the CPU.

@Research_Associate Thank you so much.
The command getAnnotationObjects() worked well for automatic selection of annotations.
The challenge remains runing the detection for bigger annotations as it keeps giving error.

I’m not sure if these are the same issue or different issues, but I think I need more info either way.

@Research_Associate is the error very specific to the region you’ve selected? I’d need a way to replicate the problem to understand what is wrong – either with instructions or a data file containing a problematic annotation.

@Terfa what exactly is the error you see? Copying and pasting the contents of View → Show log helps identify this.

It looks like any annotation that includes sufficient background on the sample image will work, but I haven’t been able to figure out what “sufficient” actually means.

The drawn annotation in the above image always triggers the error.
So does


image
image
image
Even just the following generated an error:
image

On the other hand
image
works, and
image
is fine, since it is a much smaller region.
Most empty spaces cause the error.

If you have CMU-1.svs open, the following script runs for a bit longer than the rest, but replicates the error each time for me.

size = 10000
def roi = ROIs.createRectangleROI(0, 22500, size, size, getCurrentViewer().getImagePlane())

def annotation = PathObjects.createAnnotationObject(roi)
addObject(annotation)

import qupath.tensorflow.stardist.StarDist2D

// Specify the model directory (you will need to change this!)
def pathModel = 'F:\\stardist\\QuPath Models\\he_heavy_augment'

def stardist = StarDist2D.builder(pathModel)
      .threshold(0.5)              // Prediction threshold
      .normalizePercentiles(1, 99) // Percentile normalization
      .pixelSize(0.5)              // Resolution for detection
      .build()

// Run detection for the selected objects
def imageData = getCurrentImageData()
def pathObjects = getAnnotationObjects()

pathObjects.each{pathObject->
    stardist.detectObjects(imageData, pathObject, true)
}
println 'Done!'

The Y coordinate can be set to 0 to make the script error out almost instantly. Same error as above each time so far. LinearRing.