The notebook shows how to load an IDR image with labels.
The image is referenced in the paper "NesSys: a novel method for accurate nuclear segmentation in 3D" published August 2019 in PLOS Biology: https://doi.org/10.1371/journal.pbio.3000388 and can be viewed online in the Image Data Resource.
In this notebook, the image is loaded together with the labels and analyzed using StarDist. The StarDist analysis produces a segmentation, which is then viewed side-by-side with the original segmentations produced by the authors of the paper obtained via the loaded labels.
If you wish to run the notebook locally or run the corresponding Python script, please read instruction in README.
The cell below will install dependencies if you choose to run the notebook in Google Colab.
%pip install omero-py stardist==0.8.1 geojson omero-cli-zarr
Requirement already satisfied: omero-py in /srv/conda/envs/notebook/lib/python3.9/site-packages (5.11.1) Requirement already satisfied: stardist in /srv/conda/envs/notebook/lib/python3.9/site-packages (0.8.1) Requirement already satisfied: geojson in /srv/conda/envs/notebook/lib/python3.9/site-packages (2.5.0) Requirement already satisfied: omero-cli-zarr in /srv/conda/envs/notebook/lib/python3.9/site-packages (0.3.0) Requirement already satisfied: keras==2.6 in /srv/conda/envs/notebook/lib/python3.9/site-packages (2.6.0) Requirement already satisfied: ome-zarr>=0.3.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from omero-cli-zarr) (0.4.1) Requirement already satisfied: requests in /srv/conda/envs/notebook/lib/python3.9/site-packages (from omero-py) (2.25.1) Requirement already satisfied: numpy in /srv/conda/envs/notebook/lib/python3.9/site-packages (from omero-py) (1.21.6) Requirement already satisfied: PyYAML in /srv/conda/envs/notebook/lib/python3.9/site-packages (from omero-py) (6.0) Requirement already satisfied: zeroc-ice<3.7,>=3.6.4 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from omero-py) (3.6.5) Requirement already satisfied: future in /srv/conda/envs/notebook/lib/python3.9/site-packages (from omero-py) (0.18.2) Requirement already satisfied: appdirs in /srv/conda/envs/notebook/lib/python3.9/site-packages (from omero-py) (1.4.4) Requirement already satisfied: Pillow in /srv/conda/envs/notebook/lib/python3.9/site-packages (from omero-py) (9.0.1) Requirement already satisfied: scikit-image in /srv/conda/envs/notebook/lib/python3.9/site-packages (from ome-zarr>=0.3.0->omero-cli-zarr) (0.19.2) Requirement already satisfied: dask in /srv/conda/envs/notebook/lib/python3.9/site-packages (from ome-zarr>=0.3.0->omero-cli-zarr) (2022.4.1) Requirement already satisfied: toolz in /srv/conda/envs/notebook/lib/python3.9/site-packages (from ome-zarr>=0.3.0->omero-cli-zarr) (0.11.2) Requirement already satisfied: fsspec[s3]!=2021.07.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from ome-zarr>=0.3.0->omero-cli-zarr) (2022.3.0) Requirement already satisfied: zarr>=2.8.1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from ome-zarr>=0.3.0->omero-cli-zarr) (2.11.3) Requirement already satisfied: aiohttp<4 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from ome-zarr>=0.3.0->omero-cli-zarr) (3.8.1) Requirement already satisfied: yarl<2.0,>=1.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiohttp<4->ome-zarr>=0.3.0->omero-cli-zarr) (1.7.2) Requirement already satisfied: charset-normalizer<3.0,>=2.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiohttp<4->ome-zarr>=0.3.0->omero-cli-zarr) (2.0.12) Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiohttp<4->ome-zarr>=0.3.0->omero-cli-zarr) (4.0.2) Requirement already satisfied: multidict<7.0,>=4.5 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiohttp<4->ome-zarr>=0.3.0->omero-cli-zarr) (6.0.2) Requirement already satisfied: frozenlist>=1.1.1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiohttp<4->ome-zarr>=0.3.0->omero-cli-zarr) (1.3.0) Requirement already satisfied: attrs>=17.3.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiohttp<4->ome-zarr>=0.3.0->omero-cli-zarr) (20.3.0) Requirement already satisfied: aiosignal>=1.1.2 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiohttp<4->ome-zarr>=0.3.0->omero-cli-zarr) (1.2.0) Requirement already satisfied: s3fs in /srv/conda/envs/notebook/lib/python3.9/site-packages (from fsspec[s3]!=2021.07.0->ome-zarr>=0.3.0->omero-cli-zarr) (2022.3.0) Requirement already satisfied: idna>=2.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from yarl<2.0,>=1.0->aiohttp<4->ome-zarr>=0.3.0->omero-cli-zarr) (2.10) Requirement already satisfied: numcodecs>=0.6.4 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from zarr>=2.8.1->ome-zarr>=0.3.0->omero-cli-zarr) (0.9.1) Requirement already satisfied: asciitree in /srv/conda/envs/notebook/lib/python3.9/site-packages (from zarr>=2.8.1->ome-zarr>=0.3.0->omero-cli-zarr) (0.3.3) Requirement already satisfied: fasteners in /srv/conda/envs/notebook/lib/python3.9/site-packages (from zarr>=2.8.1->ome-zarr>=0.3.0->omero-cli-zarr) (0.17.3) Requirement already satisfied: numba in /srv/conda/envs/notebook/lib/python3.9/site-packages (from stardist) (0.55.1) Requirement already satisfied: imageio in /srv/conda/envs/notebook/lib/python3.9/site-packages (from stardist) (2.18.0) Requirement already satisfied: csbdeep>=0.6.3 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from stardist) (0.6.3) Requirement already satisfied: six in /srv/conda/envs/notebook/lib/python3.9/site-packages (from csbdeep>=0.6.3->stardist) (1.15.0) Requirement already satisfied: h5py>=3 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from csbdeep>=0.6.3->stardist) (3.6.0) Requirement already satisfied: tqdm in /srv/conda/envs/notebook/lib/python3.9/site-packages (from csbdeep>=0.6.3->stardist) (4.64.0) Requirement already satisfied: matplotlib in /srv/conda/envs/notebook/lib/python3.9/site-packages (from csbdeep>=0.6.3->stardist) (3.5.1) Requirement already satisfied: tifffile in /srv/conda/envs/notebook/lib/python3.9/site-packages (from csbdeep>=0.6.3->stardist) (2022.4.26) Requirement already satisfied: scipy in /srv/conda/envs/notebook/lib/python3.9/site-packages (from csbdeep>=0.6.3->stardist) (1.8.0) Requirement already satisfied: partd>=0.3.10 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from dask->ome-zarr>=0.3.0->omero-cli-zarr) (1.2.0) Requirement already satisfied: cloudpickle>=1.1.1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from dask->ome-zarr>=0.3.0->omero-cli-zarr) (2.0.0) Requirement already satisfied: packaging>=20.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from dask->ome-zarr>=0.3.0->omero-cli-zarr) (20.9) Requirement already satisfied: pyparsing>=2.0.2 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from packaging>=20.0->dask->ome-zarr>=0.3.0->omero-cli-zarr) (2.4.7) Requirement already satisfied: locket in /srv/conda/envs/notebook/lib/python3.9/site-packages (from partd>=0.3.10->dask->ome-zarr>=0.3.0->omero-cli-zarr) (1.0.0) Requirement already satisfied: cycler>=0.10 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from matplotlib->csbdeep>=0.6.3->stardist) (0.11.0) Requirement already satisfied: fonttools>=4.22.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from matplotlib->csbdeep>=0.6.3->stardist) (4.33.3) Requirement already satisfied: python-dateutil>=2.7 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from matplotlib->csbdeep>=0.6.3->stardist) (2.8.1) Requirement already satisfied: kiwisolver>=1.0.1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from matplotlib->csbdeep>=0.6.3->stardist) (1.4.2) Requirement already satisfied: setuptools in /srv/conda/envs/notebook/lib/python3.9/site-packages (from numba->stardist) (49.6.0.post20210108) Requirement already satisfied: llvmlite<0.39,>=0.38.0rc1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from numba->stardist) (0.38.0) Requirement already satisfied: certifi>=2017.4.17 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from requests->omero-py) (2020.12.5) Requirement already satisfied: urllib3<1.27,>=1.21.1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from requests->omero-py) (1.26.3) Requirement already satisfied: chardet<5,>=3.0.2 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from requests->omero-py) (4.0.0) Requirement already satisfied: aiobotocore~=2.2.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from s3fs->fsspec[s3]!=2021.07.0->ome-zarr>=0.3.0->omero-cli-zarr) (2.2.0) Requirement already satisfied: botocore<1.24.22,>=1.24.21 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiobotocore~=2.2.0->s3fs->fsspec[s3]!=2021.07.0->ome-zarr>=0.3.0->omero-cli-zarr) (1.24.21) Requirement already satisfied: aioitertools>=0.5.1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiobotocore~=2.2.0->s3fs->fsspec[s3]!=2021.07.0->ome-zarr>=0.3.0->omero-cli-zarr) (0.10.0) Requirement already satisfied: wrapt>=1.10.10 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aiobotocore~=2.2.0->s3fs->fsspec[s3]!=2021.07.0->ome-zarr>=0.3.0->omero-cli-zarr) (1.14.0) Requirement already satisfied: typing_extensions>=4.0 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from aioitertools>=0.5.1->aiobotocore~=2.2.0->s3fs->fsspec[s3]!=2021.07.0->ome-zarr>=0.3.0->omero-cli-zarr) (4.2.0) Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from botocore<1.24.22,>=1.24.21->aiobotocore~=2.2.0->s3fs->fsspec[s3]!=2021.07.0->ome-zarr>=0.3.0->omero-cli-zarr) (1.0.0) Requirement already satisfied: networkx>=2.2 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from scikit-image->ome-zarr>=0.3.0->omero-cli-zarr) (2.8) Requirement already satisfied: PyWavelets>=1.1.1 in /srv/conda/envs/notebook/lib/python3.9/site-packages (from scikit-image->ome-zarr>=0.3.0->omero-cli-zarr) (1.3.0) Note: you may need to restart the kernel to use updated packages.
from omero.gateway import BlitzGateway
import matplotlib.pyplot as plt
%matplotlib inline
import numpy
HOST = 'ws://idr.openmicroscopy.org/omero-ws'
conn = BlitzGateway('public', 'public',
host=HOST, secure=True)
print(conn.connect())
conn.c.enableKeepAlive(60)
True
image_id = 6001247
image = conn.getObject("Image", image_id)
The image is loaded a TCZYX numpy array.
def load_numpy_array(image):
pixels = image.getPrimaryPixels()
size_z = image.getSizeZ()
size_c = image.getSizeC()
size_t = image.getSizeT()
size_y = image.getSizeY()
size_x = image.getSizeX()
z, t, c = 0, 0, 0 # first plane of the image
zct_list = []
for t in range(size_t):
for c in range(size_c): # all channels
for z in range(size_z): # get the Z-stack
zct_list.append((z, c, t))
values = []
# Load all the planes as YX numpy array
planes = pixels.getPlanes(zct_list)
s = "t:%s c:%s z:%s y:%s x:%s" % (size_t, size_c, size_z, size_y, size_x)
print(s)
print("Downloading image %s" % image.getName())
all_planes = numpy.stack(list(planes))
shape = (size_t, size_c, size_z, size_y, size_x)
return numpy.reshape(all_planes, newshape=shape)
Load the binary data as a numpy array
data = load_numpy_array(image)
t:1 c:2 z:257 y:210 x:253 Downloading image B4_C3.tif
from stardist.models import StarDist2D
model_versatile = StarDist2D.from_pretrained('2D_demo')
Found model '2D_demo' for 'StarDist2D'. Downloading data from https://github.com/stardist/stardist-models/releases/download/v0.1/python_2D_demo.zip 5300224/5298331 [==============================] - 1s 0us/step 5308416/5298331 [==============================] - 1s 0us/step Loading network weights from 'weights_best.h5'. Loading thresholds from 'thresholds.json'. Using default values: prob_thresh=0.486166, nms_thresh=0.5.
Normalize the input image
model_versatile.predict_instances
will
from csbdeep.utils import normalize
axis_norm = (0,1)
c = 1
img = normalize(data[0, c, :, :, :], 1,99.8, axis=axis_norm)
results = []
results_details = []
for i in range(len(img)):
new_labels, details = model_versatile.predict_instances(img[i])
results_details.append(details)
results.append(new_labels)
label_slices = numpy.array(results)
Load the original labels in order to compare them with the StarDist ones Original labels have been saved as mask.
from omero_zarr import masks
roi_service = conn.getRoiService()
result = roi_service.findByImage(image_id, None)
dims = (image.getSizeT(), image.getSizeC(), image.getSizeZ(), image.getSizeY(), image.getSizeX())
shapes = []
for roi in result.rois:
shapes.append(roi.copyShapes())
saver = masks.MaskSaver(None, image, numpy.int64)
labels, fillColors, properties = saver.masks_to_labels(shapes, mask_shape=dims)
print(labels.shape)
(1, 2, 257, 210, 253)
Display the original labels and the labels based on StarDist prediction side-by-side
from ipywidgets import *
def update(z=0):
c = 1
fig = plt.figure(figsize=(10, 10))
plt.subplot(121)
plt.imshow(data[0, c, z, :, :], cmap='jet')
try:
plt.imshow(labels[0, c, z, :, :], cmap='gray', alpha=0.5)
except Exception:
print(z)
plt.subplot(122)
plt.imshow(data[0, c, z, :, :], cmap='gray')
plt.imshow(label_slices[z, :, :], cmap='jet', alpha=0.5)
plt.tight_layout()
fig.canvas.flush_events()
interact(update, z= widgets.IntSlider(value=1, min=0, max=data.shape[2]-1, step=1, description="Select Z", continuous_update=False))
interactive(children=(IntSlider(value=1, continuous_update=False, description='Select Z', max=256), Output()),…
<function __main__.update(z=0)>
conn.close()
StarDist offers method to save the labels into ImageJ rois using export_imagej_rois
. This is outside the scope of this notebook.
Below we show how to save the segmentation represented as polygon details locally in a machine- and human-readable format: geojson.
notebooks
folder in a .geojson
file.# Convert into Polygon and add to Geometry Collection
from geojson import Feature, FeatureCollection, Polygon
c = 1
shapes = []
for i in range(len(results_details)):
details = results_details[i]
for obj_id, region in enumerate(details['coord']):
coordinates = []
x = region[1]
y = region[0]
for j in range(len(x)):
coordinates.append((float(x[j]), float(y[j])))
# append the first coordinate to close the polygon
coordinates.append(coordinates[0])
shape = Polygon(coordinates)
properties = {
"stroke-width": 1,
"z": i,
"c": c,
}
shapes.append(Feature(geometry=shape, properties=properties))
gc = FeatureCollection(shapes)
# Save the shapes as geojson
import geojson
geojson_file = "stardist_shapes_%s.geojson" % image_id
geojson_dump = geojson.dumps(gc, sort_keys=True)
with open(geojson_file, 'w') as out:
out.write(geojson_dump)
Copyright (C) 2022 University of Dundee. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.