Fusión de objetos utilizando aprendizaje automático#

El ObjectMerger es un Clasificador de Bosque Aleatorio parte de la biblioteca apoc que puede aprender qué etiquetas fusionar y cuáles no. Permite el post-procesamiento de imágenes de etiquetas después de que los objetos hayan sido (intencionalmente o no) sobresegmentados.

import apoc
from skimage.io import imread, imshow
import pyclesperanto_prototype as cle
import numpy as np

Un ejemplo común puede derivarse de una imagen que muestra intensidades en membranas celulares.

image = imread('../../data/membrane2d.tif')
cle.asarray(image)
cle._ image
shape(256, 256)
dtypefloat32
size256.0 kB
min277.0
max44092.0

Como las membranas tienen diferentes intensidades dependiendo de la región en la imagen, necesitamos corregir esto primero.

background_subtracted = cle.divide_by_gaussian_background(image, sigma_x=10, sigma_y=10)
background_subtracted
cle._ image
shape(256, 256)
dtypefloat32
size256.0 kB
min0.15839748
max11.448771

Por razones técnicas, también se recomienda convertir la imagen de intensidad en una imagen de tipo entero. Por lo tanto, la normalización podría ser necesaria. Es importante que las imágenes utilizadas para el entrenamiento y las imágenes utilizadas para la predicción tengan intensidades en el mismo rango.

oversegmented = imread("../../data/membrane2d_oversegmented.tif")
cle.asarray(oversegmented).astype(np.uint32)
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min1.0
max54.0

Una anotación sirve para indicar al algoritmo qué objetos segmentados deben fusionarse y cuáles no.

annotation = imread("../../data/membrane2d_merge_annotation.tif")
cle.asarray(annotation).astype(np.uint32)
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min0.0
max2.0

Para fines de visualización, podemos superponer la anotación con la imagen de la membrana.

cle.imshow(background_subtracted, max_display_intensity=4, continue_drawing=True)
cle.imshow(annotation, alpha=0.6, labels=True)
../_images/ed4124ba7532565c50e80bc09e8a750e648ef841fefa532d76468f463025b4fb.png

Para mostrar más de cerca lo que necesita ser anotado, también superponemos la imagen de bordes de etiquetas y la anotación. Nótese que los bordes que no se supone que deben fusionarse son pequeños puntos que siempre anotan cuidadosamente solo dos objetos (que no deben fusionarse).

cle.imshow(cle.detect_label_edges(oversegmented), continue_drawing=True)
cle.imshow(annotation, alpha=0.6, labels=True)
../_images/3e3e7c26276223990a47c1d3fa12c738cead94714793ea0d4cfdfc692f647b4b.png

Entrenando el fusionador#

El LabelMerger puede ser entrenado usando tres características:

  • touch_portion: La cantidad relativa en que un objeto toca a otro. Por ejemplo, en un tejido simétrico, similar a un panal, las células vecinas tienen una porción de contacto de 1/6 entre sí.

  • touch_count: El número de píxeles donde los objetos se tocan. Al usar este parámetro, asegúrate de que las imágenes utilizadas para el entrenamiento y la predicción tengan el mismo tamaño de vóxel.

  • mean_touch_intensity: La intensidad promedio entre objetos que se tocan. Si una célula está sobresegmentada, se encuentran múltiples objetos dentro de esa célula. El área donde estos objetos se tocan tiene una intensidad más baja que el área donde se tocan dos células. Por lo tanto, pueden diferenciarse. Normalizar la imagen como se mostró anteriormente es clave.

  • centroid_distance: La distancia (en píxeles o vóxeles) entre los centroides de los objetos etiquetados.

Nota: se recomienda usar la mayoría de las características solo en imágenes isotrópicas.

feature_definition = "touch_portion mean_touch_intensity"

classifier_filename = "label_merger.cl"

apoc.erase_classifier(classifier_filename)
classifier = apoc.ObjectMerger(opencl_filename=classifier_filename)

classifier.train(features=feature_definition,
                 labels=oversegmented,
                 sparse_annotation=annotation,
                 image=background_subtracted) 
merged_labels = classifier.predict(labels=oversegmented, image=background_subtracted)
merged_labels
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min1.0
max31.0