Group Work 1 Solution Notebook#
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "tifffile",
# "spotiflow",
# "tqdm",
# "cellpose",
# "tqdm",
# ]
# ///
Step 3#
In this step you need to add the code that segments nuclei and cytoplasm of all the images in the dataset using Cellpose and saves the segmentation of each image as a .tif file.
For each step, create a new
codecell in the notebook (+button)Within the cell, add the necessary code.
Tip: to get the nuclei segmentation, you can pass only the nuclei channel (channel 0) to the
Cellposeevalmethod. To get the cytoplasm segmentation, you can pass both channels (0 and 1).
Import Dependencies
from pathlib import Path
from cellpose import core, io, models
from cellpose.models import MODEL_DIR
from tqdm import tqdm
Setup
#setup
io.logger_setup() # to get printing of progress
use_gpu = core.use_gpu()
print("GPU available:", use_gpu)
Load Image Files
# Path to the folder containing the images to segment
folder_path = Path("data/group-work-1")
# Get the sorted list of all .tif images in the folder
images_path = sorted(folder_path.glob("*.tif"))
# OPTIONAL: what's the images shape?
img1 = io.imread(images_path[0])
print(f"Image shape: {img1.shape}")
#OPTIONAL: if you add to the dependencies list matplotlib, you can visualize the image
import matplotlib.pyplot as plt
ch = 0 # choose the channel to visualize
plt.imshow(img1[ch], cmap='gray')
plt.show()
Initialize the Model
# Initialize the model once before the loop
model_path = str(MODEL_DIR / "cpsam_v2") # or "cpdino" / "cpdino-vitb" or "cpsam"
model = models.CellposeModel(pretrained_model=model_path, gpu=use_gpu)
Cellpose Segmentation: nuclei
# Run Cellpose on each image one by one
# Create a subfolder to save the nuclei segmentation results
nuclei_folder = folder_path / "nuclei_labels"
nuclei_folder.mkdir(exist_ok=True)
# NOTE: tqdm is used to show a progress bar, but you can remove it if you don't want it
for image_path in tqdm(images_path, desc="Processing images"):
# Load the image
image = io.imread(image_path)
# select the channels to segement from the multichannel image
nuc_image = image[0]
# Run Cellpose on the image
masks, flows, styles = model.eval(nuc_image)
# Save the segmentation results as a TIFF file
output_path = nuclei_folder / f"{image_path.stem}_nuclei_labels.tif"
io.imsave(output_path, masks) # or tifffile.imwrite(output_path, masks)
Cellpose Segmentation: cytoplasm
# Run Cellpose on each image one by one
# Create a subfolder to save the cell segmentation results
cell_folder = folder_path / "cell_labels"
cell_folder.mkdir(exist_ok=True)
# NOTE: tqdm is used to show a progress bar, but you can remove it if you don't want it
for image_path in tqdm(images_path, desc="Processing images"):
# Load the image
image = io.imread(image_path)
# select the channels to segement from the multichannel image
nuc_cell_image = image[[0, 1]]
# Run Cellpose on the image
masks, flows, styles = model.eval(nuc_cell_image)
# Save the segmentation results as a TIFF file
output_path = cell_folder / f"{image_path.stem}_cell_labels.tif"
io.imsave(output_path, masks) # or tifffile.imwrite(output_path, masks)
Step 4#
In this step you need to add the code that detects spots in the 4th channels of all the images in the dataset using Spotiflow and saves a .csv file of their coordinates.
For each step, create a new
codecell in the notebook (+button).Within the cell, add the necessary code.
Import Dependencies
import csv
import numpy as np
import tifffile
from spotiflow.model import Spotiflow
Load Images
# specify the channels you want to process in predict_multichannel()
channels = 3 # can be a tuple or an int
Initialize Model
# Initialize the model once before the loop
model = Spotiflow.from_pretrained("general")
Define Function to Save Spot Coordinates as a CSV File
def save_points_as_csv(points, output_path="points.csv", channel_last=False) -> None:
"""Save points as a napari-compatible CSV (drag-and-drop as Points layer).
napari maps the CSV columns (axis-0, axis-1, ...) to the layer axes in order.
`predict_multichannel` returns the channel as the *last* column (e.g. (y, x, channel)),
so set `channel_last=True` to move it to the front (e.g. (channel, y, x)) and have the
spots line up with a channel-first (C, ...) image in napari.
"""
points = np.asarray(points)
if channel_last:
# move the last column (channel) to the front
points = points[:, [-1, *range(points.shape[1] - 1)]]
ndim = points.shape[1]
headers = ["index"] + [f"axis-{i}" for i in range(ndim)]
with open(output_path, "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(headers)
for i, p in enumerate(points):
writer.writerow([i, *p])
Use Spotiflow to Detect Spots & Save their Coordinates in a CSV file
# Create a subfolder to save the spot detection results
spot_folder = folder_path / "spotiflow_points"
spot_folder.mkdir(exist_ok=True)
# NOTE: tqdm is used to show a progress bar, but you can remove it if you don't want it
for image_path in tqdm(images_path, desc="Processing images"):
# Load the image
image = tifffile.imread(image_path)
# Transpose the image to channel-last format for `predict_multichannel`
tr_image = image.transpose(1, 2, 0) # (C, Y, X) -> (Y, X, C)
# Run Spotiflow on the image
points, details = model.predict_multichannel(tr_image, channels=channels)
# Save the points as a CSV file
output_path = spot_folder / f"{image_path.stem}_points.csv"
save_points_as_csv(points, str(output_path), channel_last=True)