Registering two intensity images

Introduction

Aim & explanations

This how-to aims at explaining how to performs image registration between two intensity images using the basic algorithms from timagetk’s algorithms module. If it look too complicated, you can always use the RegistrationPlugin from the plugins module.

There are many possible applications to image registration, here is a non-exhaustive list of examples:

  • if the two images are from a time-series, rigid registration will enable a sort of temporal registration of the two images that will then be aligned over time, obviously it is possible to use more than two images to obtain a temporally coherent “film” (see the corresponding tutorial “how to register a time-series”);

  • if the two images are from a time-series, affine registration can give you the deformation undergone by the tissue in the three main axis of deformation;

  • if the two images are from a time-series, non-linear registration will give you a dense vectorfield that, under the right circumstances, can be used to precisely describe growth of the tissue;

  • if the two images are from a time-series and you have a cell-based segmentation, non-linear registration will allows you to compute cell lineage;

These applications are all based on the blockmatching algorithm, just remembers it register the “signal” and it is better to register the “smallest” (also often the “youger” when analysing growing tissues) tissue onto the “largest” (the “older” in the same way) tissue.

Import the required classes & functions

%matplotlib inline
from timagetk.algorithms.blockmatching import blockmatching
from timagetk.algorithms.trsf import apply_trsf
from timagetk.algorithms.trsf import compose_trsf
from timagetk.components.multi_channel import BlendImage
from timagetk.components.multi_channel import MultiChannelImage
from timagetk.io.util import shared_data
from timagetk.io import imread
from timagetk.visu.stack import orthogonal_view
/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 online multichannel data

We use a open-source online dataset available on Zenodo acquired by C.S. Galvan-Ampudia.

As per the documentation attached to the dataset, the used images are multichannel images:

File names containing qDII-CLV3-DR5 have the following data:

  • Channel 1: DII-VENUS-N7

  • Channel 2: pPIN1:PIN1-GFP

  • Channel 3: Propidium Iodide (cell walls)

  • Channel 4: pRPS5a:TagBFP-SV40

  • Channel 5: pCLV3:mCherry-N7

We will thus use channel 3 (Propidium Iodide or PI) for registration since it contains a cell-wall targeted signal (staining technique).

ch_names = ['DII-VENUS-N7', 'pPIN1:PIN1-GFP', 'Propidium Iodide', 'pRPS5a:TagBFP-SV40', 'pCLV3:mCherry-N7']

We defines the initial observation (t0) of the younger tissue as the floating image and the later observation (t0 + 5h) of the older tissue as the reference image. We do that because we are observing growing tissues, hence the observation frame of the older tissue might be bigger.

