Skip to content

2. Images and Labels

Images

In order to start working with the image data, we need to instantiate an Image object. ngio provides a high-level API to access the image data at different resolution levels and pixel sizes.

Getting an image

By default, the get_image method returns the highest resolution image:

>>> ome_zarr_container.get_image() # Get the highest resolution image
Image(path=0, Dimensions(c: 3, z: 1, y: 4320, x: 5120))

To get a specific pyramid level, you can use the path parameter:

>>> ome_zarr_container.get_image(path="1") # Get a specific pyramid level
Image(path=1, Dimensions(c: 3, z: 1, y: 2160, x: 2560))
This will return the image at the specified pyramid level.

If you want to get an image with a specific pixel size, you can use the pixel_size parameter:

>>> from ngio import PixelSize
>>> pixel_size = PixelSize(x=0.65, y=0.65, z=1.0)
>>> ome_zarr_container.get_image(pixel_size=pixel_size)
Image(path=2, Dimensions(c: 3, z: 1, y: 1080, x: 1280))

By default the pixels must match exactly the requested pixel size. If you want to get the nearest resolution, you can use the strict parameter:

>>> from ngio import PixelSize
>>> pixel_size = PixelSize(x=0.60, y=0.60, z=1.0)
>>> ome_zarr_container.get_image(pixel_size=pixel_size, strict=False)
Image(path=2, Dimensions(c: 3, z: 1, y: 1080, x: 1280))
This will return the image with the nearest resolution to the requested pixel size.

Similarly to the OME-Zarr Container, the Image object provides a high-level API to access the image metadata.

>>> image.dimensions
Dimensions(c: 3, z: 1, y: 1080, x: 1280)
The dimensions attribute returns a object with the image dimensions for each axis.

>>> image.pixel_size
PixelSize(x=0.65, y=0.65, z=1.0, t=1.0)
The pixel_size attribute returns the pixel size for each axis.

>>> image.shape, image.dtype, image.chunks
(3, 1, 1080, 1280) uint16 (1, 1, 1080, 1280)
The axes attribute returns the order of the axes in the image.

Working with image data

Once you have the Image object, you can access the image data as a:

>>> data = image.get_array() # Get the image as a numpy array
>>> data.shape, data.dtype
(3, 1, 1080, 1280) uint16
>>> dask_array = image.get_array(mode="dask") # Get the image as a dask array
>>> dask_array
dask.array<from-zarr, shape=(3, 1, 1080, 1280), dtype=uint16, chunksize=(1, 1, 1080, 1280), chunktype=numpy.ndarray>
>>> dask_delayed = image.get_array(mode="delayed") # Get the image as a dask delayed object
>>> dask_delayed
Delayed('transform_numpy_array-21f175ac-358b-49e8-a04a-b921eea51860')

The get_array can also be used to slice the image data, and query specific axes in specific orders:

>>> image_slice = image.get_array(c=0, x=slice(0, 128), axes_order=["t", "z", "y", "x", "c"]) # Get a specific channel and axes order
>>> image_slice.shape
(1, 1, 1080, 128, 1)

If you want to edit the image data, you can use the set_array method:

>>> image.set_array(data) # Set the image data

The set_array method can be used to set the image data from a numpy array, dask array, or dask delayed object.

A minimal example of how to use the get_array and set_array methods:

# Get the image data as a numpy array
data = image.get_array(c=0, x=slice(0, 128), y=slice(0, 128), axes_order=["z", "y", "x", "c"])

# Modify the image data
data = some_function(data)

# Set the modified image data
image.set_array(data, c=0, x=slice(0, 128), y=slice(0, 128), axes_order=["z", "y", "x", "c"])
image.consolidate() # Consolidate the changes to all resolution levels, see below for more details

Important

The set_array method will overwrite the image data at single resolution level. After you have finished editing the image data, you need to consolidate the changes to the OME-Zarr file at all resolution levels:

>>> image.consolidate() # Consolidate the changes
This will write the changes to the OME-Zarr file at all resolution levels.

Labels

Labels represent segmentation masks that identify objects in the image. In ngio Labels are similar to Images and can be accessed and manipulated in the same way.

Getting a label

Now let's see what labels are available in our image:

>>> ome_zarr_container.list_labels() # Available labels
['nuclei', 'wf_2_labels', 'wf_3_labels', 'wf_4_labels']

We have 4 labels available in our image. Let's see how to access them:

By default, the get_label method returns the highest resolution label:

>>> ome_zarr_container.get_label("nuclei") # Get the highest resolution label
Label(path=0, Dimensions(z: 1, y: 4320, x: 5120))

To get a specific pyramid level, you can use the path parameter:

>>> ome_zarr_container.get_label("nuclei", path="1") # Get a specific pyramid level
Label(path=1, Dimensions(z: 1, y: 2160, x: 2560))
This will return the label at the specified pyramid level.

If you want to get a label with a specific pixel size, you can use the pixel_size parameter:

>>> from ngio import PixelSize
>>> pixel_size = PixelSize(x=0.65, y=0.65, z=1.0)
>>> ome_zarr_container.get_label("nuclei", pixel_size=pixel_size)
Label(path=2, Dimensions(z: 1, y: 1080, x: 1280))

By default the pixels must match exactly the requested pixel size. If you want to get the nearest resolution, you can use the strict parameter:

>>> from ngio import PixelSize
>>> pixel_size = PixelSize(x=0.60, y=0.60, z=1.0)
>>> ome_zarr_container.get_label("nuclei", pixel_size=pixel_size, strict=False)
Label(path=2, Dimensions(z: 1, y: 1080, x: 1280))
This will return the label with the nearest resolution to the requested pixel size.

Working with label data

Data access and manipulation for Labels is similar to Images. You can use the get_array and set_array methods to access and modify the label data.

Deriving a label

Often, you might want to create a new label based on an existing image. You can do this using the derive_label method:

>>> new_label = ome_zarr_container.derive_label("new_label", overwrite=True) # Derive a new label
Label(path=0, Dimensions(z: 1, y: 4320, x: 5120))

This will create a new label with the same dimensions as the original image (without channels) and compatible metadata. If you want to create a new label with slightly different metadata see API Reference.