clEsperanto#
clEsperanto est un projet entre plusieurs écosystèmes d’analyse d’images biologiques visant à supprimer les barrières linguistiques. Il est basé sur OpenCL, un standard ouvert pour la programmation des unités de traitement graphique (GPU, et plus) et son wrapper Python pyopencl. Sous le capot, il utilise des noyaux de traitement provenant du projet clij.
Voir aussi
Initialisation du GPU#
Nous allons commencer par vérifier quels GPU sont installés :
import pyclesperanto_prototype as cle
import matplotlib.pyplot as plt
import stackview
# list available devices
cle.available_device_names()
['NVIDIA GeForce RTX 3050 Ti Laptop GPU',
'gfx1035',
'cupy backend (experimental)']
# select a specific device with only a part of its name
cle.select_device("2080")
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\pyclesperanto_prototype\_tier0\_device.py:77: UserWarning: No OpenCL device found with 2080 in their name. Using gfx1035 instead.
warnings.warn(f"No OpenCL device found with {name} in their name. Using {device.name} instead.")
<gfx1035 on Platform: AMD Accelerated Parallel Processing (2 refs)>
# check which device is uses right now
cle.get_device()
<gfx1035 on Platform: AMD Accelerated Parallel Processing (2 refs)>
Traitement des images#
Pour charger les données d’image, nous utilisons scikit-image comme d’habitude :
from skimage.io import imread, imshow
image = imread("../../data/blobs.tif")
imshow(image)
<matplotlib.image.AxesImage at 0x206d07ad0a0>
La passerelle cle. contient toutes les méthodes dont vous avez besoin, elle n’a pas de sous-packages :
# noise removal
blurred = cle.gaussian_blur(image, sigma_x=1, sigma_y=1)
blurred
|
|
cle._ image
|
# binarization
binary = cle.threshold_otsu(blurred)
binary
|
|
cle._ image
|
# labeling
labels = cle.connected_components_labeling_box(binary)
labels
|
|
cle._ image
|
# visualize results
imshow(labels)
C:\Users\haase\mambaforge\envs\bio39\lib\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 0x206d2d6cb80>
stackview propose également une fonction imshow, qui permet par exemple d’afficher plus facilement les images d’étiquettes :
stackview.imshow(labels)
On peut également déterminer les bords des étiquettes et les superposer à l’image.
label_edges = cle.detect_label_edges(labels) * labels
stackview.imshow(image, continue_drawing=True)
stackview.imshow(label_edges, alpha=0.5)
Par conséquent, il peut être judicieux d’agrandir la figure et de combiner plusieurs sous-graphiques
fig, axs = plt.subplots(1, 2, figsize=(12,12))
# left plot
stackview.imshow(image, plot=axs[0])
# right plot
stackview.imshow(image, alpha=0.5, continue_drawing=True, plot=axs[1])
stackview.imshow(label_edges, labels=True, alpha=0.5, plot=axs[1])
Certaines de ces opérations, par exemple voronoi_otsu_labeling sont en fait des raccourcis et combinent un certain nombre d’opérations telles que le flou gaussien, l’étiquetage de Voronoi et le seuillage d’Otsu pour passer directement d’une image brute à une image étiquetée :
labels = cle.voronoi_otsu_labeling(image, spot_sigma=3.5, outline_sigma=1)
labels
|
|
cle._ image
|
Aussi, juste un rappel, lisez la documentation des méthodes que vous n’avez pas utilisées auparavant :
print(cle.voronoi_otsu_labeling.__doc__)
Labels objects directly from grey-value images.
The two sigma parameters allow tuning the segmentation result. Under the hood,
this filter applies two Gaussian blurs, spot detection, Otsu-thresholding [2] and Voronoi-labeling [3]. The
thresholded binary image is flooded using the Voronoi tesselation approach starting from the found local maxima.
Notes
-----
* This operation assumes input images are isotropic.
Parameters
----------
source : Image
Input grey-value image
label_image_destination : Image, optional
Output image
spot_sigma : float, optional
controls how close detected cells can be
outline_sigma : float, optional
controls how precise segmented objects are outlined.
Returns
-------
label_image_destination
Examples
--------
>>> import pyclesperanto_prototype as cle
>>> cle.voronoi_otsu_labeling(source, label_image_destination, 10, 2)
References
----------
.. [1] https://clij.github.io/clij2-docs/reference_voronoiOtsuLabeling
.. [2] https://ieeexplore.ieee.org/document/4310076
.. [3] https://en.wikipedia.org/wiki/Voronoi_diagram
Interopérabilité#
Dans pyclesperanto, les images sont gérées dans la mémoire à accès aléatoire (RAM) de votre GPU. Si vous voulez utiliser d’autres bibliothèques qui traitent les images sur le GPU, la mémoire doit être transférée en retour. Généralement, cela se produit de manière transparente pour l’utilisateur, par exemple lors de l’utilisation de scikit-image pour mesurer les propriétés des régions :
from skimage.measure import regionprops
statistics = regionprops(labels)
import numpy as np
np.mean([s.area for s in statistics])
333.77272727272725
Si vous voulez explicitement convertir votre image, par exemple en un tableau numpy, vous pouvez le faire comme ceci :
np.asarray(labels)
array([[ 0, 0, 0, ..., 62, 62, 62],
[ 0, 0, 0, ..., 62, 62, 62],
[ 0, 0, 0, ..., 62, 62, 62],
...,
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0]], dtype=uint32)
Gestion de la mémoire#
Dans les notebooks Jupyter, les variables restent en vie tant que le noyau du notebook est en cours d’exécution. Ainsi, votre GPU peut se remplir de mémoire. Donc, si vous n’avez plus besoin d’une image, supprimez-la de la mémoire en utilisant del. Elle sera alors supprimée de la mémoire du GPU grâce à la magie de pyopencl.
del image
del blurred
del binary
del labels