ref_url = "https://zenodo.org/record/3737795/files/qDII-CLV3-PIN1-PI-E35-LD-SAM4-T10.czi"
ref_img = imread(ref_url, channel_names=ch_names)
flo_url = "https://zenodo.org/record/3737795/files/qDII-CLV3-PIN1-PI-E35-LD-SAM4-T5.czi"
flo_img = imread(flo_url, channel_names=ch_names)
  0%|          | 0.00/650M [00:00<?, ?B/s]
  0%|          | 992k/650M [00:00<01:11, 9.46MB/s]
  0%|          | 2.12M/650M [00:00<01:04, 10.5MB/s]
  0%|          | 3.22M/650M [00:00<01:04, 10.6MB/s]
  1%|          | 4.44M/650M [00:00<01:01, 11.1MB/s]
  1%|          | 5.59M/650M [00:00<00:59, 11.3MB/s]
  1%|          | 6.72M/650M [00:00<00:59, 11.3MB/s]
  1%|          | 7.84M/650M [00:00<01:00, 11.2MB/s]
  1%|▏         | 8.97M/650M [00:00<01:00, 11.2MB/s]
  2%|▏         | 10.1M/650M [00:00<00:59, 11.2MB/s]
  2%|▏         | 11.3M/650M [00:01<00:58, 11.5MB/s]
  2%|▏         | 12.4M/650M [00:01<00:58, 11.4MB/s]
  2%|▏         | 13.5M/650M [00:01<00:59, 11.3MB/s]
  2%|▏         | 14.6M/650M [00:01<00:59, 11.2MB/s]
  2%|▏         | 15.7M/650M [00:01<00:59, 11.1MB/s]
  3%|▎         | 16.8M/650M [00:01<00:59, 11.1MB/s]
  3%|▎         | 17.9M/650M [00:01<00:59, 11.1MB/s]
  3%|▎         | 18.9M/650M [00:01<01:00, 11.0MB/s]
  3%|▎         | 20.0M/650M [00:01<01:03, 10.4MB/s]
  3%|▎         | 21.0M/650M [00:02<01:03, 10.4MB/s]
  3%|▎         | 22.2M/650M [00:02<01:01, 10.7MB/s]
  4%|▎         | 23.3M/650M [00:02<01:00, 10.9MB/s]
  4%|▎         | 24.3M/650M [00:02<01:02, 10.6MB/s]
  4%|▍         | 25.5M/650M [00:02<00:59, 11.0MB/s]
  4%|▍         | 26.7M/650M [00:02<00:58, 11.1MB/s]
  4%|▍         | 27.8M/650M [00:02<00:58, 11.2MB/s]
  4%|▍         | 28.9M/650M [00:02<00:57, 11.3MB/s]
  5%|▍         | 30.0M/650M [00:02<00:58, 11.2MB/s]
  5%|▍         | 31.1M/650M [00:02<00:57, 11.2MB/s]
  5%|▍         | 32.3M/650M [00:03<00:56, 11.5MB/s]
  5%|▌         | 33.4M/650M [00:03<00:56, 11.4MB/s]
  5%|▌         | 34.6M/650M [00:03<00:55, 11.6MB/s]
  6%|▌         | 35.8M/650M [00:03<00:55, 11.7MB/s]
  6%|▌         | 36.9M/650M [00:03<00:55, 11.6MB/s]
  6%|▌         | 38.1M/650M [00:03<00:56, 11.4MB/s]
  6%|▌         | 39.2M/650M [00:03<00:56, 11.3MB/s]
  6%|▌         | 40.2M/650M [00:03<00:56, 11.2MB/s]
  6%|▋         | 41.3M/650M [00:03<00:57, 11.2MB/s]
  7%|▋         | 42.7M/650M [00:03<00:53, 11.8MB/s]
  7%|▋         | 43.9M/650M [00:04<00:52, 12.1MB/s]
  7%|▋         | 45.2M/650M [00:04<00:50, 12.4MB/s]
  7%|▋         | 46.4M/650M [00:04<00:51, 12.2MB/s]
  7%|▋         | 47.6M/650M [00:04<00:54, 11.6MB/s]
  8%|▊         | 48.8M/650M [00:04<00:53, 11.7MB/s]
  8%|▊         | 50.0M/650M [00:04<00:53, 11.7MB/s]
  8%|▊         | 51.1M/650M [00:04<00:55, 11.3MB/s]
  8%|▊         | 52.3M/650M [00:04<00:54, 11.6MB/s]
  8%|▊         | 53.4M/650M [00:04<00:54, 11.5MB/s]
  8%|▊         | 54.8M/650M [00:05<00:51, 12.0MB/s]
  9%|▊         | 56.0M/650M [00:05<00:50, 12.3MB/s]
  9%|▉         | 57.2M/650M [00:05<00:50, 12.2MB/s]
  9%|▉         | 58.5M/650M [00:05<00:49, 12.5MB/s]
  9%|▉         | 59.8M/650M [00:05<00:49, 12.6MB/s]
  9%|▉         | 61.0M/650M [00:05<00:49, 12.5MB/s]
 10%|▉         | 62.2M/650M [00:05<00:49, 12.5MB/s]
 10%|▉         | 63.4M/650M [00:05<00:52, 11.8MB/s]
 10%|▉         | 64.6M/650M [00:05<00:51, 11.8MB/s]
 10%|█         | 65.8M/650M [00:06<00:52, 11.8MB/s]
 10%|█         | 67.2M/650M [00:06<00:48, 12.7MB/s]
 11%|█         | 68.4M/650M [00:06<00:48, 12.6MB/s]
 11%|█         | 69.7M/650M [00:06<00:49, 12.2MB/s]
 11%|█         | 70.8M/650M [00:06<00:51, 11.8MB/s]
 11%|█         | 72.1M/650M [00:06<00:50, 12.0MB/s]
 11%|█▏        | 73.3M/650M [00:06<00:50, 12.1MB/s]
 11%|█▏        | 74.4M/650M [00:06<00:50, 11.9MB/s]
 12%|█▏        | 75.8M/650M [00:06<00:48, 12.5MB/s]
 12%|█▏        | 77.0M/650M [00:06<00:49, 12.1MB/s]
 12%|█▏        | 78.2M/650M [00:07<00:49, 12.1MB/s]
 12%|█▏        | 79.4M/650M [00:07<00:49, 12.1MB/s]
 12%|█▏        | 80.6M/650M [00:07<00:49, 12.1MB/s]
 13%|█▎        | 81.8M/650M [00:07<00:48, 12.3MB/s]
 13%|█▎        | 83.1M/650M [00:07<00:47, 12.4MB/s]
 13%|█▎        | 84.3M/650M [00:07<00:47, 12.4MB/s]
 13%|█▎        | 85.5M/650M [00:07<00:47, 12.4MB/s]
 13%|█▎        | 86.9M/650M [00:07<00:45, 13.1MB/s]
 14%|█▎        | 88.2M/650M [00:07<00:44, 13.2MB/s]
 14%|█▍        | 89.5M/650M [00:08<00:46, 12.8MB/s]
 14%|█▍        | 90.8M/650M [00:08<00:46, 12.7MB/s]
 14%|█▍        | 92.0M/650M [00:08<00:46, 12.5MB/s]
 14%|█▍        | 93.3M/650M [00:08<00:45, 12.8MB/s]
 15%|█▍        | 94.6M/650M [00:08<00:48, 12.1MB/s]
 15%|█▍        | 95.8M/650M [00:08<00:49, 11.8MB/s]
 15%|█▍        | 97.0M/650M [00:08<00:48, 11.9MB/s]
 15%|█▌        | 98.3M/650M [00:08<00:46, 12.4MB/s]
 15%|█▌        | 99.5M/650M [00:08<00:46, 12.3MB/s]
 15%|█▌        | 101M/650M [00:08<00:47, 12.1MB/s] 
 16%|█▌        | 102M/650M [00:09<00:47, 12.2MB/s]
 16%|█▌        | 103M/650M [00:09<00:43, 13.1MB/s]
 16%|█▌        | 105M/650M [00:09<00:45, 12.7MB/s]
 16%|█▋        | 106M/650M [00:09<00:45, 12.6MB/s]
 16%|█▋        | 107M/650M [00:09<00:44, 12.8MB/s]
 17%|█▋        | 109M/650M [00:09<00:43, 13.0MB/s]
 17%|█▋        | 110M/650M [00:09<00:42, 13.5MB/s]
 17%|█▋        | 111M/650M [00:09<00:42, 13.2MB/s]
 17%|█▋        | 113M/650M [00:09<00:42, 13.1MB/s]
 18%|█▊        | 114M/650M [00:10<00:41, 13.7MB/s]
 18%|█▊        | 115M/650M [00:10<00:43, 13.0MB/s]
 18%|█▊        | 117M/650M [00:10<00:42, 13.1MB/s]
 18%|█▊        | 118M/650M [00:10<00:42, 13.0MB/s]
 18%|█▊        | 119M/650M [00:10<00:43, 12.9MB/s]
 19%|█▊        | 121M/650M [00:10<00:40, 13.9MB/s]
 19%|█▉        | 122M/650M [00:10<00:38, 14.2MB/s]
 19%|█▉        | 124M/650M [00:10<00:39, 14.1MB/s]
 19%|█▉        | 125M/650M [00:10<00:38, 14.4MB/s]
 19%|█▉        | 127M/650M [00:10<00:39, 14.0MB/s]
 20%|█▉        | 128M/650M [00:11<00:39, 13.8MB/s]
 20%|█▉        | 129M/650M [00:11<00:39, 13.8MB/s]
 20%|██        | 131M/650M [00:11<00:39, 13.8MB/s]
 20%|██        | 132M/650M [00:11<00:39, 13.9MB/s]
 21%|██        | 134M/650M [00:11<00:39, 13.8MB/s]
 21%|██        | 135M/650M [00:11<00:39, 13.6MB/s]
 21%|██        | 136M/650M [00:11<00:39, 13.6MB/s]
 21%|██        | 138M/650M [00:11<00:41, 13.1MB/s]
 21%|██▏       | 139M/650M [00:11<00:41, 13.0MB/s]
 22%|██▏       | 140M/650M [00:12<00:40, 13.2MB/s]
 22%|██▏       | 142M/650M [00:12<00:39, 13.5MB/s]
 22%|██▏       | 143M/650M [00:12<00:40, 13.1MB/s]
 22%|██▏       | 144M/650M [00:12<00:38, 13.7MB/s]
 22%|██▏       | 146M/650M [00:12<00:38, 13.8MB/s]
 23%|██▎       | 147M/650M [00:12<00:38, 13.8MB/s]
 23%|██▎       | 149M/650M [00:12<00:36, 14.2MB/s]
 23%|██▎       | 150M/650M [00:12<00:37, 14.1MB/s]
 23%|██▎       | 151M/650M [00:12<00:39, 13.4MB/s]
 23%|██▎       | 153M/650M [00:13<00:39, 13.2MB/s]
 24%|██▎       | 154M/650M [00:13<00:37, 14.0MB/s]
 24%|██▍       | 156M/650M [00:13<00:37, 13.9MB/s]
 24%|██▍       | 157M/650M [00:13<00:34, 15.0MB/s]
 24%|██▍       | 159M/650M [00:13<00:34, 14.9MB/s]
 25%|██▍       | 160M/650M [00:13<00:34, 15.0MB/s]
 25%|██▍       | 162M/650M [00:13<00:34, 14.8MB/s]
 25%|██▌       | 163M/650M [00:13<00:34, 14.8MB/s]
 25%|██▌       | 165M/650M [00:13<00:33, 15.3MB/s]
 26%|██▌       | 166M/650M [00:13<00:34, 14.7MB/s]
 26%|██▌       | 168M/650M [00:14<00:34, 14.5MB/s]
 26%|██▌       | 169M/650M [00:14<00:35, 14.3MB/s]
 26%|██▌       | 171M/650M [00:14<00:35, 14.0MB/s]
 26%|██▋       | 172M/650M [00:14<00:34, 14.4MB/s]
 27%|██▋       | 174M/650M [00:14<00:33, 14.8MB/s]
 27%|██▋       | 175M/650M [00:14<00:33, 15.0MB/s]
 27%|██▋       | 177M/650M [00:14<00:34, 14.2MB/s]
 27%|██▋       | 178M/650M [00:14<00:35, 14.0MB/s]
 28%|██▊       | 179M/650M [00:14<00:36, 13.4MB/s]
 28%|██▊       | 181M/650M [00:15<00:36, 13.4MB/s]
 28%|██▊       | 182M/650M [00:15<00:38, 12.9MB/s]
 28%|██▊       | 183M/650M [00:15<00:39, 12.5MB/s]
 28%|██▊       | 184M/650M [00:15<00:39, 12.5MB/s]
 29%|██▊       | 186M/650M [00:15<00:39, 12.4MB/s]
 29%|██▊       | 187M/650M [00:15<00:39, 12.4MB/s]
 29%|██▉       | 188M/650M [00:15<00:38, 12.5MB/s]
 29%|██▉       | 190M/650M [00:15<00:37, 12.8MB/s]
 29%|██▉       | 191M/650M [00:15<00:36, 13.4MB/s]
 30%|██▉       | 192M/650M [00:16<00:36, 13.3MB/s]
 30%|██▉       | 194M/650M [00:16<00:36, 13.0MB/s]
 30%|██▉       | 195M/650M [00:16<00:35, 13.4MB/s]
 30%|███       | 196M/650M [00:16<00:36, 13.2MB/s]
 30%|███       | 198M/650M [00:16<00:37, 12.6MB/s]
 31%|███       | 199M/650M [00:16<00:37, 12.8MB/s]
 31%|███       | 200M/650M [00:16<00:35, 13.5MB/s]
 31%|███       | 202M/650M [00:16<00:34, 13.7MB/s]
 31%|███       | 203M/650M [00:16<00:34, 13.6MB/s]
 31%|███▏      | 204M/650M [00:16<00:35, 13.1MB/s]
 32%|███▏      | 206M/650M [00:17<00:34, 13.4MB/s]
 32%|███▏      | 207M/650M [00:17<00:32, 14.4MB/s]
 32%|███▏      | 209M/650M [00:17<00:31, 14.5MB/s]
 32%|███▏      | 210M/650M [00:17<00:33, 14.0MB/s]
 33%|███▎      | 212M/650M [00:17<00:31, 14.4MB/s]
 33%|███▎      | 213M/650M [00:17<00:34, 13.2MB/s]
 33%|███▎      | 214M/650M [00:17<00:35, 13.0MB/s]
 33%|███▎      | 216M/650M [00:17<00:35, 13.0MB/s]
 33%|███▎      | 217M/650M [00:17<00:36, 12.5MB/s]
 34%|███▎      | 218M/650M [00:18<00:34, 13.1MB/s]
 34%|███▍      | 220M/650M [00:18<00:33, 13.5MB/s]
 34%|███▍      | 221M/650M [00:18<00:32, 13.7MB/s]
 34%|███▍      | 223M/650M [00:18<00:31, 14.1MB/s]
 35%|███▍      | 224M/650M [00:18<00:30, 14.6MB/s]
 35%|███▍      | 226M/650M [00:18<00:29, 14.9MB/s]
 35%|███▌      | 228M/650M [00:18<00:28, 15.3MB/s]
 35%|███▌      | 229M/650M [00:18<00:29, 15.0MB/s]
 35%|███▌      | 231M/650M [00:18<00:28, 15.5MB/s]
 36%|███▌      | 232M/650M [00:19<00:28, 15.3MB/s]
 36%|███▌      | 234M/650M [00:19<00:28, 15.3MB/s]
 36%|███▌      | 235M/650M [00:19<00:29, 14.9MB/s]
 36%|███▋      | 237M/650M [00:19<00:30, 14.4MB/s]
 37%|███▋      | 238M/650M [00:19<00:30, 14.3MB/s]
 37%|███▋      | 240M/650M [00:19<00:28, 15.3MB/s]
 37%|███▋      | 242M/650M [00:19<00:26, 16.4MB/s]
 37%|███▋      | 243M/650M [00:19<00:25, 16.7MB/s]
 38%|███▊      | 245M/650M [00:19<00:27, 15.4MB/s]
 38%|███▊      | 247M/650M [00:19<00:26, 16.0MB/s]
 38%|███▊      | 248M/650M [00:20<00:26, 16.2MB/s]
 38%|███▊      | 250M/650M [00:20<00:26, 16.1MB/s]
 39%|███▊      | 251M/650M [00:20<00:26, 15.5MB/s]
 39%|███▉      | 253M/650M [00:20<00:26, 15.9MB/s]
 39%|███▉      | 255M/650M [00:20<00:25, 16.5MB/s]
 39%|███▉      | 257M/650M [00:20<00:24, 16.6MB/s]
 40%|███▉      | 258M/650M [00:20<00:24, 16.5MB/s]
 40%|████      | 260M/650M [00:20<00:23, 17.2MB/s]
 40%|████      | 262M/650M [00:20<00:25, 15.9MB/s]
 41%|████      | 264M/650M [00:21<00:24, 16.3MB/s]
 41%|████      | 265M/650M [00:21<00:23, 17.1MB/s]
 41%|████      | 267M/650M [00:21<00:23, 17.0MB/s]
 41%|████▏     | 269M/650M [00:21<00:23, 17.3MB/s]
 42%|████▏     | 271M/650M [00:21<00:23, 16.9MB/s]
 42%|████▏     | 272M/650M [00:21<00:22, 17.5MB/s]
 42%|████▏     | 274M/650M [00:21<00:22, 17.7MB/s]
 42%|████▏     | 276M/650M [00:21<00:24, 16.2MB/s]
 43%|████▎     | 277M/650M [00:21<00:25, 15.5MB/s]
 43%|████▎     | 279M/650M [00:22<00:25, 15.3MB/s]
 43%|████▎     | 280M/650M [00:22<00:28, 13.7MB/s]
 43%|████▎     | 282M/650M [00:22<00:30, 12.8MB/s]
 44%|████▎     | 283M/650M [00:22<00:30, 12.6MB/s]
 44%|████▎     | 284M/650M [00:22<00:30, 12.6MB/s]
 44%|████▍     | 286M/650M [00:22<00:32, 11.9MB/s]
 44%|████▍     | 287M/650M [00:22<00:33, 11.3MB/s]
 44%|████▍     | 288M/650M [00:22<00:33, 11.3MB/s]
 44%|████▍     | 289M/650M [00:22<00:33, 11.2MB/s]
 45%|████▍     | 290M/650M [00:23<00:33, 11.3MB/s]
 45%|████▍     | 291M/650M [00:23<01:10, 5.36MB/s]
 45%|████▍     | 292M/650M [00:23<00:58, 6.40MB/s]
 45%|████▌     | 293M/650M [00:23<01:02, 6.02MB/s]
 45%|████▌     | 294M/650M [00:23<00:52, 7.10MB/s]
 45%|████▌     | 295M/650M [00:24<00:58, 6.36MB/s]
 46%|████▌     | 296M/650M [00:24<00:49, 7.43MB/s]
 46%|████▌     | 297M/650M [00:24<01:00, 6.15MB/s]
 46%|████▌     | 298M/650M [00:24<00:54, 6.78MB/s]
 46%|████▌     | 299M/650M [00:24<01:22, 4.49MB/s]
 46%|████▌     | 300M/650M [00:25<01:04, 5.71MB/s]
 46%|████▋     | 301M/650M [00:25<01:32, 3.97MB/s]
 46%|████▋     | 302M/650M [00:25<01:11, 5.13MB/s]
 47%|████▋     | 303M/650M [00:25<01:12, 5.01MB/s]
 47%|████▋     | 304M/650M [00:25<00:59, 6.12MB/s]
 47%|████▋     | 305M/650M [00:26<01:01, 5.91MB/s]
 47%|████▋     | 306M/650M [00:26<00:53, 6.69MB/s]
 47%|████▋     | 307M/650M [00:26<01:06, 5.42MB/s]
 47%|████▋     | 308M/650M [00:26<00:53, 6.76MB/s]
 48%|████▊     | 309M/650M [00:26<00:56, 6.33MB/s]
 48%|████▊     | 312M/650M [00:26<00:33, 10.5MB/s]
 48%|████▊     | 315M/650M [00:26<00:23, 14.7MB/s]
 49%|████▉     | 317M/650M [00:27<00:19, 18.2MB/s]
 49%|████▉     | 320M/650M [00:27<00:16, 21.3MB/s]
 50%|████▉     | 323M/650M [00:27<00:14, 23.8MB/s]
 50%|█████     | 326M/650M [00:27<00:12, 26.2MB/s]
 51%|█████     | 329M/650M [00:27<00:12, 27.9MB/s]
 51%|█████     | 333M/650M [00:27<00:11, 29.5MB/s]
 52%|█████▏    | 336M/650M [00:27<00:10, 31.3MB/s]
 52%|█████▏    | 339M/650M [00:27<00:10, 31.6MB/s]
 53%|█████▎    | 342M/650M [00:27<00:11, 28.1MB/s]
 53%|█████▎    | 345M/650M [00:28<00:12, 24.7MB/s]
 53%|█████▎    | 348M/650M [00:28<00:13, 23.0MB/s]
 54%|█████▍    | 350M/650M [00:28<00:13, 22.7MB/s]
 54%|█████▍    | 352M/650M [00:28<00:14, 22.2MB/s]
 54%|█████▍    | 354M/650M [00:28<00:13, 22.4MB/s]
 55%|█████▍    | 357M/650M [00:28<00:13, 22.7MB/s]
 55%|█████▌    | 359M/650M [00:28<00:13, 23.2MB/s]
 56%|█████▌    | 361M/650M [00:28<00:12, 23.4MB/s]
 56%|█████▌    | 364M/650M [00:28<00:12, 24.0MB/s]
 56%|█████▋    | 366M/650M [00:29<00:11, 24.9MB/s]
 57%|█████▋    | 369M/650M [00:29<00:11, 25.7MB/s]
 57%|█████▋    | 372M/650M [00:29<00:11, 26.3MB/s]
 58%|█████▊    | 375M/650M [00:29<00:10, 26.8MB/s]
 58%|█████▊    | 377M/650M [00:29<00:10, 27.1MB/s]
 58%|█████▊    | 380M/650M [00:29<00:09, 28.4MB/s]
 59%|█████▉    | 383M/650M [00:29<00:09, 29.3MB/s]
 59%|█████▉    | 386M/650M [00:29<00:09, 29.8MB/s]
 60%|█████▉    | 389M/650M [00:29<00:08, 30.8MB/s]
 60%|██████    | 393M/650M [00:29<00:08, 32.2MB/s]
 61%|██████    | 396M/650M [00:30<00:08, 33.0MB/s]
 61%|██████▏   | 400M/650M [00:30<00:07, 33.6MB/s]
 62%|██████▏   | 403M/650M [00:30<00:07, 34.0MB/s]
 62%|██████▏   | 406M/650M [00:30<00:07, 33.8MB/s]
 63%|██████▎   | 410M/650M [00:30<00:07, 35.2MB/s]
 64%|██████▎   | 414M/650M [00:30<00:06, 36.0MB/s]
 64%|██████▍   | 417M/650M [00:30<00:06, 36.9MB/s]
 65%|██████▍   | 421M/650M [00:30<00:06, 37.8MB/s]
 65%|██████▌   | 425M/650M [00:30<00:06, 38.5MB/s]
 66%|██████▌   | 429M/650M [00:31<00:12, 19.4MB/s]
 67%|██████▋   | 433M/650M [00:31<00:09, 23.3MB/s]
 67%|██████▋   | 436M/650M [00:31<00:10, 22.1MB/s]
 67%|██████▋   | 439M/650M [00:31<00:10, 21.4MB/s]
 68%|██████▊   | 441M/650M [00:31<00:10, 20.3MB/s]
 68%|██████▊   | 443M/650M [00:31<00:10, 20.6MB/s]
 69%|██████▊   | 446M/650M [00:32<00:10, 20.5MB/s]
 69%|██████▉   | 448M/650M [00:32<00:10, 20.1MB/s]
 69%|██████▉   | 450M/650M [00:32<00:10, 19.8MB/s]
 69%|██████▉   | 452M/650M [00:32<00:10, 19.2MB/s]
 70%|██████▉   | 454M/650M [00:32<00:10, 19.2MB/s]
 70%|███████   | 456M/650M [00:32<00:10, 20.0MB/s]
 70%|███████   | 458M/650M [00:32<00:10, 20.2MB/s]
 71%|███████   | 460M/650M [00:32<00:09, 20.4MB/s]
 71%|███████   | 462M/650M [00:32<00:09, 20.7MB/s]
 71%|███████▏  | 464M/650M [00:33<00:09, 19.8MB/s]
 72%|███████▏  | 466M/650M [00:33<00:09, 20.4MB/s]
 72%|███████▏  | 468M/650M [00:33<00:09, 20.1MB/s]
 72%|███████▏  | 470M/650M [00:33<00:10, 18.2MB/s]
 73%|███████▎  | 472M/650M [00:33<00:11, 16.5MB/s]
 73%|███████▎  | 473M/650M [00:33<00:11, 16.0MB/s]
 73%|███████▎  | 475M/650M [00:33<00:11, 16.1MB/s]
 73%|███████▎  | 476M/650M [00:33<00:11, 16.2MB/s]
 74%|███████▎  | 478M/650M [00:33<00:10, 16.5MB/s]
 74%|███████▍  | 480M/650M [00:34<00:10, 16.6MB/s]
 74%|███████▍  | 481M/650M [00:34<00:10, 17.2MB/s]
 74%|███████▍  | 483M/650M [00:34<00:09, 17.7MB/s]
 75%|███████▍  | 485M/650M [00:34<00:09, 18.7MB/s]
 75%|███████▍  | 487M/650M [00:34<00:08, 19.5MB/s]
 75%|███████▌  | 489M/650M [00:34<00:08, 20.1MB/s]
 76%|███████▌  | 492M/650M [00:34<00:07, 21.1MB/s]
 76%|███████▌  | 494M/650M [00:34<00:07, 22.0MB/s]
 76%|███████▋  | 496M/650M [00:34<00:07, 22.7MB/s]
 77%|███████▋  | 499M/650M [00:34<00:06, 23.2MB/s]
 77%|███████▋  | 501M/650M [00:35<00:06, 23.7MB/s]
 77%|███████▋  | 504M/650M [00:35<00:06, 24.7MB/s]
 78%|███████▊  | 506M/650M [00:35<00:05, 25.6MB/s]
 78%|███████▊  | 509M/650M [00:35<00:05, 26.2MB/s]
 79%|███████▊  | 512M/650M [00:35<00:05, 26.8MB/s]
 79%|███████▉  | 514M/650M [00:35<00:05, 27.0MB/s]
 80%|███████▉  | 518M/650M [00:35<00:04, 28.4MB/s]
 80%|████████  | 521M/650M [00:35<00:04, 29.2MB/s]
 81%|████████  | 524M/650M [00:35<00:04, 29.5MB/s]
 81%|████████  | 527M/650M [00:35<00:04, 31.1MB/s]
 82%|████████▏ | 530M/650M [00:36<00:03, 32.0MB/s]
 82%|████████▏ | 534M/650M [00:36<00:03, 33.1MB/s]
 83%|████████▎ | 537M/650M [00:36<00:03, 33.8MB/s]
 83%|████████▎ | 541M/650M [00:36<00:03, 33.8MB/s]
 84%|████████▎ | 544M/650M [00:36<00:03, 34.2MB/s]
 84%|████████▍ | 547M/650M [00:36<00:03, 33.0MB/s]
 85%|████████▍ | 552M/650M [00:36<00:02, 36.9MB/s]
 85%|████████▌ | 556M/650M [00:36<00:02, 37.8MB/s]
 86%|████████▌ | 560M/650M [00:36<00:02, 39.3MB/s]
 87%|████████▋ | 564M/650M [00:36<00:02, 40.1MB/s]
 87%|████████▋ | 568M/650M [00:37<00:02, 40.7MB/s]
 88%|████████▊ | 572M/650M [00:37<00:01, 41.2MB/s]
 89%|████████▊ | 576M/650M [00:37<00:01, 41.7MB/s]
 89%|████████▉ | 580M/650M [00:37<00:01, 41.9MB/s]
 90%|████████▉ | 585M/650M [00:37<00:01, 42.7MB/s]
 91%|█████████ | 589M/650M [00:37<00:01, 44.0MB/s]
 91%|█████████▏| 594M/650M [00:37<00:01, 45.5MB/s]
 92%|█████████▏| 599M/650M [00:37<00:01, 46.5MB/s]
 93%|█████████▎| 604M/650M [00:37<00:01, 48.3MB/s]
 94%|█████████▎| 608M/650M [00:38<00:00, 48.6MB/s]
 94%|█████████▍| 613M/650M [00:38<00:00, 49.0MB/s]
 95%|█████████▌| 618M/650M [00:38<00:00, 47.6MB/s]
 96%|█████████▌| 624M/650M [00:38<00:00, 50.6MB/s]
 97%|█████████▋| 629M/650M [00:38<00:00, 51.8MB/s]
 97%|█████████▋| 634M/650M [00:38<00:00, 50.1MB/s]
 98%|█████████▊| 640M/650M [00:38<00:00, 55.0MB/s]
 99%|█████████▉| 645M/650M [00:38<00:00, 53.7MB/s]
650MB [00:38, 17.5MB/s]                           

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[3], line 2
      1 ref_url = "https://zenodo.org/record/3737795/files/qDII-CLV3-PIN1-PI-E35-LD-SAM4-T10.czi"
----> 2 ref_img = imread(ref_url, channel_names=ch_names)
      3 flo_url = "https://zenodo.org/record/3737795/files/qDII-CLV3-PIN1-PI-E35-LD-SAM4-T5.czi"
      4 flo_img = imread(flo_url, channel_names=ch_names)

File /builds/J-gEBwyb/0/mosaic/timagetk/src/timagetk/io/image.py:321, in imread(fname, rtype, **kwargs)
    318 if isinstance(fname, str):
    319     # URL checkpoint:
    320     if fname.startswith('http'):
--> 321         return imread(_image_from_url(fname), rtype, **kwargs)
    322     else:
    323         fname = Path(fname)

File /builds/J-gEBwyb/0/mosaic/timagetk/src/timagetk/io/image.py:338, in imread(fname, rtype, **kwargs)
    336 log.debug("Loading image: {}".format(fname))
    337 if ext == ".czi":
--> 338     img = read_czi_image(fname, kwargs.get("channel_names", None))
    339     # - Select only one channel:
    340     if 'channel' in kwargs:

