Validate a tool against IDR data: Load Image with labels from IDR, re-analyze using Cellpose
IDR is based on OMERO and thus all what we show in this notebook can be easily adjusted for use against another OMERO server, e.g. your institutional OMERO server instance.
The main objective of this notebook is to demonstrate how public resources such as the IDR can be used to train your neural network or validate software tools.
The authors of the PLOS Biology paper, "Nessys: A new set of tools for the automated detection of nuclei within intact tissues and dense 3D cultures" published in August 2019: https://doi.org/10.1371/journal.pbio.3000388 , considered several image segmenation packages, but they did not use the approach described in this notebook.
We will analyse the data using Cellpose and compare the output with the original segmentation produced by the authors. StarDist was not considered by the authors. Our workflow shows how public repository can be accessed and data inside it used to validate software tools or new algorithms.
We will use an image (id=6001247) referenced in the paper. The image can be viewed online in the Image Data Resource (IDR).
We will use a predefined model from Cellpose as a starting point. Steps to access data from IDR could be re-used if you wish to create a new model (outside the scope of this notebook).
Code Snippets
2 3 4 5 6 7 8 9 | # Package required to interact with Cellpose %pip install cellpose==2.2.1 # Package required to interact with IDR or OMERO %pip install omero-py==5.13.1 # Package to convert masks stored in OMERO/IDR into numpy arrays %pip install omero-cli-zarr==0.5.2 |
13 14 15 16 17 18 | from omero.gateway import BlitzGateway HOST = 'ws://idr.openmicroscopy.org/omero-ws' conn = BlitzGateway('public', 'public', host=HOST, secure=True) print(conn.connect()) conn.c.enableKeepAlive(60) |
22 | image_id = 6001247 |
26 27 | image = conn.getObject("Image", image_id) print(image.getName()) |
31 | print("Size X: %s, Size Y: %s" % (image.getSizeX(), image.getSizeY())) |
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import numpy def load_numpy_array(image): pixels = image.getPrimaryPixels() size_z = image.getSizeZ() size_c = image.getSizeC() size_t = image.getSizeT() size_x = image.getSizeX() size_y = image.getSizeY() 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" % (size_t, size_c, size_z) 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) |
63 | data = load_numpy_array(image) |
67 | print(data.shape) |
71 72 | from cellpose import models model = models.Cellpose(gpu=False, model_type='cyto') |
76 77 78 79 | channels = [[0, 1]] t = 0 z = int(image.getPrimaryPixels().getSizeZ() / 2) cellpose_masks, flows, styles, diams = model.eval(data[t, :, z, :, :], diameter=None, channels=channels) |
83 84 85 86 87 88 89 | from cellpose import plot import matplotlib.pyplot as plt fig = plt.figure(figsize=(12,5)) plot.show_segmentation(fig, data[t, 1, z, :, :], cellpose_masks, flows[0], channels=channels) plt.tight_layout() plt.show() |
93 94 95 96 97 98 | roi_service = conn.getRoiService() result = roi_service.findByImage(image_id, None) shapes = [] for roi in result.rois: shapes.append(roi.copyShapes()) |
102 103 104 105 | from omero_zarr import masks dims = (image.getSizeT(), image.getSizeC(), image.getSizeZ(), image.getSizeY(), image.getSizeX()) saver = masks.MaskSaver(None, image, numpy.int64) labels, fillColors, properties = saver.masks_to_labels(shapes, mask_shape=dims) |
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | import matplotlib.pyplot as plt %matplotlib inline c = 1 t = 0 fig = plt.figure(figsize=(10, 10)) # Show the original labels from IDR sub1 = plt.subplot(121) sub1.title.set_text('Original labels IDR') plt.imshow(labels[t, c, z, :, :], cmap='gray', alpha=0.5) # Show the Cellpose labels sub2 = plt.subplot(122) sub2.title.set_text('Cellpose labels this notebook') plt.imshow(cellpose_masks, cmap='jet', alpha=0.5) fig2 = plt.figure(figsize=(8.5, 8.5)) # Show the original image sub3 = plt.subplot(121) sub3.title.set_text("Original unsegmented image") plt.imshow(data[t, c, z, :, :], cmap='jet') # Show the Cellpose labels sub4 = plt.subplot(122) sub4.title.set_text('Cellpose labels this notebook') plt.imshow(cellpose_masks, cmap='jet', alpha=0.5) plt.tight_layout() fig.canvas.flush_events() |
136 137 138 | from cellpose import io, utils outlines = utils.outlines_list(cellpose_masks) io.outlines_to_text(str(image_id), outlines) |
142 143 144 145 146 147 148 149 | def create_roi(img, shapes): # create an ROI, link it to Image roi = omero.model.RoiI() # use the omero.model.ImageI that underlies the 'image' wrapper roi.setImage(img._obj) for shape in shapes: roi.addShape(shape) return roi |
153 154 155 156 157 158 159 160 161 162 163 164 165 166 | # Convert roi into ome rois import re import omero from omero.rtypes import rdouble, rint, rstring polygons = [] with open(str(image_id) + "_cp_outlines.txt", "r") as text_file: for line in text_file: points = re.sub(r',([^,]*),', r',\1, ', line) polygon = omero.model.PolygonI() polygon.theZ = rint(z) polygon.theT = rint(t) polygon.points = rstring(points) polygons.append(polygon) roi = create_roi(image, polygons) |
170 171 172 | # Save the ROI when using an OMERO server if "idr" not in HOST: conn.getUpdateService().saveAndReturnObject(roi) |
176 177 178 179 180 181 182 183 | def disconnect(conn): """ Disconnect from an OMERO server :param conn: The BlitzGateway """ conn.close() disconnect(conn) |
Support
- Future updates
Related Workflows





