Batch export multiplex FL images in Qupath with specific channels ON/OFF

Sample image and/or code

Using this script to batch export rendered image from viewer

I’ve edited downsampling to = 1 so there is no downsampling and image file format to .jpg

Background

  • This is a component_data.tif file (multilayer tif) that was generated after unmixing a multiplex scan from the Vectra 3. The .tif file when loaded into QuPath sees all appropriate 7 color channels with labels provided by the Vectra.

Analysis goals

  • Exporting in batch a set of images from a project with specific channels ON/OFF. For example, exporting DAPI and SOX10 only, without remaining multiplex FL channels

Challenges

When running the script as “Run for Project (without save)” the two files I have in the test project export both as a tif and are not downsampled (great), however all channels in both images are still exported. I want only the 3 channels I have checked DAPI, CD33 and SOX10 that are seen in the image viewer to be exported into a single merged image.

I personally use HALO for all image analysis, however am needing an alternative simply for batch image export for specific channels. If ImageJ offers a better alternative to batch export multiplex images for certain channels, I’m all ears as well. Thank you!

Hi @MicroBioShock

The script will export a rendered image, i.e. converted to RGB. This will contain very different pixel values from the original image (which I believe are 32-bit floating point). The RGB image won’t really be suitable at all for any downstream analysis – especially with extra JPEG artifacts being included.

I haven’t used HALO but I presume it should be able to read the TIFF directly (with all the channels), so I’m not sure why any need to be removed.

So can you explain a bit more about your goals and what happens next? If it is really for analysis, I think you really ought to export the raw pixels and not an RGB version. If it’s just for visualization then I understand better why the rendered image would be used.

1 Like

Hi @petebankhead thanks for your comment and of course everything else you’ve done!

I actually do not need downstream analysis. This is purely for sharing images for visualization, RGB conversion is fine. I have the raw files for analysis which I use in HALO for image analysis.

I just need images to share to people that want to use it in a presentation, powerpoint, lab meeting etc. I’ll get requests of can I get these 25 images with only these three channels and it is a bit tedious loading each image in HALO, turn off all but 3 channels and saving a tif file. I would like a batch method for exporting images for visualization, which QuPath is very close to doing I think.

I hope that bit of information helps.

Ah ok, in that case adding display(viewer.getImageDisplay()) to the RenderedImageServer.Builder may suffice:

def server = new RenderedImageServer.Builder(imageData)
    .display(viewer.getImageDisplay())
    .downsamples(downsample)
    .layers(new HierarchyOverlay(viewer.getImageRegionStore(), viewer.getOverlayOptions(), imageData))
    .build()

Basically this will incorporate the display settings for the current image. I don’t recall exactly whether it will retain the min/max values per channel as well or if these will be recomputed – but at least it should include the channel on/off status (assuming the names are identical).

3 Likes

Thank you @petebankhead adding that code works - just tested in both 0.2.3 and 0.2.0! I have a set of batched image files in the format I requested with only the channels on status exported into a single merged image file. Perfect!

Now I’m testing the downsampling to see which value acts as no downsampling at all. Wondering if downsample = 0 is having no downsampling or if downsample = 1 is the correct value… Will edit after I test… = 0 seems to be taking awhile if at all working.

edit downsample = 0 does not work and just hangs there trying to export. I will leave at 1 as mentioned. thanks

downsample = 1 would be the correct value for the full resolution image (0 wouldn’t be valid… QuPath might quietly switch it to 1 instead, but best not count on that).