Downloading ROIs (3D)#
Following up the notebooks about uploading nD segmentations as ROIs to OMERO and the previous notebook on restoring segmentations from uploaded ROIs, let’s look at how we can accomplish the same with nD-segmentations.
For this tutorial, you’ll have to install napari, too:
mamba install napari pyqt
from omero.model import Shape
from omero.rtypes import unwrap
from typing import Tuple
import ezomero
import napari
import numpy as np
viewer = napari.Viewer(ndisplay=3)
Let’s connect to our server:
user = 'your-user'
group = 'default'
host = 'your-host'
port = 4064
secure = True
conn = ezomero.connect(host=host, port=port, group=group, user=user, password=None, secure=secure)
Let’s retrieve the image - again, check the OMERO browser to see the id of the uploaded image, as it will likely differ on your end.
image_id = 38009
image_wrapper, image = ezomero.get_image(conn, image_id, dim_order='tczyx')
image_wrapper
Image information
|
|
Let’s check what ROIs we find attached to this image. In our case, there are two ROIs. One for the binary mask and one for the labels image from the previous tutorial.
rois = image_wrapper.getROIs()
print('Number of ROIs:', len(rois))
Number of ROIs: 34
Labels images#
Let’s directly try and recreate some label images from this data. We first allocate and empty label image. Note that we want to restore a 3D segmentation in this case, so we have to build the 3D label objects from the individual ROIs. Luckily, every ROI is explicitly assigned to a specific channel, z-slice and timepoint so that there is not ambiguity. Again, we use the copied mask_to_binary_image
function from omero-cli-zarr for our purposes here until it has been moved over to the omero-rois package.
def mask_to_binary_image(
mask: Shape, dtype=bool
) -> Tuple[np.ndarray, Tuple[int, ...]]:
"""
Convert an OMERO mask to a binary image
:param mask MaskI: An OMERO mask
:param dtype: Data type for the binary image
:return: tuple of
- Binary mask
- (T, C, Z, Y, X, w, h) tuple of mask settings (T, C, Z may be
None)
"""
t = unwrap(mask.theT)
c = unwrap(mask.theC)
z = unwrap(mask.theZ)
x = int(mask.x.val)
y = int(mask.y.val)
w = int(mask.width.val)
h = int(mask.height.val)
mask_packed = mask.getBytes()
# convert bytearray into something we can use
intarray = np.fromstring(mask_packed, dtype=np.uint8)
binarray = np.unpackbits(intarray).astype(dtype)
# truncate and reshape
binarray = np.reshape(binarray[: (w * h)], (h, w))
return binarray, (t, c, z, y, x, h, w)
labels = np.zeros(image.shape, dtype=np.uint16)
labels.shape
(1, 2, 60, 256, 256)
for idx, roi in enumerate(rois):
shapes = roi.copyShapes()
for shape in shapes:
array, metadata = mask_to_binary_image(shape)
t = metadata[0]
c = metadata[1]
z = metadata[2]
y = metadata[3]
x = metadata[4]
h = metadata[5]
w = metadata[6]
mask = array == 1
labels[t, c, z, y:y+h, x:x+w][mask] = idx + 1
Let’s see what we get from this:
image.squeeze().shape
(2, 60, 256, 256)
viewer.layers.clear()
viewer.add_image(image.squeeze(), name='image', channel_axis=0)
viewer.add_labels(labels.squeeze()[1], name='roi', opacity=0.5)
napari.utils.nbscreenshot(viewer)
There we go :)