Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save petebankhead/bea34ee1716b67246c2308808dd3c025 to your computer and use it in GitHub Desktop.
Save petebankhead/bea34ee1716b67246c2308808dd3c025 to your computer and use it in GitHub Desktop.
Identify distinct clusters after using QuPath's 'Delaunay cluster features 2D' command
/**
* QuPath script to group together clusters identified with Delaunay clustering.
* This provides several options:
* - clusters as classifications
* - clusters as object names
* - clusters as measurement values
* You should comment out the lines you don't want.
*
* Note that this is *very* rough and not guaranteed to work.
* It was written for https://forum.image.sc/t/cell-classification-within-a-segmented-region-in-histology-images/55507/21?u=petebankhead
*
* Developed with v0.2.3 in mind (although written with v0.3.0 snapshot).
*
* @author Pete Bankhead
*/
import qupath.lib.objects.PathObject
import static qupath.lib.scripting.QP.*
def imageData = getCurrentImageData()
def hierarchy = imageData.getHierarchy()
// Get cells
def cells = getCellObjects()
// Extract Delaunay info (should have run clustering plugin already)
def connections = imageData.getProperties().get('OBJECT_CONNECTIONS')
// Assign labels to clusters
int label = 0
for (group in connections.getConnectionGroups()) {
def allObjects = group.getPathObjects() as Set
while (!allObjects.isEmpty()) {
def nextObject = allObjects.pop()
label++
def cluster = new HashSet()
def pending = [nextObject]
while (!pending.isEmpty()) {
nextObject = pending.pop()
addToCluster(group, nextObject, cluster, pending)
}
for (pathObject in cluster) {
// REMOVE THE OPTIONS YOU DON'T WANT!
// Show cluster as classification
pathObject.setPathClass(getPathClass("Cluster " + label))
// Show cluster as name
pathObject.setName("Cluster " + label)
// Add cluster as measurement (but don't use this in an object classifier!)
pathObject.getMeasurementList().putMeasurement("Cluster", label)
pathObject.getMeasurementList().close()
}
allObjects.removeAll(cluster)
}
}
fireHierarchyUpdate()
void addToCluster(group, pathObject, cluster, pending) {
if (cluster.add(pathObject)) {
for (next in group.getConnectedObjects(pathObject)) {
if (!cluster.contains(next))
pending.add(next)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment