Flux de travail dans napari#

Pour utiliser napari et dask ensemble afin de définir et concevoir des flux de travail, nous avons créé une petite bibliothèque pour rendre ces choses plus pratiques : napari-workflows. L’objectif était de permettre à l’utilisateur de configurer des flux de travail en cliquant dans napari. Ces flux de travail sont ensuite accessibles en tant qu’objet, similaire à un dictionnaire, auquel on peut demander les résultats d’étapes de flux de travail données. Par exemple, dans le flux de travail montré ci-dessous, une image d’entrée est floutée à l’aide d’un noyau gaussien, puis seuillée en utilisant la méthode d’Otsu et scikit-image.

from napari_workflows import Workflow

from skimage.io import imread
from skimage.filters import threshold_otsu, gaussian
from skimage.measure import label
from pyclesperanto_prototype import imshow

Tout d’abord, nous définissons un flux de travail et y ajoutons des opérations. Par exemple, une opération qui prend une image nommée "input" et produit une image "denoised" à partir de celle-ci en utilisant la fonction gaussian() et sigma=2 comme paramètre.

workflow = Workflow()

# define denoising
workflow.set("denoised", gaussian, "input", sigma=2)

Nous pouvons également ajouter des fonctions personnalisées, ce qui est par exemple nécessaire pour produire une image binaire à partir d’une image d’intensité directement avec un seul appel de fonction.

# define segmentation
def threshold(image):
    return image > threshold_otsu(image)
workflow.set("binarized", threshold, "denoised")

Nous appliquons également un étiquetage des composantes connexes à l’image binaire.

workflow.set("labeled", label, "binarized")

# Let's print out the whole workflow
print(str(workflow))
Workflow:
denoised <- (<function gaussian at 0x19b297940>, 'input', 2, None, 'nearest', 0, None, False, 4.0)
binarized <- (<function threshold at 0x19dbd8430>, 'denoised')
labeled <- (<function label at 0x19ba7c820>, 'binarized', None, False)

Exécution des flux de travail#

Jusqu’ici, aucune image n’était impliquée. Nous chargeons maintenant une image et la stockons dans le flux de travail en tant que "input".

workflow.set("input", imread("https://samples.fiji.sc/blobs.png"))

print(str(workflow))
Workflow:
denoised <- (<function gaussian at 0x19b297940>, 'input', 2, None, 'nearest', 0, None, False, 4.0)
binarized <- (<function threshold at 0x19dbd8430>, 'denoised')
labeled <- (<function label at 0x19ba7c820>, 'binarized', None, False)
input <- [[ 40  32  24 ... 216 200 200]
 [ 56  40  24 ... 232 216 216]
 [ 64  48  24 ... 240 232 232]
 ...
 [ 72  80  80 ...  48  48  48]
 [ 80  80  80 ...  48  48  48]
 [ 96  88  80 ...  48  48  48]]

Pour exécuter réellement le calcul, nous appelons la fonction workflow.get() qui produit une seule sortie spécifiée. En coulisses, elle exécutera également toutes les opérations intermédiaires nécessaires pour arriver à la sortie finale.

result = workflow.get("labeled")

imshow(result, labels=True)
../_images/b46f00c2a30b6b117eb2e39466aeb14acc0b44b46a27ed2c5f2e130939bad9ac.png