File /builds/J-gEBwyb/0/mosaic/timagetk/src/timagetk/io/image.py:789, in read_czi_image(czi_file, channel_names, **kwargs)
    731 """Read Carl Zeiss Image (CZI) file.
    732 
    733 Parameters
   (...)
    786 
    787 """
    788 import xmltodict as xmltodict
--> 789 from czifile import CziFile
    791 return_order = kwargs.get('return_order', 'ZYXC')
    792 pattern = kwargs.get('pattern', '.C.ZXY.')

ModuleNotFoundError: No module named 'czifile'

Let’s print some information about the reference image & its channels:

print(ref_img)

You can also list the channel names using the channel_names attributes as follow:

ref_img.channel_names

We now select the channels to use for the registration algorithm:

ref_ch = ref_img.get_channel('Propidium Iodide')
flo_ch = flo_img.get_channel('Propidium Iodide')

Equalizing images contrast

To make sure the two images have similar “brightness” when displayed together, we adjust their constrast by stretching it:

from timagetk.algorithms.exposure import global_contrast_stretch
ref_ch = global_contrast_stretch(ref_ch)
flo_ch = global_contrast_stretch(flo_ch)

Let’s print some information about the selected channel from the reference image:

print(ref_ch)

Visualize PI channels individually

Let’s have a quick look at the data using othogonal views:

