Created
July 28, 2021 07:13
-
-
Save petebankhead/bea34ee1716b67246c2308808dd3c025 to your computer and use it in GitHub Desktop.
Identify distinct clusters after using QuPath's 'Delaunay cluster features 2D' command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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