Cell tracking example#
This example demonstrates how the track layer is used for visualizing cell tracking data, by displaying 2D + time dataset of cells with colored properties for track-id.
Thanks to Dr. Alessia Ruggieri and Philipp Klein, Centre for Integrative Infectious Disease Research (CIID), University Hospital Heidelberg, Germany for the data. You can find the data on: https://doi.org/10.5281/zenodo.15597019
Extra packages required
This example requires additional packages that are not available in typical
napari installations.
For this example to work in recommended napari installations,
you will need to install additional packages: trackastra.
See the plugin manager guide
for ways to install additional packages from within napari.
Downloading...
From: https://drive.google.com/uc?id=1tuHI_io67gVdFZBA5E97fXrAWaxI2cqi
To: /home/runner/work/docs/docs/.cache/napari cell tracking example/tmpybwi2mwe
0%| | 0.00/455k [00:00<?, ?B/s]
100%|██████████| 455k/455k [00:00<00:00, 6.25MB/s]
Downloading...
From: https://drive.google.com/uc?id=1qhAbIZiEKfo_a38YFtw7KJ3JjEhicDeJ
To: /home/runner/work/docs/docs/.cache/napari_cell_tracking_example/tmph_tn1ga7
0%| | 0.00/15.7M [00:00<?, ?B/s]
30%|██▉ | 4.72M/15.7M [00:00<00:00, 37.3MB/s]
100%|██████████| 15.7M/15.7M [00:00<00:00, 87.0MB/s]
/tmp/tmp7bm8vyup/general_2d.zip: 0%| | 0.00/38.0M [00:00<?, ?iB/s]
/tmp/tmp7bm8vyup/general_2d.zip: 26%|██▌ | 9.80M/38.0M [00:00<00:00, 103MiB/s]
/tmp/tmp7bm8vyup/general_2d.zip: 56%|█████▌ | 21.2M/38.0M [00:00<00:00, 112MiB/s]
/tmp/tmp7bm8vyup/general_2d.zip: 86%|████████▌ | 32.7M/38.0M [00:00<00:00, 116MiB/s]
/tmp/tmp7bm8vyup/general_2d.zip: 100%|██████████| 38.0M/38.0M [00:00<00:00, 115MiB/s]
Extracting features: 0%| | 0/30 [00:00<?, ?it/s]
Extracting features: 17%|█▋ | 5/30 [00:00<00:00, 49.44it/s]
Extracting features: 33%|███▎ | 10/30 [00:00<00:00, 49.76it/s]
Extracting features: 53%|█████▎ | 16/30 [00:00<00:00, 50.57it/s]
Extracting features: 73%|███████▎ | 22/30 [00:00<00:00, 49.88it/s]
Extracting features: 90%|█████████ | 27/30 [00:00<00:00, 49.91it/s]
Extracting features: 100%|██████████| 30/30 [00:00<00:00, 50.42it/s]
Building windows: 0%| | 0/27 [00:00<?, ?it/s]
Building windows: 100%|██████████| 27/27 [00:00<00:00, 15384.62it/s]
Computing associations: 0%| | 0/27 [00:00<?, ?it/s]
Computing associations: 11%|█ | 3/27 [00:00<00:00, 24.78it/s]
Computing associations: 22%|██▏ | 6/27 [00:00<00:00, 25.01it/s]
Computing associations: 33%|███▎ | 9/27 [00:00<00:00, 25.09it/s]
Computing associations: 44%|████▍ | 12/27 [00:00<00:00, 25.38it/s]
Computing associations: 56%|█████▌ | 15/27 [00:00<00:00, 25.26it/s]
Computing associations: 67%|██████▋ | 18/27 [00:00<00:00, 24.92it/s]
Computing associations: 78%|███████▊ | 21/27 [00:00<00:00, 24.64it/s]
Computing associations: 89%|████████▉ | 24/27 [00:00<00:00, 24.80it/s]
Computing associations: 100%|██████████| 27/27 [00:01<00:00, 25.19it/s]
Computing associations: 100%|██████████| 27/27 [00:01<00:00, 25.05it/s]
0%| | 0/30 [00:00<?, ?it/s]
29 edges in frame 0 Total edges: 29: 0%| | 0/30 [00:00<?, ?it/s]
25 edges in frame 1 Total edges: 54: 0%| | 0/30 [00:00<?, ?it/s]
25 edges in frame 2 Total edges: 79: 0%| | 0/30 [00:00<?, ?it/s]
30 edges in frame 3 Total edges: 109: 0%| | 0/30 [00:00<?, ?it/s]
29 edges in frame 4 Total edges: 138: 0%| | 0/30 [00:00<?, ?it/s]
29 edges in frame 5 Total edges: 167: 0%| | 0/30 [00:00<?, ?it/s]
29 edges in frame 6 Total edges: 196: 0%| | 0/30 [00:00<?, ?it/s]
31 edges in frame 7 Total edges: 227: 0%| | 0/30 [00:00<?, ?it/s]
31 edges in frame 8 Total edges: 258: 0%| | 0/30 [00:00<?, ?it/s]
30 edges in frame 9 Total edges: 288: 0%| | 0/30 [00:00<?, ?it/s]
29 edges in frame 10 Total edges: 317: 0%| | 0/30 [00:00<?, ?it/s]
28 edges in frame 11 Total edges: 345: 0%| | 0/30 [00:00<?, ?it/s]
27 edges in frame 12 Total edges: 372: 0%| | 0/30 [00:00<?, ?it/s]
28 edges in frame 13 Total edges: 400: 0%| | 0/30 [00:00<?, ?it/s]
31 edges in frame 14 Total edges: 431: 0%| | 0/30 [00:00<?, ?it/s]
31 edges in frame 15 Total edges: 462: 0%| | 0/30 [00:00<?, ?it/s]
30 edges in frame 16 Total edges: 492: 0%| | 0/30 [00:00<?, ?it/s]
30 edges in frame 17 Total edges: 522: 0%| | 0/30 [00:00<?, ?it/s]
31 edges in frame 18 Total edges: 553: 0%| | 0/30 [00:00<?, ?it/s]
31 edges in frame 19 Total edges: 584: 0%| | 0/30 [00:00<?, ?it/s]
30 edges in frame 20 Total edges: 614: 0%| | 0/30 [00:00<?, ?it/s]
33 edges in frame 21 Total edges: 647: 0%| | 0/30 [00:00<?, ?it/s]
32 edges in frame 22 Total edges: 679: 0%| | 0/30 [00:00<?, ?it/s]
31 edges in frame 23 Total edges: 710: 0%| | 0/30 [00:00<?, ?it/s]
30 edges in frame 24 Total edges: 740: 0%| | 0/30 [00:00<?, ?it/s]
28 edges in frame 25 Total edges: 768: 0%| | 0/30 [00:00<?, ?it/s]
28 edges in frame 26 Total edges: 796: 0%| | 0/30 [00:00<?, ?it/s]
28 edges in frame 27 Total edges: 824: 0%| | 0/30 [00:00<?, ?it/s]
27 edges in frame 28 Total edges: 851: 0%| | 0/30 [00:00<?, ?it/s]
Greedily matched edges: 0%| | 0/851 [00:00<?, ?it/s]
Greedily matched edges: 99%|█████████▉| 845/851 [00:00<00:00, 182051.93it/s]
Converting graph to CTC results: 0%| | 0/53 [00:00<?, ?it/s]
Converting graph to CTC results: 100%|██████████| 53/53 [00:00<00:00, 1664.92it/s]
Computing centroids: 0%| | 0/30 [00:00<?, ?it/s]
Computing centroids: 67%|██████▋ | 20/30 [00:00<00:00, 193.18it/s]
Converting CTC to napari tracks: 0%| | 0/53 [00:00<?, ?it/s]
from pathlib import Path
import numpy as np
import pooch
import tifffile
from trackastra.model import Trackastra
from trackastra.tracking import ctc_to_napari_tracks, graph_to_ctc
import napari
# Create temporary directory
tmp_dir = Path(pooch.os_cache('napari-cell-tracking-example'))
tmp_dir.mkdir(parents=True, exist_ok=True)
# Extract silver truth data for trackastra
st_url = "doi:10.5281/zenodo.15852284/masks_pred.npz"
st_path = pooch.retrieve(
url=st_url,
fname="masks_pred.npz",
known_hash=None,
path=pooch.os_cache("napari cell tracking example")
)
# Extract raw tif files for trackastra
tif_url = "doi:10.5281/zenodo.17643282/01(1).zip"
tif_file = pooch.retrieve(
url=tif_url,
fname="01(1).zip",
known_hash=None,
path=pooch.os_cache("napari_cell_tracking_example"),
processor=pooch.Unzip(),
)
# Load the downloaded masks
masks_npz = np.load(st_path)
masks = masks_npz['masks']
# Sort through images and stack them
imgs = sorted(tif_file)
images = np.stack([
tifffile.imread(fn) for fn in imgs
])
# Initiate trackastra model
model = Trackastra.from_pretrained("general_2d", device='cpu')
# Generate tracks
graph, *_ = model.track(imgs=images, masks=masks, mode='greedy')
tracks_df, tracked_masks = graph_to_ctc(graph=graph, masks_original=masks)
napari_tracks, napari_graph = ctc_to_napari_tracks(segmentation=tracked_masks, man_track=tracks_df)
# Add Napari viewer
viewer = napari.Viewer()
viewer.add_image(images, name='Images')
viewer.add_labels(masks, name='Predicted Masks')
viewer.add_tracks(napari_tracks, graph=napari_graph, name="Tracks")
if __name__ == "__main__":
napari.run()
Total running time of the script: (0 minutes 16.328 seconds)