De fotones a píxeles#

Outline del capítulo

  • Los valores de píxeles en una imagen de fluorescencia dependen del número de fotones detectados

  • Nuestras imágenes no pueden ser perfectas: el desenfoque y el ruido son inevitables

Hide 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#

Una de las modalidades más comunes de bioimagenología, asociadas con el análisis de imágenes es la microscopía de fluorescencia. Aplicar de manera significativa las técnicas de análisis descritas en este libro a imágenes de fluorescencia implica entender un poco acerca del proceso de obtención de imágenes.

La Parte III tiene como objetivo proporcionar una introducción a las ideas principales, junto con algunos modelos mentales útiles para ayudar a relacionar las técnicas de análisis con las realidades de la microscopía. Estas ideas pueden ayudar a descubrir cómo adquirir y analizar datos de microscopía de fluorescencia de manera científicamente justificable.

El panorama general de las microscopía de fluorescencia#

Las imágenes en microscopía de fluorescencia se forman detectando luz. Las cantidades de luz involucradas son tan pequeñas que pueden considerarse en términos de fotones individuales.

Los fotones son emitidos por moléculas fluorescentes dentro de la muestra de la que se están tomando imágenes. A veces, estas moléculas emisoras de fotones pueden ser precisamente las cosas que nos interesa estudiar, pero a menudo sólo se han introducido en la muestra porque tienen la útil propiedad de fluorescer en presencia de las moléculas o estructuras que realmente nos gustaría visualizar (que de otra forma no serían fluorescentes).

De cualquier manera, lo más que la imagen puede decirnos es cuánta luz se emitió desde un punto particular de la muestra. A partir de esta información hacemos nuestras interpretaciones, como por ejemplo sobre la presencia o ausencia de alguna característica, sobre el tamaño y la forma de una estructura, o sobre la concentración relativa de una molécula. Pero en ningún caso vemos la característica, estructura o molécula directamente en las imágenes grabadas: sólo tenemos medidas de la cantidad de fotones que pudimos detectar, codificadas en valores de píxeles.

No prestaremos mucha atención aquí a lo que realmente indica un número particular de fotones que emana de una muestra desde un punto de vista biológico - esto dependería demasiado del diseño y los detalles del experimento, es decir, de las células, las tinciones y otras sustancias involucradas. Sin embargo, a menudo podemos hacer suposiciones generales. Una de esas suposiciones es que si viéramos (en promedio) el doble de fotones provenientes de una región que de otra, la cantidad de moléculas fluorescentes debe ser aproximadamente el doble en la primera región [^fn_1]. Pero antes de que podamos preocuparnos por tales cosas, primero debemos considerar con qué precisión podemos siquiera determinar el número y los orígen de los fotones emitidos por la muestra, dada la calidad limitada de las imágenes que realmente podemos registrar.

Grabación de imágenes#

Ya presentamos un modelo simple de formación de imágenes de fluorescencia en Imágenes y píxeles con dos animaciones. La primera animación muestra el proceso general:

La segunda animación se acerca para brindar más detalles sobre la detección de fotones y cómo esto finalmente conduce a que los valores de los píxeles se almacenen en una imagen digital:

Será útil tener presente este modelo a lo largo de las siguientes secciones.

