Preprocessing
The preprocessing step prepares a raw SpatialData image for segmentation by performing the following operations:
Load morphology image from a SpatialData Zarr file.
zarr_path = os.path.join(self.zarr_dir, self.zarr_name) self.sdata = sd.read_zarr(zarr_path) img_xr = self.sdata.images[f"{self.fov}_image"] img = img_xr.transpose("y", "x", "c").data.compute()
Extract channels:
Membrane (Y),DNA (U).channel_indices = [channel_names.index(ch) for ch in channels_to_use] img = img[..., channel_indices]
Normalize contrast (2–98% percentile stretch).
p2, p98 = np.percentile(img, (2, 98)) img_stretched = np.clip((img - p2) / (p98 - p2), 0, 1).astype(np.float32)
Convert to 8-bit RGB (required for Cellpose).
img_8bit = (img_stretched * 255).astype(np.uint8) if img_8bit.ndim == 3 and img_8bit.shape[-1] == 2: zero_channel = np.zeros_like(img_8bit[..., :1]) img_8bit = np.concatenate([img_8bit, zero_channel], axis=-1) elif img_8bit.ndim == 2: img_8bit = np.stack([img_8bit] * 3, axis=-1)
Downsize to
768×768(ideal for Cellpose ViT cyto3 on low RAM).seg_pil = Image.fromarray(img_8bit, mode="RGB") seg_pil.thumbnail(thumbnail_size=(768, 768), Image.Resampling.LANCZOS)
Save a segmentation-ready
.pngfile.if output_path is not None: seg_pil.save(output_path) self.image = seg_pil