Ir al contenido

PGD | §2.4 – Almacenamiento de una imagen digital

< §2.3 – Cuantificación en aplicaciones reales

Una vez resuelto el problema de la digitalización, queda por ver como se procede a guardar o almacenar la imagen para su uso posterior. Hemos mencionado ya algunos dispositivos capaces de alcanzar este objetivo; ahora podemos dar una descripción más completa.

Los dispositivos de almacenamiento pueden clasificarse de varias maneras; en particular, por el tipo de medio (mecánico, magnético, óptico o semiconductor); por su persistencia (volátil o no volátil); por sus posibilidades de modificación (lectura/escritura o lectura solamente); etc. Afortunadamente, para nuestros fines, todos ellos tienen en común que pueden considerarse equivalentes en cuanto a la organización de la información allí almacenada.

Básicamente podemos pensar que cada medio de almacenamiento nos permite guardar una secuencia de bytes de longitud arbitraria (dentro de la capacidad del medio) y leerla en algún momento posterior. Esta secuencia de bytes almacenados se denomina habitualmente archivo (file) y recibe una descripción textual o título que lo identifica, llamado nombre del archivo (filename). Además, el medio debe proveer algún sistema de administración de estos archivos, para poder guardar sus nombres, ubicar cualquiera de ellos dentro del mismo, saber la cantidad de bytes que ocupa (su longitud), la fecha de su creación, organizarlos en grupos llamados carpetas (folders) o también directorios (directories), conocer la lista de los archivos presentes, etc. Estas funciones las realiza el sistema de archivos (filesystem) y debe existir para que el medio de almacenamiento sea utilizable en la práctica. La creación de un determinado sistema de archivos en un medio es un proceso que debe hacerse previamente a su uso y que comúnmente se conoce como formateo (formatting).

Un sistema de archivos ignora en general el contenido de cada archivo; sólo nos suministra, por así decirlo, la logística necesaria. Queda librado a los usuarios del sistema de archivos (es decir, los programas que los leen y crean) el significado de la información que contienen.

El problema se reduce, pues, a decidir cómo determinada información a guardar se convierte en una secuencia de bytes, de manera que pueda ser utilizada en el futuro, por nosotros o por terceros. Es común llamar a este proceso serialización, ya que implica adoptar un método reversible para tomar la información a almacenar en su presentación original y convertirla en una serie o secuencia de bytes. Según el tipo de información, en algunos casos esa conversión será más o menos natural; en otros existirá un cierto grado de libertad para decidir cuál será dicha secuencia.

Por ejemplo, si la información es texto, donde cada carácter (número, letra, signo de puntuación) está representado por un código (digamos ASCII extendido de 1 byte), por ser ya el texto una secuencia de caracteres, resulta natural convertirlo en una secuencia de bytes igual a los códigos respectivos. En cambio, en una imagen no hay un orden natural, ya que tenemos una organización de muestras en dos dimensiones, a cada una de las cuales les corresponde una cantidad de bytes que depende de su cuantificación. Por ello debemos asegurarnos que cualquiera sea el orden en que se almacena cada byte (la secuencia elegida), esta forma sea conocida por quien leerá el archivo para obtener nuevamente la imagen digital original. Por ejemplo, en una imagen color RGB, puede crearse una secuencia colocando los tres bytes correspondientes a los valores RGB de la primera muestra (que podemos considerar la superior izquierda) para seguir hacia la derecha con otros tres bytes de la segunda muestra, y así sucesivamente hasta completar la primera fila; luego hacer lo mismo con la segunda fila, etc., hasta completar la imagen; en este esquema, estamos guardando la imagen por pixeles. Si N es el número total de muestras, y cada subíndice indica el número de pixel, la secuencia quedaría

R1G1B1R2G2B2R3G3B3… RN-1GN-1BN-1RNGNBN.

(Total: 3xN bytes)

Otra posibilidad es guardar la imagen por canales, es decir guardar primero toda la información para un canal, y repetir el proceso con los canales restantes:

R1R2R3…RN-1RNG1G2G3…GN-1GNB1B2B3…BN-1BN.

(Total: 3xN bytes)

También es posible aplicar ambos métodos pero examinando la imagen por columnas en lugar de hacerlo por filas, etc. Queda claro que, en cualquiera de estos casos, será necesario conocer previamente la longitud de cada línea (es decir el número de muestras horizontales NW) para saber cuándo una fila termina y empieza la siguiente (o, de manera correspondiente, el número de muestras verticales NH para distinguir el final y comienzo de una columna). Por último, también el orden RGB podría cambiarse a BGR, RBG, etc.

Además, para que el archivo que contiene la imagen sea útil no sólo debemos guardar las muestras cuantificadas, sino que también deberemos guardar otros datos, como sus dimensiones, la resolución empleada en su muestreo, etc.

El mejor modo de lograrlo es definir una forma estándar de guardar en un archivo la secuencia, junto con cualquier dato adicional relativo a la imagen. Esta forma estándar se denomina formato de archivo (file format), cuya especificación está en general públicamente disponible, aunque su uso podrá ser o no gratuito; en este último caso, su empleo para almacenar imágenes puede estar sujeto al pago de licencias de uso. Es común indicar el formato empleado usando un nombre de archivo finalizado con un sufijo llamado extensión (file extension), formado por un punto seguido generalmente de tres o cuatro caracteres que identifican ese formato.

Todo esto nos indica que, cualquiera sea la información a almacenar, es necesario agregar datos adicionales para que esa información sea accesible, según la especificación del formato de archivo utilizado. Por esto, definiremos:

Llamaremos peso de archivo a la cantidad total de información que requiere un determinado formato de archivo para guardar datos.

Identificaremos el peso de archivo con el símbolo PA.

Si el peso de la información guardada es P, los datos adicionales que se guardarán con ella harán que se cumpla en general:
PA > P

Gráficamente, podemos representar esta relación así:

Datos adicionales P (peso de la información a almacenar)
PA (Peso de archivo)

No obstante, el peso de esos datos adicionales[1] (tratándose de imágenes) es normalmente muy pequeño en comparación con la información en sí (en general mucho menor al 1%), por lo cual en la práctica, sobre todo al realizar estimaciones, se considera que el peso de archivo es casi igual al peso de la información original, es decir:

PA ~ P.

Compresión de datos

Sabemos que es fácil superar el millón de muestras en imágenes digitales de uso cotidiano. Si multiplicamos este millón por el número de bytes requerido por la cuantificación adoptada vemos que cualquier imagen requiere archivos de al menos varios millones de bytes. Siempre ha sido de interés lograr maneras de codificar la misma información utilizando el mínimo número posible de símbolos para así reducir el tiempo necesario para su transmisión o el volumen de su almacenamiento.

Ahora bien, si en su momento definimos la cantidad de información contenida en cada mensaje en función de los distintos mensajes disponibles, ¿cómo es posible utilizar menos información que ésa?

Supongamos que cada mensaje requiere n bits (porque procede de un conjunto de 2n mensajes). Entonces dos mensajes consecutivos requerirán 2 x n bits, tres mensajes 3 x n bits, etc., siempre y cuando los mensajes sean independientes entre sí, es decir, cuando la recepción del primer mensaje no me permite anticipar cuál será el segundo, ni siquiera acotar el conjunto de posibilidades.

Sin embargo, esto no suele ser así. Si los mensajes son los distintos caracteres que forman un texto, la recepción de un carácter particular muchas veces condiciona el carácter siguiente que es probable recibir. Por ejemplo, en un mensaje escrito en español, la recepción de la letra “q” hará prácticamente seguro que la siguiente letra del mensaje sea una “u”, y después de ésta, hará muy probable que la tercera sea una “e” o una “i”. Supongamos que se utilizan 5 bits para codificar un carácter; observemos que, bajo la suposición de independencia total, al recibir una “q” la información contenida en las siguientes dos letras es de 10 bits (5 + 5), mientras que si sabemos que el idioma del texto es español, la misma información es sólo 1 bit, pues sólo existen dos posibilidades: “ue” o “ui” [2].

También en las imágenes sucede algo similar. Si una muestra tiene un valor particular, digamos en la gama del azul por pertenecer al cielo en un paisaje, es muy improbable que una muestra adyacente sea completamente opuesta, por ejemplo amarilla; es mucho más probable que sea un azul parecido o incluso el mismo. Luego, si la imagen está cuantificada en RGB, la segunda muestra no transporta 24 bits de información (que potencialmente corresponde a cualquier color entre los 224 = 16.777.216 colores posibles) sino que transporta muchos menos, quizás unos pocos bits[3].

Cuando esto sucede, se dice que la fuente de información contiene redundancia, ya que ciertas secuencias parciales son mucho más probables que otras; es otra forma de decir que las muestras consecutivas no son completamente independientes. Un algoritmo de compresión tiene por objeto hallar y explotar estas redundancias para deducir una descripción equivalente de la misma fuente pero que requiera menos bits en total[4]. El mismo algoritmo invertido define el procedimiento necesario para realizar la operación opuesta, es decir, la descompresión del archivo, para obtener nuevamente la información original.

Actividades para el capítulo §2.4

  1. Suponga una pequeña imagen de 4 x 3 pixeles (12 muestras en total). Si esa imagen está cuantificada en RGB de 8 bits (1 byte) por canal, serán necesarios 12 x 3 = 36 bytes para su almacenamiento. La siguiente secuencia de 36 bytes,
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0  0 0 128 0 0 128 0 0 128 0 0 128 0
    representa esta sencilla imagen, asumiendo que está guardada por píxeles, por fila:

    ¿Que imagen obtendría si erróneamente interpretara esta secuencia por pixeles, por columnas? ¿Cuál sería si la interpretara por canales, por fila?

  2. El ejemplo anterior muestra que con sólo los datos de la imagen puestos en secuencia no estaremos en condiciones de reconstruir la imagen sin alguna información adicional. Para que un archivo de imagen esté autocontenido, será necesario guardar junto con esa secuencia esos datos necesarios para su interpretación. Analice cuántos datos adicionales sería necesario guardar con la imagen como mínimo para que pueda reconstruirse sin error ni suposiciones extra.
  3. ¿Es posible saber la resolución de esta imagen con los datos dados?
§2.5 – Métodos de compresión en la práctica >

1 A veces se denomina sobrecarga (overhead) del formato a esa cantidad adicional de información que debe incluirse para que el formato tenga utilidad operativa. Esta sobrecarga es porcentualmente pequeña en los archivos de imagen, no porque sean pocos datos, sino porque la información generada por una imagen es alta y la sobrepasa en varios órdenes de magnitud.
2 De hecho, la información contenida en el segundo carácter es cero, pues es seguro que se trata de una “u”, mientras que el tercer carácter contiene 1 bit; los dos caracteres juntos contienen, pues, 0 + 1 = 1 bit.
3 Aquí nos falta el “idioma” que nos permita precisar cuántos bits en realidad se requieren para codificar la muestra siguiente; ese papel lo cumple la estadística de esa imagen particular, que nos dirá que tan probables son los tonos azules.
4 Uno podría preguntarse: si la aplicación de un algoritmo de compresión reduce la cantidad de bits necesaria para representar un “mensaje” (un texto, una imagen, etc.), ¿por qué no definimos la información a partir de la cantidad de bits del mensaje “comprimido”? Una razón es que el modelo de mensajes presentado permite tratar el tema de manera sencilla, permitiendo una traducción más o menos simple y directa entre mensajes y secuencias de bits, a expensas de suponer que todos los mensajes son equiprobables. Por otro lado, es imposible la compresión sistemática de cualquier archivo, cualquiera sea el algoritmo de compresión elegido; una demostración de esta imposibilidad puede verse aquí.