orthogonal_view(flo_ch)
orthogonal_view(ref_ch)

Visualize blended PI channels

blend = BlendImage(flo_ch, ref_ch, colors=['green', 'red'])
print(blend.shape)
orthogonal_view(blend)

As we can see the images are not “aligned”.

Note the the ‘green’ floral organ on the lower right corner is a removed organ between the two acquisitions.

Translate & rotate with rigid registration

Rigid transformation estimation

We starts by estimating the rigid transformation between the two channels using the blockmatching algorithm. It will estimate the optimal translation and rotation matrix to apply to “align” them properly:

trsf_rig = blockmatching(flo_ch, ref_ch, method='rigid')
type(trsf_rig)

Apply estimated transformation to floating image

We now apply this estimated rigid transformation to the floating image to register it on the reference image frame:

reg_ch = apply_trsf(flo_ch, trsf_rig, interpolation='linear')

Visualizing blended PI channels after rigid registration

blend = BlendImage(reg_ch, ref_ch, colors=['green', 'red'])
orthogonal_view(blend)

Linear deformation with affine transformation estimation

We now try to explains the previously unexplained deformation using an affine transformation between the two cell-wall channels using the blockmatching algorithm.

As we will initialize the algorithm with the previously estimated rigid transformation, we will get an estimate of the optimal scaling and shearing matrix to apply to “align” them properly:

trsf_paff = blockmatching(flo_ch, ref_ch, method='affine', left_trsf=trsf_rig)
type(trsf_paff)

Transformations composition

As we initialized the blockmatching algorithm with a rigid tranformation using the left_trsf keyword argument, the returned Trsf object contains only the affine part of the full transformation registering flo_ch on ref_ch. To get this full transformation we thus need to compose the two transformations:

\[\begin{equation*} T_{rigid} \circ T_{affine} \end{equation*}\]

This is can be accomplished using the compose_trsf algorithm:

trsf_aff = compose_trsf([trsf_rig, trsf_paff])

Using the init_trsf keyword argument would return this composition as an output of the blockmatching algorithm, but we detailled it here for the sake of clarity.

Apply estimated transformation to floating image

We now apply this estimated affine transformation to the floating image to register it on the reference image frame:

reg_ch = apply_trsf(flo_ch, trsf_aff, interpolation='linear')

Visualizing blended PI channels after affine registration

blend = BlendImage(reg_ch, ref_ch, colors=['green', 'red'])
orthogonal_view(blend)

Now we note that altought some lateral organs (flower meristems) looks better “aligned”, a linear deformation seems largely insufficient to explains observed deformation of a growing tissue like the shoot apical meristem.

We wil now try to reach an even better alignment with a non-linear estimation of the deformation.

