sábado, 3 de octubre de 2020

Como se almacena una imagen digitalmente (Primera parte)

 
Explicado fácil, de una vez por todas y más biológico de lo que creen

Creo que a estas alturas, nadie puede negar la importancia de los ordenadores en el desarrollo de la ciencia en general y de las biológicas en particular. El uso de computadoras avanzó tanto, que hoy en día casi nadie puede prescindir de la ayuda de algún análisis bioinformático para sus trabajos. Es más, los bioinformátic@s, pasaron de ser considerados como “es@s vag@s que están todo el día frente a la compu sin tocar un tubo” (aparentemente, el símbolo del trabajo duro para un químico), a ser unos tip@s bastante copad@s (según mi opinión).

La presente, es la primera de una serie de tres notas que tienen que ver con las bases sobre el uso de la memoria digital en nuestros ordenadores, sobre un paralelismo con el almacenamiento de la información genética y de como ambos mecanismos de almacenamiento están empezando a fucionarse (!Faaaaaa! -diría Zamba).

 

 Faaaaaaaaaaaaaaaaaa!!!


¡Se va la primera!


En mí último video de YouTube, di un tutorial de como usar el programa ImageJ para cuantificar la intensidad de bandas en una imagen de western blot (enlace al video).


 

Luego de hacer ese video, me quedé con las ganas de explicar los principios básicos de como el programa cuantifica esas bandas, y la clave de todo esto (creo), estaría en la forma que la computadora almacena las imágenes en su memoria.


Vamos desde el principio

Cuando abrimos cualquier imagen en nuestra computadora y le hacemos suficiente zoom, vemos que la misma está compuesta por miles y miles de pequeños cuadritos (ver figura 1). Cada uno de esos cuadritos se llama píxel (que es un acrónimo de picture element, o “elemento de imagen” en ingles).


Nota 1: De ahí viene el nombre de la compañía PIXAR, la cual sería una combinación de las palabras arte y píxeles (seguro que no se lo veían venir ;-)).


Figura 1: Imagen compuesta por 1.524.750 píxeles. Luego de 18 aumentos, se hacen evidentes los píxeles que componen la imagen.

 

Tampoco esto de hacer imágenes con cuadritos es algo muy novedosos. Los griegos y los romanos lo hacían hace miles de años, y ni hablar de mamá naturaleza, que lo viene haciendo desde hace millones. Por supuesto, esta “idea” es también la base del funcionamiento de nuestros monitores de TV, celulares y computadoras (ver figura 2).

 

Figura 2: 1) fragmento de un mosaico romano encontrado al oeste de la capital de Chipre. 2) Imagen de una serpiente cobra. 3) Escamas de las alas de una mariposa. 4) configuración de los píxeles de diferentes modelos de monitor.

https://www.nationalgeographic.com.es/historia/actualidad/mosaico-muestra-trepidante-carrera-carros-sale-chipre_10603

 

Una vez que sabemos como componer una imagen a través de elementos simples, ya tenemos resuelto la mitad del problema. El siguiente paso es ver como codificar esta información visual en otro formato.

Como ya sabemos, las computadoras solo pueden almacenar información en “cadenas” de números (binarios, pero números al fin), así que tenemos que ver la forma de traducir todos estos píxeles a números.

Para esto, hagamos el siguiente ejercicio:

Supongamos que tenemos que traducir una imagen un código de números y anotarlos en una libreta. Esta información debe estar redactad de forma tal, que cualquier persona que la lea y conozca “el código”, pueda reconstruir la imagen original. Para esto, procedemos de la siguiente manera:

1) Tomemos esta pequeña imagen simplificada, por ejemplo, Messi pateando una pelota (figura 3).


 Figura 3: Messi pateando una pelota (¿o es Maradona?)

 

Nota 2: Vamos…, Un poco de imaginación che!!! ¿qué?... ¿no ven donde está la pelota?


2) Dividamos la imagen en una grilla que incluya todos los píxeles y definamos un set de coordenadas para cada uno (figura 4).

 

Figura 4: izquierda: La figura se divide en una grilla de 5x5 píxeles. Derecha: Cada píxel tiene una coordenada fija.


3) Asignamos a cada píxel un valor numérico según el color que tenga. Para esto podemos usar la escala de la figura 5. Luego les cuento por qué escogí esta escala.

Figura 5: Escala numérica que cuantifica la intensidad de cada píxel. A mayor luminosidad, mayor es el valor de cada píxel.

 

4) Basándonos en esto, podemos reemplazar cada color por su valor numérico (figura 6).

Figura 6: Cada píxel es traducido a su equivalente en números enteros.

 

5) Entonces, escribimos la lista de píxeles según su orden (coordenada) como:


255-255-0-255-255-0-0-0-0-0-255-255-0-255-255-255-0-255-0-255-255-0-255-0-85


