Skip to content

1. OME-Zarr containers

Open an OME-Zarr image and explore what it holds.

The OME-Zarr container is your entry point to working with OME-Zarr images. It gives you high-level access to the metadata, images, labels and tables in a store.

The objects inside an OME-Zarr container An OmeZarrContainer branches into an images container made of one Image per resolution level, a labels container holding named multiscale labels, and a tables container holding typed tables. OmeZarrContainer the store, opened IMAGE · PIXEL DATA LABELS · SEGMENTATIONS TABLES · MEASUREMENTS AND ROIS ImagesContainer several resolutions LabelsContainer masks, by name TablesContainer tables, by name Image · level 0 Image · level 1 Image · level 2 … Label · nuclei Label · cells RoiTable FeatureTable MaskingRoiTable … any number of labels
from pathlib import Path

from ngio import open_ome_zarr_container
from ngio.utils import download_ome_zarr_dataset

# Download a sample dataset
download_dir = Path("./data").absolute()
hcs_path = download_ome_zarr_dataset("CardiomyocyteSmallMip", download_dir=download_dir)
image_path = hcs_path / "B" / "03" / "0"

# Open the OME-Zarr container
ome_zarr_container = open_ome_zarr_container(image_path)
print(ome_zarr_container)
OmeZarrContainer(levels=5, #labels=4, #tables=7)

The OME-Zarr container will be the starting point for all your image processing tasks.

Main concepts

What is the OME-Zarr container?

The OME-Zarr container gives you:

  • OME-Zarr overview: get an overview of the OME-Zarr file, including the number of image levels, list of labels, and tables available.
  • Image access: get access to the images at different resolution levels and pixel sizes.
  • Label management: check which labels are available, access them, and create new labels.
  • Table management: check which tables are available, access them, and create new tables.
  • Derive new OME-Zarr images: create new images based on the original one, with the same or similar metadata.

What is the OME-Zarr container not?

The OME-Zarr container does not give you access to the image data directly. For that, use the Image, Label, and Table objects.

OME-Zarr overview

Examples of accessing the OME-Zarr metadata:

Show the number of resolution levels:

print(ome_zarr_container.levels)  # Show the number of resolution levels
5

Show the paths to all available resolution levels:

print(ome_zarr_container.level_paths)  # Show the paths to all available images
['0', '1', '2', '3', '4']

Show if the image is 2D or 3D:

print(ome_zarr_container.is_3d)  # Get if the image is 3D
False
or if the image is a time series:
print(ome_zarr_container.is_time_series)  # Get if the image is a time series
False

metadata = ome_zarr_container.meta
print(metadata)
NgioImageMeta(name=None, datasets=['0', '1', '2', '3', '4'], axes=('c', 'z', 'y', 'x'))
The metadata object contains all the information about the image, for example, the channel labels:
print(metadata.channels_meta.channel_labels)
['DAPI', 'nanog', 'Lamin B1']
And those three channels, read from a lower pyramid level:
2026-08-11T12:16:14.044391 image/svg+xml Matplotlib v3.11.0, https://matplotlib.org/ DAPI nanog Lamin B1

Modifying metadata

ngio provides methods to modify the image metadata, such as channel labels, colours, display windows, axes names, and units.

Channel metadata

You can update channel labels, colours, and display windows:

Update the labels (names) of the channels:

ome_zarr_container.set_channel_labels(["DAPI", "GFP", "RFP"])

Update the display colours of the channels (hex format):

ome_zarr_container.set_channel_colors(["0000FF", "00FF00", "FF0000"])

Update the display windows (start/end values) for each channel:

ome_zarr_container.set_channel_windows([(0, 255), (0, 1000), (0, 500)])

Automatically compute display windows based on data percentiles:

ome_zarr_container.set_channel_windows_with_percentiles(percentiles=(0.1, 99.9))

Axes metadata

You can update the axes names and units:

Rename the axes in the metadata:

ome_zarr_container.set_axes_names(["t", "c", "z", "y", "x"])

Set the space and time units:

ome_zarr_container.set_axes_units(space_unit="micrometer", time_unit="second")

Image name

You can set the name of the image in the metadata:

ome_zarr_container.set_name("My Processed Image")

Note

The set_name method only updates the metadata. It does not change the group name or file paths.

Accessing images / labels / tables

To access images, labels, and tables, you can use the get_image, get_label, and get_table methods of the OME-Zarr container.

A variety of examples and additional information can be found in the Images and labels, and Tables sections.

Creating derived images

When processing an image, you might want to create a new image with the same metadata:

# Create a new image based on the original
new_image = ome_zarr_container.derive_image("data/new_ome.zarr", overwrite=True)

This will create a new OME-Zarr image with the same metadata as the original image. But you can also create a new image with slightly different metadata, for example, with a different shape:

# Create a new image with a different shape
new_image = ome_zarr_container.derive_image(
    "data/new_ome.zarr",
    overwrite=True,
    shape=(16, 128, 128),
    pixelsize=0.65,
    z_spacing=1.0
)

Creating new images

You can create OME-Zarr images from an existing numpy array using the create_ome_zarr_from_array function.

import numpy as np
from ngio import create_ome_zarr_from_array

# Create a random 3D array
x = np.random.randint(0, 255, (16, 128, 128), dtype=np.uint8)

# Save as OME-Zarr
new_ome_zarr_image = create_ome_zarr_from_array(
    store="random_ome.zarr",
    array=x,
    pixelsize=0.65,
    z_spacing=1.0
)

Alternatively, if you want to create an empty OME-Zarr image, you can use the create_empty_ome_zarr function:

from ngio import create_empty_ome_zarr
# Create an empty OME-Zarr image
new_ome_zarr_image = create_empty_ome_zarr(
    store="empty_ome.zarr",
    shape=(16, 128, 128),
    pixelsize=0.65,
    z_spacing=1.0
)

This will create an empty OME-Zarr image with the specified shape and pixel sizes.

Opening remote OME-Zarr containers

You can use ngio to open remote OME-Zarr containers. For publicly available OME-Zarr containers, use the open_ome_zarr_container function with a URL.

For example, to open a remote OME-Zarr container hosted on a GitHub repository:

from ngio import open_ome_zarr_container
from ngio.utils import fractal_fsspec_store

url = (
    "https://raw.githubusercontent.com/"
    "fractal-analytics-platform/fractal-ome-zarr-examples/"
    "refs/heads/main/v04/"
    "20200812-CardiomyocyteDifferentiation14-Cycle1_B_03_mip.zarr/"
)

store = fractal_fsspec_store(url=url)
ome_zarr_container = open_ome_zarr_container(store)

For Fractal users, the fractal_fsspec_store function can be used to open private OME-Zarr containers. In this case you need to provide a fractal_token to authenticate.

from ngio import open_ome_zarr_container
from ngio.utils import fractal_fsspec_store

store = fractal_fsspec_store(url="https://fractal_url...", fractal_token="**your_secret_token**")
ome_zarr_container = open_ome_zarr_container(store)

Next steps

  • Images and labels — read and write pixel data.
  • TablesROIs, features and measurements stored alongside the image.