How to register a temporal sequence of intensity images¶
Introduction¶
Aim & explanations¶
This how-to aims at explaining how to performs image registration for a temporal sequence of intensity images, also called time-series, using the dedicated plugin from timagetk
’s plugins
module.
There are several reasons for which you would like and should performs a time-series temporal registration prior to a quantitative analysis but most importantly, it will give you a growth centered view of the time series and a temporally coherent view of the observed process.
Implications are:
sequence animations will be centered on the object;
subsequent deformation analysis, such as cell displacement or cell growth quantifications, will also benefit from it.
It should be noted that if its biologicaly relevant and you have the means of doing it, using a fixed reference point should be doable with create_trsf
using the fixed_point
keyword parameter…
Import the required classes & functions¶
%matplotlib inline
from timagetk.components.multi_channel import BlendImage
from timagetk.components.multi_channel import MultiChannelImage
from timagetk.tasks.registration import sequence_registration
from timagetk.io import imread
from timagetk.io.image import _image_from_url
from timagetk.visu.mplt import grayscale_imshow
/builds/J-gEBwyb/0/mosaic/timagetk/src/timagetk/components/labelled_image.py:31: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from tqdm.autonotebook import tqdm
Note that the first line %matplotlib inline
is only required here in the jupyter notebook to display matplotlib figures.
Load time-series of grayscale images¶
file_urls = [
"https://zenodo.org/record/7151866/files/p58-t0-imgFus.inr.gz",
"https://zenodo.org/record/7151866/files/p58-t1-imgFus.inr.gz",
"https://zenodo.org/record/7151866/files/p58-t2-imgFus.inr.gz"
]
file_hashs = [
"48f6f9924289037c55ea785273c2fe72",
"377dfa1b2aaf2471e5f8ab5655ef7610",
"0c08a63c0966bd5655e4676893dd1068"
]
fnames = [_image_from_url(url ,hash_value=md5_hash, hash_method='md5') for url, md5_hash in zip(file_urls, file_hashs)]
0%| | 0.00/74.7M [00:00<?, ?B/s]
1%|▏ | 1.09M/74.7M [00:00<00:07, 10.6MB/s]
3%|▎ | 2.12M/74.7M [00:00<00:07, 10.0MB/s]
4%|▍ | 3.19M/74.7M [00:00<00:07, 10.3MB/s]
6%|▌ | 4.19M/74.7M [00:00<00:07, 10.1MB/s]
7%|▋ | 5.16M/74.7M [00:00<00:07, 10.0MB/s]
8%|▊ | 6.12M/74.7M [00:00<00:07, 9.86MB/s]
10%|▉ | 7.09M/74.7M [00:00<00:07, 9.92MB/s]
11%|█ | 8.09M/74.7M [00:00<00:07, 9.92MB/s]
12%|█▏ | 9.06M/74.7M [00:00<00:06, 9.84MB/s]
14%|█▎ | 10.2M/74.7M [00:01<00:06, 10.3MB/s]
15%|█▍ | 11.2M/74.7M [00:01<00:06, 9.71MB/s]
16%|█▋ | 12.2M/74.7M [00:01<00:06, 9.99MB/s]
18%|█▊ | 13.2M/74.7M [00:01<00:06, 10.1MB/s]
19%|█▉ | 14.2M/74.7M [00:01<00:06, 9.92MB/s]
20%|██ | 15.2M/74.7M [00:01<00:06, 9.86MB/s]
22%|██▏ | 16.2M/74.7M [00:01<00:06, 9.94MB/s]
23%|██▎ | 17.2M/74.7M [00:01<00:06, 9.73MB/s]
24%|██▍ | 18.3M/74.7M [00:01<00:05, 10.3MB/s]
26%|██▌ | 19.3M/74.7M [00:02<00:05, 10.1MB/s]
27%|██▋ | 20.3M/74.7M [00:02<00:05, 10.0MB/s]
28%|██▊ | 21.2M/74.7M [00:02<00:05, 9.97MB/s]
30%|██▉ | 22.2M/74.7M [00:02<00:05, 10.1MB/s]
31%|███ | 23.2M/74.7M [00:02<00:05, 10.1MB/s]
32%|███▏ | 24.2M/74.7M [00:02<00:05, 10.2MB/s]
34%|███▍ | 25.2M/74.7M [00:02<00:05, 10.1MB/s]
35%|███▌ | 26.2M/74.7M [00:02<00:05, 10.1MB/s]
37%|███▋ | 27.3M/74.7M [00:02<00:04, 10.3MB/s]
38%|███▊ | 28.3M/74.7M [00:02<00:04, 9.89MB/s]
39%|███▉ | 29.3M/74.7M [00:03<00:04, 10.1MB/s]
41%|████ | 30.3M/74.7M [00:03<00:04, 9.78MB/s]
42%|████▏ | 31.2M/74.7M [00:03<00:04, 9.82MB/s]
43%|████▎ | 32.2M/74.7M [00:03<00:04, 9.95MB/s]
45%|████▍ | 33.2M/74.7M [00:03<00:04, 10.0MB/s]
46%|████▌ | 34.3M/74.7M [00:03<00:04, 10.3MB/s]
48%|████▊ | 35.5M/74.7M [00:03<00:03, 10.5MB/s]
49%|████▉ | 36.5M/74.7M [00:03<00:03, 10.5MB/s]
50%|█████ | 37.6M/74.7M [00:03<00:03, 10.5MB/s]
52%|█████▏ | 38.6M/74.7M [00:04<00:03, 10.4MB/s]
53%|█████▎ | 39.6M/74.7M [00:04<00:03, 10.5MB/s]
54%|█████▍ | 40.7M/74.7M [00:04<00:03, 10.5MB/s]
56%|█████▌ | 41.7M/74.7M [00:04<00:03, 10.4MB/s]
57%|█████▋ | 42.7M/74.7M [00:04<00:03, 10.3MB/s]
58%|█████▊ | 43.7M/74.7M [00:04<00:03, 9.98MB/s]
60%|█████▉ | 44.6M/74.7M [00:04<00:03, 9.79MB/s]
61%|██████ | 45.7M/74.7M [00:04<00:03, 10.0MB/s]
63%|██████▎ | 46.7M/74.7M [00:04<00:02, 10.3MB/s]
64%|██████▍ | 47.8M/74.7M [00:04<00:02, 10.4MB/s]
65%|██████▌ | 48.8M/74.7M [00:05<00:02, 10.4MB/s]
67%|██████▋ | 49.8M/74.7M [00:05<00:02, 10.5MB/s]
68%|██████▊ | 50.9M/74.7M [00:05<00:02, 10.5MB/s]
70%|██████▉ | 51.9M/74.7M [00:05<00:02, 10.5MB/s]
71%|███████ | 53.1M/74.7M [00:05<00:02, 10.9MB/s]
73%|███████▎ | 54.2M/74.7M [00:05<00:02, 10.3MB/s]
74%|███████▍ | 55.2M/74.7M [00:05<00:01, 10.3MB/s]
75%|███████▌ | 56.3M/74.7M [00:05<00:01, 10.4MB/s]
77%|███████▋ | 57.3M/74.7M [00:05<00:01, 10.4MB/s]
78%|███████▊ | 58.3M/74.7M [00:06<00:01, 10.3MB/s]
79%|███████▉ | 59.3M/74.7M [00:06<00:01, 10.3MB/s]
81%|████████ | 60.3M/74.7M [00:06<00:01, 10.4MB/s]
82%|████████▏ | 61.3M/74.7M [00:06<00:01, 10.3MB/s]
84%|████████▎ | 62.4M/74.7M [00:06<00:01, 10.6MB/s]
85%|████████▌ | 63.5M/74.7M [00:06<00:01, 10.6MB/s]
86%|████████▋ | 64.5M/74.7M [00:06<00:01, 10.6MB/s]
88%|████████▊ | 65.6M/74.7M [00:06<00:00, 10.5MB/s]
89%|████████▉ | 66.6M/74.7M [00:06<00:00, 10.5MB/s]
91%|█████████ | 67.7M/74.7M [00:06<00:00, 10.6MB/s]
92%|█████████▏| 68.7M/74.7M [00:07<00:00, 10.7MB/s]
93%|█████████▎| 69.8M/74.7M [00:07<00:00, 10.3MB/s]
95%|█████████▍| 70.8M/74.7M [00:07<00:00, 9.82MB/s]
96%|█████████▌| 71.8M/74.7M [00:07<00:00, 10.0MB/s]
98%|█████████▊| 72.9M/74.7M [00:07<00:00, 10.5MB/s]
99%|█████████▉| 74.0M/74.7M [00:07<00:00, 10.6MB/s]
74.7MB [00:07, 10.2MB/s]
0%| | 0.00/110M [00:00<?, ?B/s]
1%| | 1.00M/110M [00:00<00:11, 10.0MB/s]
2%|▏ | 2.09M/110M [00:00<00:10, 10.8MB/s]
3%|▎ | 3.19M/110M [00:00<00:10, 10.9MB/s]
4%|▍ | 4.25M/110M [00:00<00:10, 10.9MB/s]
5%|▍ | 5.31M/110M [00:00<00:10, 10.8MB/s]
6%|▌ | 6.34M/110M [00:00<00:10, 10.7MB/s]
7%|▋ | 7.38M/110M [00:00<00:10, 10.1MB/s]
8%|▊ | 8.41M/110M [00:00<00:10, 10.2MB/s]
9%|▊ | 9.56M/110M [00:00<00:09, 10.7MB/s]
10%|▉ | 10.7M/110M [00:01<00:09, 10.8MB/s]
11%|█ | 11.7M/110M [00:01<00:09, 10.8MB/s]
12%|█▏ | 12.9M/110M [00:01<00:09, 11.1MB/s]
13%|█▎ | 14.0M/110M [00:01<00:09, 11.1MB/s]
14%|█▎ | 15.0M/110M [00:01<00:09, 11.0MB/s]
15%|█▍ | 16.2M/110M [00:01<00:08, 11.1MB/s]
16%|█▌ | 17.2M/110M [00:01<00:08, 11.1MB/s]
17%|█▋ | 18.3M/110M [00:01<00:08, 11.1MB/s]
18%|█▊ | 19.4M/110M [00:01<00:08, 11.0MB/s]
19%|█▊ | 20.4M/110M [00:01<00:08, 11.1MB/s]
20%|█▉ | 21.5M/110M [00:02<00:08, 11.0MB/s]
21%|██ | 22.7M/110M [00:02<00:07, 11.5MB/s]
22%|██▏ | 23.8M/110M [00:02<00:07, 11.3MB/s]
23%|██▎ | 24.9M/110M [00:02<00:08, 10.9MB/s]
24%|██▎ | 26.0M/110M [00:02<00:08, 11.0MB/s]
25%|██▍ | 27.0M/110M [00:02<00:08, 10.6MB/s]
26%|██▌ | 28.2M/110M [00:02<00:07, 10.9MB/s]
27%|██▋ | 29.2M/110M [00:02<00:07, 10.9MB/s]
28%|██▊ | 30.3M/110M [00:02<00:07, 10.5MB/s]
28%|██▊ | 31.3M/110M [00:03<00:07, 10.5MB/s]
29%|██▉ | 32.4M/110M [00:03<00:07, 10.7MB/s]
30%|███ | 33.5M/110M [00:03<00:07, 10.8MB/s]
31%|███▏ | 34.6M/110M [00:03<00:07, 10.9MB/s]
32%|███▏ | 35.7M/110M [00:03<00:07, 11.0MB/s]
33%|███▎ | 36.8M/110M [00:03<00:07, 10.6MB/s]
34%|███▍ | 37.9M/110M [00:03<00:06, 10.9MB/s]
35%|███▌ | 39.0M/110M [00:03<00:06, 11.0MB/s]
36%|███▋ | 40.1M/110M [00:03<00:06, 11.0MB/s]
37%|███▋ | 41.2M/110M [00:03<00:06, 11.3MB/s]
38%|███▊ | 42.3M/110M [00:04<00:06, 11.2MB/s]
39%|███▉ | 43.4M/110M [00:04<00:06, 11.2MB/s]
40%|████ | 44.5M/110M [00:04<00:06, 10.9MB/s]
41%|████▏ | 45.6M/110M [00:04<00:06, 10.8MB/s]
42%|████▏ | 46.7M/110M [00:04<00:05, 11.1MB/s]
43%|████▎ | 47.8M/110M [00:04<00:05, 11.2MB/s]
45%|████▍ | 49.0M/110M [00:04<00:05, 11.3MB/s]
46%|████▌ | 50.1M/110M [00:04<00:05, 11.3MB/s]
47%|████▋ | 51.2M/110M [00:04<00:05, 11.4MB/s]
48%|████▊ | 52.3M/110M [00:05<00:05, 11.3MB/s]
49%|████▊ | 53.4M/110M [00:05<00:05, 11.2MB/s]
50%|████▉ | 54.6M/110M [00:05<00:05, 11.5MB/s]
51%|█████ | 55.7M/110M [00:05<00:04, 11.5MB/s]
52%|█████▏ | 56.8M/110M [00:05<00:04, 11.6MB/s]
53%|█████▎ | 57.9M/110M [00:05<00:04, 11.3MB/s]
54%|█████▎ | 59.0M/110M [00:05<00:04, 10.9MB/s]
55%|█████▍ | 60.1M/110M [00:05<00:04, 10.9MB/s]
56%|█████▌ | 61.2M/110M [00:05<00:04, 11.0MB/s]
57%|█████▋ | 62.3M/110M [00:05<00:04, 11.2MB/s]
58%|█████▊ | 63.5M/110M [00:06<00:04, 11.1MB/s]
59%|█████▊ | 64.6M/110M [00:06<00:04, 11.2MB/s]
60%|█████▉ | 65.8M/110M [00:06<00:04, 11.4MB/s]
61%|██████ | 66.8M/110M [00:06<00:03, 11.4MB/s]
62%|██████▏ | 68.0M/110M [00:06<00:03, 11.5MB/s]
63%|██████▎ | 69.1M/110M [00:06<00:03, 11.1MB/s]
64%|██████▍ | 70.2M/110M [00:06<00:03, 11.2MB/s]
65%|██████▍ | 71.4M/110M [00:06<00:03, 11.3MB/s]
66%|██████▌ | 72.5M/110M [00:06<00:03, 11.4MB/s]
67%|██████▋ | 73.6M/110M [00:07<00:03, 11.0MB/s]
68%|██████▊ | 74.7M/110M [00:07<00:03, 10.9MB/s]
69%|██████▉ | 75.7M/110M [00:07<00:03, 10.8MB/s]
70%|██████▉ | 76.9M/110M [00:07<00:03, 11.2MB/s]
71%|███████ | 78.1M/110M [00:07<00:02, 11.4MB/s]
72%|███████▏ | 79.2M/110M [00:07<00:02, 11.6MB/s]
73%|███████▎ | 80.4M/110M [00:07<00:02, 11.5MB/s]
74%|███████▍ | 81.5M/110M [00:07<00:02, 11.1MB/s]
75%|███████▌ | 82.6M/110M [00:07<00:02, 11.0MB/s]
76%|███████▌ | 83.7M/110M [00:07<00:02, 11.2MB/s]
77%|███████▋ | 84.8M/110M [00:08<00:02, 11.1MB/s]
78%|███████▊ | 86.0M/110M [00:08<00:02, 11.3MB/s]
79%|███████▉ | 87.1M/110M [00:08<00:02, 11.3MB/s]
80%|████████ | 88.2M/110M [00:08<00:02, 11.0MB/s]
81%|████████ | 89.3M/110M [00:08<00:01, 11.2MB/s]
82%|████████▏ | 90.4M/110M [00:08<00:01, 11.1MB/s]
83%|████████▎ | 91.5M/110M [00:08<00:01, 10.8MB/s]
84%|████████▍ | 92.6M/110M [00:08<00:01, 10.8MB/s]
85%|████████▌ | 93.6M/110M [00:08<00:01, 10.7MB/s]
86%|████████▌ | 94.8M/110M [00:08<00:01, 11.0MB/s]
87%|████████▋ | 95.9M/110M [00:09<00:01, 11.2MB/s]
88%|████████▊ | 97.1M/110M [00:09<00:01, 11.5MB/s]
89%|████████▉ | 98.3M/110M [00:09<00:01, 11.7MB/s]
90%|█████████ | 99.5M/110M [00:09<00:00, 11.7MB/s]
91%|█████████▏| 101M/110M [00:09<00:00, 11.6MB/s]
92%|█████████▏| 102M/110M [00:09<00:00, 11.5MB/s]
93%|█████████▎| 103M/110M [00:09<00:00, 11.5MB/s]
94%|█████████▍| 104M/110M [00:09<00:00, 11.5MB/s]
95%|█████████▌| 105M/110M [00:09<00:00, 11.3MB/s]
96%|█████████▋| 106M/110M [00:10<00:00, 10.9MB/s]
97%|█████████▋| 107M/110M [00:10<00:00, 10.9MB/s]
98%|█████████▊| 108M/110M [00:10<00:00, 11.1MB/s]
99%|█████████▉| 109M/110M [00:10<00:00, 11.0MB/s]
110MB [00:10, 11.1MB/s]
images = [imread(fname) for fname in fnames]
Down-sample the images to speed-up the computations¶
from timagetk.algorithms.resample import resample
print("# - Voxelsize (ZYX) for the initial image list:")
print("\n".join([f"Image '{im.filename}' (#{n}): {im.voxelsize}" for n, im in enumerate(images)]))
print("# - Shape (ZYX) for the initial image list:")
print("\n".join([f"Image '{im.filename}' (#{n}): {im.shape}" for n, im in enumerate(images)]))
# - Voxelsize (ZYX) for the initial image list:
Image 'p58-t0-imgFus.inr.gz' (#0): [0.20032000541687012, 0.20032000541687012, 0.20032000541687012]
Image 'p58-t1-imgFus.inr.gz' (#1): [0.2002449929714203, 0.2002449929714203, 0.2002449929714203]
Image 'p58-t2-imgFus.inr.gz' (#2): [0.1990640014410019, 0.1990640014410019, 0.1990640014410019]
# - Shape (ZYX) for the initial image list:
Image 'p58-t0-imgFus.inr.gz' (#0): (320, 460, 460)
Image 'p58-t1-imgFus.inr.gz' (#1): (360, 576, 576)
Image 'p58-t2-imgFus.inr.gz' (#2): (352, 772, 772)
images = [resample(im, voxelsize=[1., 0.5, 0.5]) for im in images]
INFO [timagetk.algorithms.resample] Resampling using provided voxel-sizes: [1.0, 0.5, 0.5]
INFO [timagetk.algorithms.resample] Resampling using provided voxel-sizes: [1.0, 0.5, 0.5]
INFO [timagetk.algorithms.resample] Resampling using provided voxel-sizes: [1.0, 0.5, 0.5]
print("# - Voxelsize (ZYX) for the resampled image list:")
print("\n".join([f"Image '{im.filename}' (#{n}): {im.voxelsize}" for n, im in enumerate(images)]))
print("# - Shape (ZYX) for the resampled image list:")
print("\n".join([f"Image '{im.filename}' (#{n}): {im.shape}" for n, im in enumerate(images)]))
# - Voxelsize (ZYX) for the resampled image list:
Image 'p58-t0-imgFus.inr.gz' (#0): [1.0, 0.5, 0.5]
Image 'p58-t1-imgFus.inr.gz' (#1): [1.0, 0.5, 0.5]
Image 'p58-t2-imgFus.inr.gz' (#2): [1.0, 0.5, 0.5]
# - Shape (ZYX) for the resampled image list:
Image 'p58-t0-imgFus.inr.gz' (#0): (64, 184, 184)
Image 'p58-t1-imgFus.inr.gz' (#1): (72, 231, 231)
Image 'p58-t2-imgFus.inr.gz' (#2): (70, 307, 307)
Visualize the time-series¶
_=grayscale_imshow(images, suptitle="Unregistered time-series", title=fnames, val_range=[0, 255])
0%| | 0/3 [00:00<?, ?image/s]
33%|███▎ | 1/3 [00:04<00:08, 4.26s/image]
67%|██████▋ | 2/3 [00:09<00:04, 4.71s/image]
100%|██████████| 3/3 [00:15<00:00, 5.36s/image]
100%|██████████| 3/3 [00:15<00:00, 5.14s/image]
Performs sequence rigid registration¶
trsfs, res_imgs = sequence_registration(images, method='rigid')
INFO [timagetk.tasks.registration] Performing consecutive image registration...
INFO [timagetk.algorithms.blockmatching] RIGID registration
- processing level # 3
- Iteration # 1 Level # 3 Size 32x 32x 1
- Iteration # 2 Level # 3 Size 32x 32x 1
- Iteration # 3 Level # 3 Size 32x 32x 1
- Iteration # 4 Level # 3 Size 32x 32x 1
- Iteration # 5 Level # 3 Size 32x 32x 1
- Iteration # 6 Level # 3 Size 32x 32x 1
- Iteration # 7 Level # 3 Size 32x 32x 1
- Iteration # 8 Level # 3 Size 32x 32x 1
- Iteration # 9 Level # 3 Size 32x 32x 1
- Iteration # 10 Level # 3 Size 32x 32x 1
- processing level # 2
- Iteration # 1 Level # 2 Size 64x 64x 1
- Iteration # 2 Level # 2 Size 64x 64x 1
- Iteration # 3 Level # 2 Size 64x 64x 1
- Iteration # 4 Level # 2 Size 64x 64x 1
- Iteration # 5 Level # 2 Size 64x 64x 1
- Iteration # 6 Level # 2 Size 64x 64x 1
- Iteration # 7 Level # 2 Size 64x 64x 1
- Iteration # 8 Level # 2 Size 64x 64x 1
- Iteration # 9 Level # 2 Size 64x 64x 1
- Iteration # 10 Level # 2 Size 64x 64x 1
INFO [timagetk.algorithms.blockmatching] RIGID registration
- processing level # 4
- Iteration # 1 Level # 4 Size 32x 32x 1
- Iteration # 2 Level # 4 Size 32x 32x 1
- Iteration # 3 Level # 4 Size 32x 32x 1
- Iteration # 4 Level # 4 Size 32x 32x 1
- Iteration # 5 Level # 4 Size 32x 32x 1
- Iteration # 6 Level # 4 Size 32x 32x 1
- Iteration # 7 Level # 4 Size 32x 32x 1
- Iteration # 8 Level # 4 Size 32x 32x 1
- Iteration # 9 Level # 4 Size 32x 32x 1
- Iteration # 10 Level # 4 Size 32x 32x 1
- processing level # 3
- Iteration # 1 Level # 3 Size 64x 64x 1
- Iteration # 2 Level # 3 Size 64x 64x 1
- Iteration # 3 Level # 3 Size 64x 64x 1
- Iteration # 4 Level # 3 Size 64x 64x 1
- Iteration # 5 Level # 3 Size 64x 64x 1
- Iteration # 6 Level # 3 Size 64x 64x 1
- Iteration # 7 Level # 3 Size 64x 64x 1
- Iteration # 8 Level # 3 Size 64x 64x 1
- Iteration # 9 Level # 3 Size 64x 64x 1
- Iteration # 10 Level # 3 Size 64x 64x 1
- processing level # 2
- Iteration # 1 Level # 2 Size 128x 128x 1
- Iteration # 2 Level # 2 Size 128x 128x 1
- Iteration # 3 Level # 2 Size 128x 128x 1
- Iteration # 4 Level # 2 Size 128x 128x 1
- Iteration # 5 Level # 2 Size 128x 128x 1
- Iteration # 6 Level # 2 Size 128x 128x 1
- Iteration # 7 Level # 2 Size 128x 128x 1
- Iteration # 8 Level # 2 Size 128x 128x 1
- Iteration # 9 Level # 2 Size 128x 128x 1
- Iteration # 10 Level # 2 Size 128x 128x 1
INFO [timagetk.tasks.registration] Composing consecutive transformations...
INFO [timagetk.tasks.registration] Composing consecutive transformations to get 0/2...
INFO [timagetk.tasks.registration] Applying composed transformations...
INFO [timagetk.tasks.registration] Applying t0/2 composed transformation to t0...
INFO [timagetk.tasks.registration] Applying t1/2 composed transformation to t1...
from timagetk.visu.mplt import grayscale_imshow
_=grayscale_imshow(list(res_imgs.values()), suptitle="Sequence RIGID registration", title=fnames, val_range=[0, 255])
0%| | 0/3 [00:00<?, ?image/s]
100%|██████████| 3/3 [00:00<00:00, 9411.30image/s]