Nota 3: Si alguien tuviera que usar esta información para reconstruir la imagen, necesitará saber el tamaño de la misma. Así que deberíamos agregar información del alto y el ancho de la imagen (preferentemente al comienzo de la lista).


5-5-255-255-0-255-255-0-0-0-0-0-255-255-0-255-255-255-0-255-0-255-255-0-255-0-85


Listo, ya tenemos una cadena de números para reconstruir nuestra imagen. Solo que hay un pequeño problema. En nuestra libreta imaginaria, solo se pueden guardar números (ni comas, ni guiones, ni espacios, solo números) y si tengo que guardar más de una imagen la cosa quedaría más o menos así:


Una imagen:

552552550255255000002552550255255255025502552550255085

Dos imágenes iguales (podrían ser diferentes):

552552550255255000002552550255255255025502552550255085

552552550255255000002552550255255255025502552550255085

 

¿Se entiende algo?

 

Como ven, no podemos saber si la imagen es de 5x5, 55x25 o 552x5525 píxeles. Tampoco sabemos si se trata de solo una imagen (u otro tipo de información).

Por lo tanto, necesitamos establecer un “origen” y “un marco de lectura” para poder “traducir” la información.


¿Les resulta familiar?

Pues claro que es familiar.

Este problema lo resolvió mamá naturaleza hace millones de años (figura 8). En este caso, la información que codifica una proteína (gen), esta almacenada en una cadena de nucleidos de ADN. Esta información debe incluir (al igual que con nuestro archivo de imágenes) una señal de inicio que le permita a la maquinaria celular reconocer el comienzo del gen (promotor) y utilizar el marco de lectura correcto (figura 7 y 8). 

 

Figura 7: representación esquemática de una unidad de transcripción en el genoma de un organismo. La dirección de la lectura puede variar según el gen se encuentre codificado en una cadena de ADN o en su complementaria.

 

Figura 8: A) Imagen de microscopia electrónica de la síntesis de proteínas en una célula eucariota (referencias al pie). B) Representación esquemática de la acción coordinada del ribosoma, el ARNm y el ARNt. Nótese los codones de 3 bases que representan cada aminoácido. C) Código genético utilizado por la célula para traducir una secuencia de ARNm a proteínas.

Nota 4: No creo que los informáticos, hayan copiado a la naturaleza para resolver el problema. El código genético se descubrió posteriormente a la creación de las primeras computadoras con memoria. Creo que este es un típico caso de convergencia evolutiva. Ambos bandos tenían que guardar información en un soporte bidimencional (una cuerda), y no hay muchas opciones que digamos.

 

Volvamos a lo nuestro...


Para el tema del origen, podríamos generar una secuencia de 3 números (por ejemplo 999) y para el caso del marco de lectura, agregamos ceros a la izquierda para que todos los valores tengan tres dígitos (vamos a leer de tres en tres).


El archivo nos quedaría así:


999005005255255000255255000000000000000255255000255255255000255000255255000

255000085


Nota 5: He intercalado en negrita para que resulte más fácil de leer.


999 : Inicio del archivo. También podría indicar el tipo de archivo a codificar (imagen, texto, video, etc)


005005: La imagen tiene 5x5 píxeles.


255255000255255: Información de los 5 primeros píxeles de la imagen (primera línea). Los siguientes 5 píxeles los agrego abajo y así hasta el final.

Como ven, ya tenemos una estrategia básica de como guardar imágenes codificadas en una cadena de números.

La estructura real de los archivos de imágenes que usamos todos los días (bmp, png, jpeg, tiff etc.) no son tan simples como la que les mostré, pero siguen esta idea.

En este enlace, les dejo como ejemplo la estructura de datos de los archivos de imágenes BMP.

https://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header


¿Cómo funciona entonces la cuantificación de bandas de imageJ?


Teniendo en cuenta todo esto, el programa ImageJ “simplemente” lo que hace es sumar todos los píxeles de cada línea en el rectángulo seleccionado. Luego hace un gráfico de la suma en función de cada línea (figura 9).


Nota 6: Posiblemente es un poco más complicado que esto, pero esa es la idea.

Figura 9: De izquierda a derecha: Representación esquemática de como el programa imageJ (y otros similares) cuantifican los píxeles de una imagen para cuantificar la intensidad de señal en un área dada. En este ejemplo se usó la imagen completa. Nótese que antes de graficar se invirtió el valor de los píxeles, ya que resulta más intuitivo que los píxeles negros represente una señal positiva.

 

Si todo muy bonito, pero las computadoras utilizan números binarios, no números decimales.

¿ y los colores?

¿y las transparencias?

¿que significa 8, 16, 24 y 32 bits?

 

Obviamente, me quedaron algunas cosas en el tintero. Todo eso lo dejamos para segunda parte.

No hay comentarios.:

Publicar un comentario

Ciencia libre con Software libre

Muchas veces, por costumbre o desconocimiento, trabajamos con un número limitado de programas. Estos programas normalmente son pagos y su ...