Una vez que se ha preparado una muestra y espera debajo del microscopio, el proceso básico de registrar una imagen de fluorescencia comprende cuatro pasos principales:

  1. Excitación de fluoróforos. Las moléculas fluorescentes (fluoróforos) primero deben elevarse a un estado excitado. Esto sucede tras la absorción de un fotón, cuya energía (es decir, longitud de onda) debe caer en un rango específico del propio fluoróforo. Esto se lleva a cabo iluminando la muestra, por ejemplo, con una lámpara o un láser.

  2. Emisión de fotones. Al regresar a su estado fundamental, cada fluoróforo puede emitir un fotón, esta vez con una energía más baja (es decir, una longitud de onda más larga) que el fotón previamente absorbido.

  3. Detección de fotones. Se puede considerar, de manera bastante informal, que la mayoría de los fotones emitidos «salen dirigidos en la dirección equivocada», en cuyo caso no tenemos ninguna esperanza de detectarlos. Pero una parte de la luz debe entrar en el objetivo del microscopio y enfocarse hacia un detector. Cuando un fotón golpea el detector, se registra como un «golpe» por la liberación de un electrón (si tenemos suerte; los detectores son imperfectos, por lo que esto podría no ocurrir, lo que significa que el fotón se pierde efectivamente).

  4. Cuantificación y almacenamiento. Después de intervalos de tiempo fijos, se cuantifican las cargas de los electrones producidos por los fotones que golpean el detector y, a partir de estas cuantificaciones, se determinan los valores de los píxeles. Una carga mayor indica más fotones, lo que se traduce en un valor de píxel más alto.

Errores e imprecisiones#

Del resumen anterior, queda claro que estamos bastante lejos de saber exactamente cuánta luz emite la muestra: la mayoría de los fotones no llegan al detector, y muchos de los que lo hacen aún no están registrados. Pero ya que es posible asumir que perdemos siempre una proporción similar de luz emitida (tal vez hasta el 90%), esto no importa mucho: podemos esperar que todas las partes de la imagen se vean afectadas de manera similar, por lo que las diferencias relativas en el brillo todavía se reflejarán en nuestros valores de píxeles.

Sin embargo, este no es nuestro único límite. Hay dos formas más críticas en las que las imágenes que podemos grabar son peores que las imágenes que querríamos:

  1. Incertidumbre en el espacio. Idealmente, toda la luz que se origina de un punto particular en la muestra incidiría en el detector exactamente en el mismo lugar y, por lo tanto, contribuiría a exactamente el mismo píxel. Sin embargo, en la práctica, la luz que se origina de un punto no se puede enfocar hacia un único punto del detector. En consecuencia, puede acabar repartido entre varios píxeles. El resultado final es que la imagen está borrosa.

  2. Incertidumbre en el brillo. Cuando una imagen está borrosa, también esperaríamos que fuera suave, pero esto no suele ser lo que obtenemos en la microscopía de fluorescencia. Más bien, hay variaciones aparentemente aleatorias de brillo en todas partes de la imagen: el ruido. Algo de ruido puede provenir de imprecisiones al determinar rápidamente la carga de pequeñas nubes de electrones. Pero, más fundamentalmente, la emisión de fotones es en sí misma aleatoria. Esto significa que incluso si pudiéramos detectar cada fotón perfectamente aún así obtendríamos imágenes ruidosas.

Estos problemas se describen en Figura 132.

Hide code cell content
fig = create_figure(figsize=(8, 4.5))

from skimage import draw
from skimage.transform import downscale_local_mean, rescale

def create_random_disks(shape, rng, n=10, min_radius=5, max_radius=15, dtype=np.float32):
    """
    Create random circular objects
    """
    im = np.zeros(shape, dtype=dtype)
    for ii in range(n):
        radius = min_radius + rng.random() * (max_radius - min_radius)
        cx = max_radius + np.floor(rng.random() * (shape[1] - max_radius*2))
        cy = max_radius + np.floor(rng.random() * (shape[0] - max_radius*2))
        coords = draw.disk((cy, cx), radius, shape=shape)
        im[coords] = 1.0
    return im

# Create an 'ideal' 2-channel image of structures (at high resolution)
size = 512
min_radius = 5
max_radius = 30
rng = np.random.default_rng(100)
n = 30
im_structures = np.dstack((
    create_random_disks((size, size), rng=rng, n=n, min_radius=min_radius, max_radius=max_radius),
    create_random_disks((size, size), rng=rng, n=n, min_radius=min_radius, max_radius=max_radius)
))

# Create a (lower-resolution) rasterized version
im_rasterized = downscale_local_mean(im_structures, (4, 4, 1))

# Simulate blur with PSF
sigma = 5
im_blurred = ndimage.gaussian_filter(im_rasterized, sigma=(sigma, sigma, 0)) * (2*np.pi*sigma*sigma)

