Flujos de trabajo en napari#
Para usar napari y dask juntos para definir y diseñar flujos de trabajo, hemos creado una pequeña biblioteca para hacer estas cosas más convenientes: napari-workflows. El objetivo era permitir al usuario configurar flujos de trabajo haciendo clic en napari. Estos flujos de trabajo son luego accesibles como objetos, similares a un diccionario, a los que se puede solicitar resultados de pasos específicos del flujo de trabajo. Por ejemplo, en el flujo de trabajo que se muestra a continuación, una imagen de entrada se desenfoca utilizando un kernel gaussiano y luego se aplica un umbral utilizando el método de Otsu y 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
Primero, definimos un flujo de trabajo y le agregamos operaciones. Por ejemplo, una operación que toma una imagen llamada "input" y produce una imagen "denoised" a partir de ella utilizando la función gaussian() y sigma=2 como parámetro.
workflow = Workflow()
# define denoising
workflow.set("denoised", gaussian, "input", sigma=2)
También podemos agregar funciones personalizadas, lo cual es necesario, por ejemplo, para producir una imagen binaria a partir de una imagen de intensidad directamente con una sola llamada de función.
# define segmentation
def threshold(image):
return image > threshold_otsu(image)
workflow.set("binarized", threshold, "denoised")
También aplicamos etiquetado de componentes conectados a la imagen binaria.
workflow.set("labeled", label, "binarized")
# Imprimamos todo el flujo de trabajo
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)
Ejecutando flujos de trabajo#
Hasta aquí, no se han involucrado imágenes. Ahora cargamos una imagen y la almacenamos en el flujo de trabajo como "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]]
Para ejecutar realmente el cálculo, llamamos a la función workflow.get() que produce una única salida especificada. Internamente, también ejecutará todas las operaciones intermedias necesarias para llegar a la salida final.
result = workflow.get("labeled")
imshow(result, labels=True)