clEsperanto#

clEsperanto ist ein Projekt zwischen mehreren Ökosystemen zur Biobildanalyse, das darauf abzielt, Sprachbarrieren zu beseitigen. Es basiert auf OpenCL, einem offenen Standard für die Programmierung von Grafikprozessoren (GPUs und mehr) und seinem Python-Wrapper pyopencl. Unter der Haube verwendet es Verarbeitungskernels, die aus dem clij Projekt stammen.

Siehe auch

GPU-Initialisierung#

Wir beginnen damit, zu überprüfen, welche GPUs installiert sind:

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)>

Verarbeitung von Bildern#

Zum Laden von Bilddaten verwenden wir wie üblich scikit-image:

from skimage.io import imread, imshow

image = imread("../../data/blobs.tif")
imshow(image)
<matplotlib.image.AxesImage at 0x206d07ad0a0>
../_images/eb756dc9532e8cdefa98ec3218709d0b49891bc9b5e8c7da3549af18dfb22404.png

Das cle. Gateway enthält alle Methoden, die Sie benötigen, es hat keine Unterpakete:

# noise removal
blurred = cle.gaussian_blur(image, sigma_x=1, sigma_y=1)
blurred
cle._ image
shape(254, 256)
dtypefloat32
size254.0 kB
min10.285456
max248.0
# binarization
binary = cle.threshold_otsu(blurred)
binary
cle._ image
shape(254, 256)
dtypeuint8
size63.5 kB
min0.0
max1.0
# labeling
labels = cle.connected_components_labeling_box(binary)
labels
cle._ image
shape(254, 256)
dtypeuint32
size254.0 kB
min0.0
max62.0
# 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>
../_images/2fa7591f17ba2c94525b5b9fd2ab7d0563100403bb291865860a00720638c8c8.png

stackview bietet auch eine imshow-Funktion, die es beispielsweise ermöglicht, Labelbilder bequemer anzuzeigen:

stackview.imshow(labels)
../_images/68262d80e6db50806bf9d41a6f283e5b48ae36c9c546d373a24b2b51f3d44603.png

Man kann auch Labelkanten bestimmen und sie über das Bild blenden.

label_edges = cle.detect_label_edges(labels) * labels

stackview.imshow(image, continue_drawing=True)
stackview.imshow(label_edges, alpha=0.5)
../_images/f4fc37bbd33da42f059fe435421bc13ee57e80ed029ab10b10a2962a141a67bf.png

Daher kann es sinnvoll sein, die Abbildung zu vergrößern und mehrere Unterplots zu kombinieren

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])
../_images/06339ef6c16f6f0e6987852549376cb5e9ec439f5f7f554ddc3ce530b1d17826.png

Einige dieser Operationen, z.B. voronoi_otsu_labeling sind in der Tat Abkürzungen und kombinieren eine Reihe von Operationen wie Gaußsche Unschärfe, Voronoi-Labeling und Otsu-Schwellenwertbildung, um direkt von einem Rohbild zu einem Labelbild zu gelangen:

labels = cle.voronoi_otsu_labeling(image, spot_sigma=3.5, outline_sigma=1)
labels
cle._ image
shape(254, 256)
dtypeuint32
size254.0 kB
min0.0
max66.0

Auch eine Erinnerung: Lesen Sie die Dokumentation von Methoden, die Sie noch nicht verwendet haben:

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
    

Interoperabilität#

In pyclesperanto werden Bilder im Arbeitsspeicher (RAM) Ihrer GPU verarbeitet. Wenn Sie andere Bibliotheken verwenden möchten, die Bilder auf der GPU verarbeiten, muss der Speicher zurück übertragen werden. Normalerweise geschieht dies für den Benutzer transparent, z.B. bei der Verwendung von scikit-image zur Messung von Regioneneigenschaften:

from skimage.measure import regionprops

statistics = regionprops(labels)

import numpy as np
np.mean([s.area for s in statistics])
333.77272727272725

Wenn Sie Ihr Bild explizit konvertieren möchten, z.B. in ein numpy-Array, können Sie das so machen:

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)

Speicherverwaltung#

In Jupyter-Notebooks bleiben Variablen so lange am Leben, wie der Notebook-Kernel läuft. Dadurch kann sich Ihre GPU mit Speicher füllen. Wenn Sie also ein Bild nicht mehr benötigen, entfernen Sie es mit del aus dem Speicher. Es wird dann dank der pyopencl-Magie aus dem GPU-Speicher entfernt.

del image
del blurred
del binary
del labels