# Simulate Poisson noise
im_noisy = rng.poisson(1 + im_blurred * 2)

# Convert to RGB
im_structures = create_rgb(im_structures, (('green', 'magenta')))
im_rasterized = create_rgb(im_rasterized, (('green', 'magenta')))
im_blurred = create_rgb(im_blurred, vmin=np.percentile(im_blurred, 0.01), vmax=np.percentile(im_blurred, 99.99), colors=(('green', 'magenta')))
im_noisy = create_rgb(im_noisy, vmin=np.percentile(im_noisy, 0.01), vmax=np.percentile(im_noisy, 99.99), colors=(('green', 'magenta')))

# Show images

def connect_axes(axA, axB):
    """
    Draw an arrow between two axes
    """
    from matplotlib.patches import ConnectionPatch
    con = ConnectionPatch(xyA=(1.02, 0.5), xyB=(-0.02, 0.5), coordsA=axA.transAxes, coordsB=axB.transAxes, 
                          arrowstyle="-|>", color=(0.25,)*3, linewidth=2, axesA=axA, axesB=axB)
    # fig.axes[1].add_artist(con)
    axB.add_artist(con)

show_image(im_structures, title='Real structures', pos=242)
show_image(im_rasterized, title='Digital image', pos=243)
connect_axes(fig.axes[-2], fig.axes[-1])

show_image(im_structures, title='Real structures', pos=245)
show_image(im_rasterized, title='Digital image', pos=246)
connect_axes(fig.axes[-2], fig.axes[-1])
show_image(im_blurred, title='Blurred image', pos=247)
connect_axes(fig.axes[-2], fig.axes[-1])
show_image(im_noisy, title='Blurred + Noisy image', pos=248)
connect_axes(fig.axes[-2], fig.axes[-1])

glue_fig('fig_imaging_colored_spots', fig)
../../../_images/75c3f4d44e0dcd3eb8ce808d2ebc55873b627d0a173078824747fde7cd5d7433.png

Figura 132 La diferencia entre lo que podríamos desear visualizar y lo que realmente podemos visualizar. (Arriba) Idealmente, los pequeños puntos de color en realided se asignarían directamente a puntos de color en la imagen, relacionados en términos de tamaño y separación. Esto haría que medir las estructuras fuera relativamente sencillo: lo que sea que midamos en la imagen corresponde exactamente a la realidad. (Abajo) En la práctica, la luz emitida desde nuestras estructuras reales terminaría produciendo objetos más grandes y borrosos en la imagen, además de ruido agregado. La imagen borrosa + ruidosa representa lo que realmente podemos adquirir con un microscopio óptico. Para el análisis, necesitamos utilizar esta imagen decididamente imperfecta para intentar determinar cuáles deberían ser las medidas de las estructuras reales.#

Los problemas gemelos de borrosidad (desenfoque) y ruido no afectan a todas las imágenes por igual. Por ejemplo, el desenfoque puede hacer que calculemos mal el tamaño de algo en varios cientos de nanómetros; si lo que estamos midiendo es mucho mayor que esto, entonces el error relativo puede ser trivial, pero si es más pequeño, entonces el error relativo puede ser enorme. De manera similar, si detectamos muchos miles de fotones, entonces la incertidumbre debida al ruido puede ser extremadamente pequeña en relación con los números involucrados, pero si tenemos pocos fotones, entonces el ruido podría dominar nuestros resultados.

Los mayores desafíos surgen cuando estamos interesados en medir estructuras diminutas en imágenes que contienen sólo decenas de fotones en sus puntos más brillantes. Esto es inconvenientemente común. En tales casos, no se pueden ignorar los efectos del desenfoque y el ruido.

La buena noticia es que el procesamiento de imágenes puede ayudarnos. Sin embargo, debemos comprender el problema para poder elegir las técnicas de procesamiento adecuadas. Por esa razón, los próximos dos capítulos describirán el desenfoque y el ruido con más detalle y señalarán formas en que podemos abordarlos.