Fidelity of TileExporter

I used the script below to export tiles from annotated regions. The annotated regions and tiles have no tumor (see image). There are two issues:

  1. First, the number of tiles displayed in QuPath is not equal to the number of tiles exported. The number of annotated tiles that I can see in QuPath is less than half of the number of patches that were exported.

  2. Second, I noticed that occasional exported patches have tumor clusters. As mentioned, when I look in QuPath at the annotated area, there is no tumor. The tumor clusters that are seen in the patches are close to the annotated regions but not in the annotated regions.

I am using QuPath version 0.2.3 and am using a Windows 10 operating system. I do not see anything directly relevant to this in the forum or in QuPath documents (

import qupath.lib.images.servers.LabeledImageServer

def imageData = getCurrentImageData()

// Define output path (relative to project)
def name = GeneralTools.getNameWithoutExtension(imageData.getServer().getMetadata().getName())
def pathOutput = buildFilePath(PROJECT_BASE_DIR, 'tiles', name)

// Define output resolution
//double requestedPixelSize = 0.2465

// Convert to downsample
double downsample = 1 //requestedPixelSize / imageData.getServer().getPixelCalibration().getAveragedPixelSize()

// Create an ImageServer where the pixels are derived from annotations
def labelServer = new LabeledImageServer.Builder(imageData)
    .backgroundLabel(0, ColorTools.WHITE) // Specify background label (usually 0 or 255)
    .downsample(downsample)    // Choose server resolution; this should match the resolution at which tiles are exported
    .addLabel('Other', 1)      // Choose output labels (the order matters!)
    .multichannelOutput(true)  // If true, each label is a different channel (required for multiclass probability)

// Create an exporter that requests corresponding tiles from the original & labeled image servers
new TileExporter(imageData)
    .downsample(downsample)     // Define export resolution
    .imageExtension('.png')     // Define file extension for original pixels (often .tif, .jpg, '.png' or '.ome.tif')
    .tileSize(512, 512)              // Define size of each tile, in pixels
//    .labeledServer(labelServer) // Define the labeled image server to use (i.e. the one we just built)
    .annotatedTilesOnly(true)  // If true, only export tiles if there is a (labeled) annotation present
    .overlap(0)                // Define overlap, in pixel units at the export resolution
    .writeTiles(pathOutput)     // Write tiles to the specified directory

print 'Done!'

When using the TileExporter there’s no need to create distinct tiles as annotations within QuPath: rather, the exporter itself figures out which tiles are needed according to the parameters specified in the script and generates them implicitly during export.

This should be much more efficient and reproducible. You can generate tile annotations in QuPath, add them to the image, and then export tiles corresponding to these annotations separately (not using the TileExporter, but rather looping through the annotations themselves). Before QuPath v0.2 this was the main way to do it. But it tends to be slower and can result in off-by-one differences in tile sizes when downsampling is applied, so the TileExporter was created to fix this.

Regarding areas being export that contain tumor clusters, see TileExporter using bounding box


Also, the N key (or Show Names through the View menu) can be used to turn off the mass of Tile # text!

1 Like