Segmenting G4X-data
Here, we lay out a basic approach to resegment your G4X-data. We strongly encourage you to start this process by looking at the existing segmentation using our G4X-viewer. This will allow you to identify where it fails to capture your desired cell morphology.
These instructions are designed to help you take the .jp2 images described in the G4X-data output documentation and run your own segmentation using Cellpose 2. This is typically an iterative process.
Basic segmentation approach
For this tutorial, we use the most basic Cellpose arguments. It is strongly encouraged that you look into the Cellpose documentation for more advanced options that may suit your needs.
1. Import libraries
import numpy as np
import glymur
from cellpose import models
from cellpose.models import CellposeModel
from skimage.exposure import rescale_intensity
2. Choose which type of segmentation you want to run
3. Load the .jp2 image using glymur
4. Normalize your nuclear image to the range 0-1
5. Run nuclear segmentation
3. Load the .jp2 images using glymur
# --- Load JP2 Images ---
nuclear = glymur.Jp2k("path/to/nuclear.jp2")[:]
marker1 = glymur.Jp2k("path/to/marker1.jp2")[:]
4. Normalize each image channel to the range 0-1
# --- Normalize each channel separately ---
nuclear_norm = rescale_intensity(nuclear, out_range=(0, 1))
marker1_norm = rescale_intensity(marker1, out_range=(0, 1))
5. Stack your channels for Cellpose input
# --- Stack channels: marker1_norm = channel 0, nuclear = channel 1 ---
input_img = np.stack([marker1_norm, nuclear_norm], axis=2)
6. Run Cyto3 segmentation
3. Load the .jp2 images using glymur
# --- Load JP2 Images ---
nuclear = glymur.Jp2k("path/to/nuclear.jp2")[:]
marker1 = glymur.Jp2k("path/to/marker1.jp2")[:]
marker2 = glymur.Jp2k("path/to/marker2.jp2")[:]
4. Normalize each image channel to the range 0-1
# --- Normalize each channel separately ---
nuclear_norm = rescale_intensity(nuclear, out_range=(0, 1))
marker1_norm = rescale_intensity(marker1, out_range=(0, 1))
marker2_norm = rescale_intensity(marker2, out_range=(0, 1))
5. Perform averaging of markers to create a combined membrane channel
6. Stack your channels for Cellpose input
# --- Stack channels: membrane = channel 0, nuclear = channel 1 ---
input_img = np.stack([membrane_combo, nuclear_norm], axis=2)
7. Run Cyto3 segmentation
Iterating on your segmentation
After you've generated your segmentation masks, you sould take time to visualize them and determine if they are meeting your needs. This is an iterative process that may take several rounds of tuning.
To save time, you may want to consider using some basic python plotting as well as subsetting your data to speed up iteration. Below are examples of each.
Visualize your segmentation
Here is a snippet of code to visualize your segmentation masks overlaid on a single fluorescent image. Notably, the variable this uses are:
marker_image: a single fluorescent image (e.g. nuclear or membrane) to show the cell outlines against (same dimensions asmasks)masks: the generated segmentation masks from Cellpose
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,8))
# Show the fluorescent image in blue with a bit of transparency
vmax = np.percentile(marker_image, 99) # remove hot pixels
plt.imshow(
marker_image,
cmap="Blues", vmin=0, vmax=vmax, alpha=0.8, origin="lower"
)
# Draw one contour around each labeled cell
# using half-integer levels to outline integer labels cleanly
levels = np.arange(0.5, masks.max() + 0.5, 1.0)
plt.contour(masks, levels=levels, colors="gray",
linewidths=0.7, origin="lower")
plt.axis("off")
plt.tight_layout()
plt.show()
Subset your images
Since this process can take quite a while on our stitched images, you may want to try to hone your approach first on a smaller, cropped image. For example, after loading your .jp2 image(s), you can subset them with something like this, running your segmentation on that block only:
sz = 1000 # max size of your subset block
# get the image size
x = marker_norm.shape[0]
y = marker_norm.shape[1]
# take the middle 1000 x 1000 pixel block
marker_subset = marker_norm[int((y/2)-int(sz/2)):int((y/2)+int(sz/2)),
int((x/2)-int(sz/2)):int((x/2)+int(sz/2))]
Applying your segmentation
Once you are happy with the outputs, you are ready to save them and run our G4X-helpers tool to regenerate your single cell data using your new segmentation masks.
Save your segmentation masks
# ---- Save generated masks ----
np.save("/path/to/output/folder/resegmented_masks.npy", masks)
np.savez_compressed("/path/to/output/folder/resegmented_masks.npz",
nuclei=masks, nuclei_exp=masks)
Regenerate your G4X outputs
After you have a segmentation that you are happy with, use out resegmentation tool to regenerate it for each tissue block. For installation tips, see our guide on installing G4X-helpers. For advanced usage tips, see our resegment documentation.
resegment
--run_base /path/to/data/dir/<block_id>
--segmentation_mask /path/to/new/masks.npy
--out_dir /path/to/output/dir/
βΈ»