ImageJ: operaciones puntuales#

Introducción#

Esta sección presenta el procesamiento de imágenes con ImageJ. Muestra dónde encontrar las operaciones principales, incluyendo algunos consejos (y advertencias) sobre su uso, junto con algunos ejercicios para probarlas.

Antes de comenzar#

Antes de embarcarnos en el procesamiento de píxeles, hay un par de cosas que debemos saber hacer como preparación.

Duplicar imágenes#

Uno de los atajos de ImageJ más importantes que debes aprender es Shift+D para duplicar la imagen. Esto aplica el comando Image ‣ Duplicate….

Poder duplicar rápidamente una imagen es importante por dos razones principales:

  1. A menudo queremos procesar duplicados de una imagen de diferentes maneras y luego combinar o comparar los resultados.

  2. Los errores pasan y Edit ‣ Undo es bastante limitado; puede deshacer algunos pasos de procesamiento aplicados a una imagen, pero no siempre… y no puede deshacer operaciones aplicadas a pilas de imágenes

Cuando trabajo con una imagen en ImageJ, casi siempre tengo al menos un duplicado disponible para cuando las cosas inevitablemente salgan mal.

Pero Image ‣ Duplicate… tiene una ventaja adicional oculta: admite la extracción solo de una parte de la imagen. Esto se controla tanto mediante cualquier ROI como mediante la selección de subconjuntos de canales, cortes z o punto de tiempo cuando sea relevante. Con frecuencia uso la duplicación como una forma de extraer el canal de una imagen, como una alternativa más conveniente a Image ‣ Color ‣ Split Channels.

../../../_images/imagej-points-duplicate.png

¿Por qué “Undo” de ImageJ no puede deshacer mucho?

Implementar “deshacer” en el software es bastante complicado. Especialmente en software flexible que permite al usuario hacer muchas cosas diferentes.

Cuando se trata de procesamiento de imágenes, deshacer (undo) efectivamente requiere que el software duplique silenciosamente los valores de píxeles de una imagen antes de cualquier paso de procesamiento, para que puedan recuperarse más tarde si es necesario. Para una imagen pequeña, eso puede funcionar bien. Pero para imágenes grandes (digamos, 1 GB o más), duplicar esa cantidad de datos podría ralentizar significativamente el software y probablemente provocar muchos errores de falta de memoria.

ImageJ proporciona soporte muy limitado para «undo» para cortes 2D, pero es mejor no confiar en él. En general, queda en manos del usuario decidir cuándo es necesario realizar la duplicación. Si sospecha que podría arrepentirse de un paso de procesamiento, lo mejor es siempre duplicar la imagen de antemano con Shift+D.

Conversión a 32 bits#

El segundo paso que hago a menudo cuando proceso una imagen en ImageJ es convertirla a punto flotante de 32 bits, usando Image ‣ Type – > 32 bit.

Esto no siempre es esencial, pero pronto veremos ejemplos en los que el tipo de imagen marca la diferencia en el resultado. Por lo tanto, al menos siempre deberías considerar la posibilidad de realizar la conversión.

Operaciones puntuales para imágenes individuales.#

Muchas operaciones de puntos para imágenes individuales se encuentran en el submenú Process ‣ Math ‣. En la parte superior de la lista están las operaciones aritméticas: Add…, Subtract… , Multiply… y Divide…que se refieren a las operaciones Sumar, Restar, Multiplicar y Dividir, respectivamente.

Abra la imagen Spooked_16-bit.tif y aplique solo los siguientes pasos:

  • Mide el valor medio de píxeles de la imagen.

  • Resta 600 de todos los valores de píxeles

  • Agrega 600 a todos los valores de píxeles

  • Mide el valor medio de píxeles de la imagen.

Matemáticamente, deberías obtener las mismas medidas medias. ¿Puedes explicar el resultado?

lanzar ImageJ.JS

En primer lugar, los comandos que debes ejecutar son:

  • Analyze ‣ Measure, o presiona M

  • Process ‣ Math ‣ Subtract… con el valor 600

  • Process ‣ Math ‣ Add… con el valor 600

  • Analyze ‣ Measure, o presiona M

Cuando hago esto, obtengo la siguiente tabla de resultados:

../../../_images/points-spooked-subtraction.png

La razón por la que los valores medios difieren es porque tenemos una imagen de 16 bits. Después de la resta, cualquier valor inferior a 600 se recorta a cero. Todos estos se convierten en 600 después de la suma, lo que eleva la media general.

Si no viste este efecto, supongo que tuviste la previsión de ejecutar Imagen ‣ Type ‣ 32 bit. Si haces esto, los valores medios coincidirán después de todo.

Los comandos Process ‣ Math ‣ Log… y Process ‣ Math– > Gamma… implementan las transformaciones log y gamma respectivamente. La transformación gamma es más común porque contiene un parámetro gamma ajustable que se puede utilizar para ajustar el efecto.

¡Cuidado con la profundidad de bits con transformaciones no lineales!

Al aplicar transformaciones gamma o logarítmicas a imágenes de 8 o 16 bits, ImageJ aplica un cambio de escala adicional (lineal) al resultado para que el output esté dentro del rango admitido por la imagen.

Este cambio de escala no es necesario para imágenes de 32 bits. Esto significa que si aplicas cualquiera de los comandos a una imagen de 32 bits, puede parecer que la imagen desaparece. Deberás realizar un seguimiento usando Image ‣ Adjust ‣ Brightness/Contrast… para re-establecer el rango de visualización de LUT y ver el output correctamente.

Explore el uso de Process ‣ Math ‣ Gamma… para mejorar el contraste de Spooked_16-bit.tif.

Si desea ver tanto al humano como al fantasma, ¿el valor gamma debería ser menor que 1, igual a 1 o mayor que 1?

Consejo: Para tener una idea de cómo cambian los valores, primero crea un histograma de la imagen y presiona el botón Live en el histograma. Luego ejecuta el comando gamma, activa la opción Preview y ajusta el control deslizante. Ahora deberías ver una actualización en vivo de cómo el cambio de gamma afecta los valores de píxeles.

lanzar ImageJ.JS

La gamma debe ser menor que 1.

Cuando la gamma es igual a 1, no hace nada en absoluto. Cuando es mayor que 1, se aplica un ajuste no lineal, pero no es uno que realmente ayude en este caso.

Inversión de imagen#

El comando Edit ‣ Invert implementa la inversión de la imagen.

¿Invertir imágenes o invertir LUT?

Edit ‣ Invert no debe confundirse con Image ‣ Lookup Tables ‣ Invert LUT, que invierte la LUT pero ¡no hace nada con los valores de píxeles!

Además, si la LUT está invertida se puede guardar dentro del archivo, por lo que potencialmente podrías abrir una imagen y descubrir que tu LUT se invirtió incluso antes de comenzar a hacer algo y, por lo tanto, juzgar mal si las estructuras son realmente más brillantes o más oscuras que todo lo demás.

File ‣ Open samples ‣ Blobs es un ejemplo de esto. Pasó mucho tiempo antes de que me diera cuenta de que los valores de píxeles dentro de las manchas son más altos que los del fondo, debido al astuto LUT invertido. Como suele ser el caso, los signos de una LUT invertida son evidentes en el texto en la parte superior de una ventana de imagen.

../../../_images/points-blobs-inverting.png

Edit ‣ Invert funciona de manera diferente cuando se aplica a diferentes tipos de imágenes. Como en el caso de 8 bits, los valores de píxeles siempre se restan de algún «máximo».

¿Cómo se determina este máximo para imágenes de 16 y 32 bits en ImageJ?

Nota: ¡los métodos utilizados para imágenes de 16 y 32 bits son diferentes entre sí!

lanzar ImageJ.JS

Cuando escribí esta pregunta por primera vez, para invertir una imagen de 16 bits se restaban píxeles de el valor máximo dentro de la imagen original. Esto también es válido para las pilas de imagenes (z-stacks): se encuentra el valor máximo en toda la pila.

Desde ImageJ v1.53k, se utiliza el valor máximo de 65535… a menos que tenga un valor Unsigned 6-bit range diferente especificado a través de {guilabel}botón Establecer a través del cuadro de diálogo Brightness and Contrast. Solo conozco esta opción alternativa furtiva a través de las [notas de la versión de ImageJ] (https://imagej.nih.gov/ij/notes.html).

Para la inversión de imágenes de 32 bits, los píxeles se restan del máximo de visualización, es decir, cualquier máximo establecido en el cuadro de dialogo Image ‣ Adjust ‣ Brightness/Contrast …. Por lo tanto, invertir una imagen de 32 bits puede dar resultados diferentes cada vez que se aplica si la configuración de contraste no se mantiene igual.

Personalmente no me gusta esta rareza impredecible. Con mucho gusto aplicaría Edit ‣ Invert a una imagen de 8 bits. Para cualquier otra cosa, generalmente prefiero convertir a 32 bits y multiplicar por -1, para saber que los resultados son reproducibles, independientemente de las configuraciones de brillo y contraste.

La calculadora de imágenes#

Process ‣ Math ‣ Image Calculator… se utiliza para combinar dos imágenes de varias maneras. Es uno de los comandos más indispensables de ImageJ.

../../../_images/points-image-calculator.png

Figura 62 El cuadro de diálogo Image Calculator…#

¡Pero cuidado con la profundidad de bits y el tipo! Si alguna de las imágenes originales es de 8 o 16 bits, es posible que sea necesario recortar o redondear el resultado, en cuyo caso debes seleccionar la opción para crear un resultado de 32 bits (float) puede ser necesario para obtener el output esperado.

Process ‣ Math ‣ Image Calculator… finalmente nos permite verificar si los valores de píxeles de dos imágenes son todos idénticos, sin depender de mediciones resumidas o histogramas.

Úsalo para determinar cuáles dos de las imágenes Same_1.tif, Same_2.tif y Same_3.tif son idénticas en términos de valores de píxeles.

lanzar ImageJ.JS

Mi forma preferida de comprobar esto es restar las imágenes entre sí, asegurándome de que el resultado sea de 32 bits (en caso de que haya valores negativos). Hacer esto debería revelar algo oculto en la imagen Same_2.tif. Ten en cuenta que la configuración de contraste difiere entre Same_1.tif y Same_3.tif, por lo que pueden verse diferentes.

(Tenga en cuenta que también se pueden utilizar los comandos Differnce o Divide de la calculadora. XOR también funcionaría, pero su output es más difícil de interpretar ya que implica comparar bits individuales utilizados para almacenar cada valor de píxel y proporciona un output donde todos los bits coincidentes son 0 y todos los bits no coincidentes son 1. Cuando se vuelven a convertir a valores decimales reales y luego a colores para que podamos verlos, esto puede parecer extraño, pero al menos si la imagen resultante no es completamente negra, entonces sabemos que las imágenes de input originales no eran idénticas).