Ouverture des fichiers LIF#

Lorsqu’on travaille avec des données d’images microscopiques, de nombreux formats de fichiers circulent, comme le format d’image Leica (LIF). Dans ce notebook, nous allons ouvrir un fichier .lif en utilisant la bibliothèque readlif.

Note : Il est recommandé d’utiliser AICSImageIO pour lire les images LIF comme montré dans ce notebook.

La bibliothèque readlif peut être installée comme ceci depuis le terminal :

pip install readlif

Après l’avoir installée, elle peut être importée.

from readlif.reader import LifFile

import os
import requests
from skimage.io import imshow
import numpy as np

Comme jeu de données d’exemple, nous utiliserons une image partagée par Gregory Marquart et Harold Burgess sous licence CC-BY 4.0. Nous devons d’abord la télécharger.

filename = "../../data/y293-Gal4_vmat-GFP-f01.lif"
url = 'https://zenodo.org/record/3382102/files/y293-Gal4_vmat-GFP-f01.lif?download=1'

if not os.path.isfile(filename):
    # télécharger le fichier seulement si nous ne l'avons pas encore
    response = requests.get(url)
    open(filename, "wb").write(response.content)

À ce stade, le fichier devrait être sur notre ordinateur et peut être ouvert comme ceci.

file = LifFile(filename)
file
'LifFile object with 1 image'
lif_image = file.get_image(0)
lif_image
'LifImage object with dimensions: Dims(x=616, y=500, z=86, t=1, m=1)'

À partir de LifImage, nous pouvons obtenir des images individuelles sous forme d’images PIL.

pil_image = lif_image.get_frame(z=0)
type(pil_image)
PIL.Image.Image

Enfin, ces images PIL 2D peuvent être converties en tableaux numpy. Ce qui nous permet finalement de jeter un coup d’œil à l’image.

np_image = np.array(pil_image)
np_image.shape
(500, 616)
imshow(np_image)
/opt/miniconda3/envs/devbio-napari-env/lib/python3.9/site-packages/skimage/io/_plugins/matplotlib_plugin.py:149: UserWarning: Low image data range; displaying image with stretched contrast.
  lo, hi, cmap = _get_display_range(image)
<matplotlib.image.AxesImage at 0x1378ab970>
../_images/ab37ca7586f86a75885f777809caa8739c896fa9783d806b7bbd61dea6380d1b.png

Pour accéder à tous les pixels de notre image 3D, nous devrions d’abord jeter un coup d’œil aux métadonnées du fichier.

lif_image.info
{'dims': Dims(x=616, y=500, z=86, t=1, m=1),
 'display_dims': (1, 2),
 'dims_n': {1: 616, 2: 500, 3: 86},
 'scale_n': {1: 2.1354804344851965,
  2: 2.135480168493237,
  3: 0.9929687300128537},
 'path': 'Experiment_002/',
 'name': 'Series011',
 'channels': 2,
 'scale': (2.1354804344851965, 2.135480168493237, 0.9929687300128537, None),
 'bit_depth': (12, 12),
 'mosaic_position': [],
 'channel_as_second_dim': False,
 'settings': {}}

Par exemple, il pourrait être utile plus tard de connaître la taille des voxels dans l’ordre z/y/x.

voxel_size = lif_image.info['scale'][2::-1]
voxel_size
(0.9929687300128537, 2.135480168493237, 2.1354804344851965)

Nous pouvons également lire combien de tranches contient la pile 3D.

num_slices = lif_image.info['dims'].z
num_slices
86

Cette information nous permet d’écrire une fonction pratique qui permet de convertir l’image LIF en une pile d’images numpy 3D.

def lif_to_numpy_stack(lif_image):
    num_slices = lif_image.info['dims'].z
    
    return np.asarray([np.array(lif_image.get_frame(z=z)) for z in range(num_slices)])
image_stack = lif_to_numpy_stack(lif_image)
image_stack.shape
(86, 500, 616)

Cette pile d’images peut ensuite être utilisée par exemple pour visualiser une projection d’intensité maximale le long de Z.

imshow(np.max(image_stack, axis=0))
<matplotlib.image.AxesImage at 0x137a1c610>
../_images/bfb0e9bded30a8f74d350d0d5c781a3f8026ddfd97ac4ac93384fb99e3693681.png