Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/* QuPath-Script to export annotations to label tif images (e.g. to be used for stardist)
Use "Run for project" to export annotations for all images within a QuPath project
Afterwards both images and mask tiffs will be stored in the project subfolder
ground_truth
├── images
└── masks
Based on code by Olivier Burri, Romain Guiet (both https://biop.epfl.ch/) and https://forum.image.sc/t/export-qupath-annotations-for-stardist-training/37391/3
*/
// USER SETTINGS
def channel_of_interest = 1 // null to export all the channels
def downsample = 1
def image_name = getProjectEntry().getImageName()
def rm = RoiManager.getRoiManager() ?: new RoiManager()
// create an annotation of the entire image
createSelectAllObject(true)
def fullimage_annotation = getSelectedObject()
imageData = getCurrentImageData();
server = imageData.getServer();
viewer = getCurrentViewer();
hierarchy = getCurrentHierarchy();
request = RegionRequest.createInstance(imageData.getServerPath(), downsample, fullimage_annotation.getROI())
pathImage = null;
pathImage = IJExtension.extractROIWithOverlay(server, fullimage_annotation, hierarchy, request, false, viewer.getOverlayOptions());
image = pathImage.getImage()
// Create the Labels image
def labels = IJ.createImage( "Labels", "16-bit black", image.getWidth(), image.getHeight() ,1 );
IJ.run(image, "To ROI Manager", "")
def rois = rm.getRoisAsArray() as List
def label_ip = labels.getProcessor()
def idx = 0
rois.each{ roi ->
if (roi.getType() == Roi.RECTANGLE) {
println("Ignoring Rectangle")
} else {
label_ip.setColor( ++idx )
label_ip.setRoi( roi )
label_ip.fill( roi )
}
}
labels.setProcessor( label_ip )
// Split to keep only channel of interest
def output = image
if ( channel_of_interest != null){
imp_chs = ChannelSplitter.split( image )
output = imp_chs[ channel_of_interest - 1 ]
}
saveImages(output, labels, image_name)
println( image_name + " Image and Mask Saved." )
// Save some RAM
output.close()
labels.close()
image.close()
// remove the fullimage_annotation from the list of annotations
// (true is to keep descendant objects)
removeObject( fullimage_annotation,true )
// This will save the images in the selected folder
def saveImages(def images, def labels, def name) {
def source_folder = new File ( buildFilePath( PROJECT_BASE_DIR, 'ground_truth', 'images' ) )
def target_folder = new File ( buildFilePath( PROJECT_BASE_DIR, 'ground_truth', 'masks' ) )
mkdirs( source_folder.getAbsolutePath() )
mkdirs( target_folder.getAbsolutePath() )
IJ.save( images , new File ( source_folder, name ).getAbsolutePath()+'.tif' )
IJ.save( labels , new File ( target_folder, name ).getAbsolutePath()+'.tif' )
}
// Manage Imports
import qupath.lib.roi.RectangleROI
import qupath.imagej.gui.IJExtension;
import ij.IJ
import ij.gui.Roi
import ij.plugin.ChannelSplitter
import ij.plugin.frame.RoiManager
print "done"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment