Procesamiento y análisis de imágenes#
Outline del capítulo
El procesamiento de imágenes consiste en modificarlas, normalmente de forma que facilite su posterior interpretación.
El análisis de imágenes consiste en convertir las imágenes en medidas.
Cuando nuestro objetivo es el análisis de imágenes, casi siempre necesitamos el procesamiento de imágenes para conseguirlo
Show code cell content
%load_ext autoreload
%autoreload 2
# Default imports
import sys
sys.path.append('../../../')
from helpers import *
from matplotlib import pyplot as plt
from myst_nb import glue
import numpy as np
from scipy import ndimage
Introducción#
Para extraer con éxito información útil de las imágenes de microscopía suele ser necesario triunfar en dos batallas principales.
La primera consiste en superar las limitaciones de calidad de la imagen y hacer que el contenido realmente interesante de la imagen sea más claramente visible. Se trata de procesar la imagen, cuyo resultado es otra imagen. La segunda consiste en calcular mediciones significativas que puedan presentarse en tablas y gráficos de resumen. Esto es el análisis de imágenes.
Nuestro principal objetivo es el análisis, pero el procesamiento es casi siempre indispensable para conseguirlo.
Un flujo de trabajo para el análisis de imágenes#
¿Cómo podemos analizar nuestras imágenes?
A la larga, necesitamos algún tipo de flujo de trabajo que comprenda múltiples pasos que nos lleven desde la imagen hasta los resultados. Cada paso individual puede ser pequeño y sencillo, pero la combinación es poderosa.
Tiendo a percibir el reto de construir cualquier flujo de trabajo de análisis científico de imágenes como algo parecido a resolver un rompecabezas. Al final, esperamos extraer algún tipo de medida cuantitativa que esté justificada por la naturaleza del experimento y los principios de la formación de imágenes. Una de las características interesantes del rompecabezas es que no existe una solución única y fija.
Aunque en principio esto pueda parecer inconveniente, puede ser liberador: sugiere que hay espacio para el pensamiento lateral y los chispazos de creatividad. Las mismas imágenes pueden analizarse de formas muy distintas. A veces dando resultados muy distintos, o respondiendo a preguntas científicas muy diferentes.
Es cierto que si no nos viene a la mente ninguna solución después de reflexionar durante un rato, esa perspectiva optimista se desvanece rápidamente y el «rompecabezas» puede convertirse en un «problema» insoportablemente exasperante, pero la cuestión es que en principio el análisis de imágenes puede ser divertido. Lo que se necesita es:
una pizca de entusiasmo (por favor traiga el suyo)
datos adquiridos correctamente, incluyendo todos los metadatos necesarios (el tema de la Parte I)
realmente tener las herramientas a tu disposición para resolver el rompecabezas (el tema de la Parte II)
Si eres un rompecabezas reacio, también ayuda tener la suerte de no estar trabajando en algo horrorosamente difícil, sino en algo que es difícil de controlar.
Combinación de herramientas de procesamiento#
El procesamiento de imágenes ofrece toda una serie de herramientas que pueden aplicarse a la resolución del «rompecabezas». Al unir los pasos de procesamiento para formar un flujo de trabajo, solemos tener dos etapas principales:
Preprocesamiento: lo que haces para limpiar la imagen, por ejemplo, restar el fondo, utilizar un filtro para reducir el ruido
Segmentación lo que haces para identificar las cosas de la imagen que te interesan, por ejemplo, aplicar un umbral para localizar características interesantes.
Una vez superadas estas etapas, suelen quedar algunas tareas adicionales (por ejemplo, realizar mediciones de la forma, la intensidad o la dinámica). Sin embargo, éstas dependen de las características específicas de la aplicación y normalmente no son lo más difícil. Si eres capaz de identificar lo que quieres cuantificar, estarás mucho mas cerca de resolver el rompecabezas.
Figura 57 muestra un ejemplo de cómo pueden encajar estas ideas.
Show code cell content
"""
Quick image analysis workflow to demonstrate the main steps involved.
"""
import numpy as np
from scipy import ndimage
from skimage.filters import threshold_triangle
from skimage.morphology import disk, extrema
from skimage.segmentation import watershed, mark_boundaries
from skimage.color import label2rgb
from matplotlib import pyplot as plt
# Read & crop image
x = 10
y = 0
s = 450
im_rgb = load_image('hela-cells.zip')[x:x+s, y:y+s, :].astype(np.float32)
# Convert to RGB - need to rescale each channel between 0 and 1
im_rgb_rgb = im_rgb - np.min(im_rgb.reshape((-1, 3)), axis=0).reshape((1, 1, 3))
im_rgb = im_rgb / np.percentile(im_rgb.reshape((-1, 3)), 99.5, axis=0).reshape((1, 1, 3))
# Extract channel of interest
im = im_rgb[:, :, 0]
# Apply difference of Gaussians filter
sigma = 3
sigma2 = sigma * 1.6
im_dog = ndimage.gaussian_filter(im, sigma) - ndimage.gaussian_filter(im, sigma2)
# Threshold for spot detection
bw_spots = im_dog > threshold_triangle(im_dog)
# Clean up with a morphological opening
strel = disk(3)
bw_spots_opened = ndimage.binary_opening(bw_spots, structure=strel)
# Perform distance-and-watershed-based split
bw_spots_dist = ndimage.distance_transform_edt(bw_spots_opened)
bw_spots_max = extrema.h_maxima(bw_spots_dist, 0.5)
bw_spots_max = ndimage.binary_dilation(bw_spots_max, structure=np.ones((3, 3)))
bw_spots_max = np.bitwise_and(bw_spots_opened, bw_spots_max)
lab_spots, n = ndimage.label(bw_spots_max)
lab_spots = watershed(-bw_spots_dist, markers=lab_spots, mask=bw_spots_opened, watershed_line=True)
bw_spots_cleaned = lab_spots > 0
# Show images
fig = create_figure(figsize=(8, 4))
show_image(np.clip(im_rgb, 0, 1), title='(A) Original image', pos=241)
show_image(im, title='(B) Extract channel', clip_percentile=0.5, pos=242)
show_image(im_dog, title='(C) Apply filters', clip_percentile=0.5, pos=243)
show_image(bw_spots, title='(D) Apply threshold', pos=244)
show_image(bw_spots_cleaned, title='(E) Refine detection', pos=245)
show_image(label2rgb(lab_spots, bg_label=0, bg_color='black'), title='(F) Distinguish objects', pos=246)
show_image(mark_boundaries(np.clip(im_rgb, 0, 1), lab_spots, mode='thick'), title='(G) Relate objects to image', pos=247)
show_image('images/workflow_results.png', title='(H) Make measurements', pos=248)
glue_fig('fig_overview_workflow', fig)
No será posible abarcar todas las herramientas de procesamiento de imágenes en un libro como éste. Más bien nos centraremos en las esenciales para empezar: umbrales, filtros, operaciones morfológicas y transformaciones.
Estos ya son suficientes para resolver muchos enigmas del análisis de imágenes, y proporcionan el marco al que se pueden añadir más posteriormente.