Non-linear deformation with non-linear transformation estimation

We now try to explains the previously unexplained deformation using an non-linear transformation between the two cell-wall channels using the blockmatching algorithm.

As we will initialize the algorithm with the previously estimated rigid transformation, we will get an estimate of the optimal non-linear deformation (excluding translation and rotation) to apply to “align” them “perfectly”:

trsf_vf = blockmatching(flo_ch, ref_ch, method='vectorfield', init_trsf=trsf_rig)
type(trsf_vf)

Using the init_trsf keyword argument would return this composition as an output of the blockmatching algorithm, but we detailled it here for the sake of clarity.

Apply estimated transformation to floating image

We now apply this estimated non-linear transformation to the floating image to register it on the reference image frame:

reg_ch = apply_trsf(flo_ch, trsf_vf, interpolation='linear')

Visualize blended PI channels after non-linear registration

blend = BlendImage(reg_ch, ref_ch, colors=['green', 'red'])
orthogonal_view(blend)

Now we can see that, in the central part of the image, signals (cell-wall) of both images is matching well. However, due to the limitation of vector norms and its regularity, lateral organs are not well aligned.

Apply a transformation to the whole multichannel image

After performing one, or more, of these registrations you may want to apply the transformation of your choosing to the whole multichannel image. Note that it is what would happen if you used the RegistrationPlugin with MultiChannelImages.

We here assume that you want to apply the rigid transformation to the other channels, but the code is the same for any transformation you have computed beforehand.

channels = {ch: apply_trsf(flo_img[ch], trsf_rig, interpolation='linear') for ch in flo_img.get_channel_names()}
reg_flo_img = MultiChannelImage(channels)
ch_colors = ['yellow', 'green', 'red', 'blue', 'cyan']
print(dict(zip(ch_names, ch_colors)))
orthogonal_view(reg_flo_img.to_blend_image(colors=ch_colors, rtype='uint8'))