Blog Posts

2023-03-04

BigImageViewer - A Python package to view very large images

Microscopes produce very large images. We have one which captures them in tiles, assembling them into 25,000x30,000 pixel TIFFs. Uncompressed that's 3Gb. Most image viewers will grind to a halt.

There are two solutions for this. TIFF supports multiple resolutions and tiling within its file format, called tiled image pyramids. However, most image viewers don't support it. The other solution is to produce several resolutions of your image, and break each up into tiles, stored in separate files. One such format is DeepZoom. Google Maps uses a similar technique.

DeepZoom

DeepZoom was proposed by OpenSeaDragon. Files have a .dzi extension. An XML file describes the image and the tiling technique, eg:

<?xml version="1.0" encoding="UTF-8"?>
<Image xmlns="http://schemas.microsoft.com/deepzoom/2008"
  Format="jpeg"
  Overlap="1"
  TileSize="254"
  >
  <Size 
    Height="24576"
    Width="30000"
  />
</Image>

In this example, the tiles are 254x254 pixels and overlap by one pixel.

The tiles are stored in a directory called filename_files. Inside that is a subdirectory for each resolution, with the smallest (most zoomed out, by default 1x1 pixel) called 0, the next size up, double the resolution, is called 1, etc, up to the original image size. Inside each of these directories are the tiles at that resolution, named y_x.jpeg. For the above the directory structure looks like this:

|-- NC100.dzi
|-- NC100_files
|   |-- 0
|   |   |-- 0_0.jpeg
|   |-- 1
|   |   |-- 0_0.jpeg
...
|   |-- 9
|   |   |-- 0_0.jpeg
|   |   |-- 0_1.jpeg
|   |   |-- 1_0.jpeg
|   |   |-- 1_0.jpeg
|   |-- 10
|   |   |-- 0_0.jpeg
|   |   |-- 0_1.jpeg
|   |   |-- 0_2.jpeg
|   |   |-- 0_3.jpeg
|   |   |-- 1_0.jpeg
...

Viewing DeepZoom images

OpenSeaDragon have developed a very nice Javaacript tool for displaying DeepZoom images. If you're interested, visit https://openseadragon.github.io/. However, we needed to view them inside a Python GUI we were developing to process microscopy images. This is why I wrote BigImageViewer.

BigImageViewer is a Python Qt component complete with zooming and panning. Tiles either side of the viewport are pre-loaded to make panning smooth.

To install, clone the repo:

git clone https://github.com/mbakereth/bigimageviewer.git

and follow the instuctions in the README.md.

An example usage is

from bigimageviewer import BigImageComponent

layout = QVBoxLayout()
viewer = BigImageComponent(width=512, height=512)
layout.addWidget(viewer)
viewer.load_image("myimage.dzi")  # or a .tif file

It also has a standalone CLI you can use without writing code.

TIFF tiled image pyramids and other formats

BigImageViewer supports other formats too, using the large_image package, which in turn is based on pyvips, the Python bindings of the excellent libvips package. libvips provides for memory efficient image processing of large images.

Creating tiled images

You can use libvips can create DeepZoom images. The vips command line tool is installed with BigImageViewer, or you can install it separately with:

virtualenv venv
venv/bin/activate
pip install 

To create a DeepZoom image, do the following

vips dzsave input.tiff outimage

It can also create tiled TIFF images. Further details are in BigImageViewer's README.

Demo

Following is a video showing BigImageViewer zooming and panning an 84,000x42,000 pixel image:

Credit for BlackMarble image: NASA https://earthobservatory.nasa.gov/features/NightLights/page3.php

Summary

This post covered BigImageViewer, my Python package fow viewing very large images with a minimal memory footprint. It provides a Qt component for integrating into your Python application, or can be used standaline. Under the hood, it uses the pyvips and large_image packages.

Matt Baker - technology and scientific IT blog