Cómo funciona el formato JPEG

Las imágenes JPEG son omnipresentes en nuestra vida digital, pero detrás de ese manto de conciencia se esconden algoritmos que eliminan detalles que el ojo humano no puede ver. El resultado es la máxima calidad visual en el tamaño de archivo más pequeño, pero ¿cómo funciona exactamente? ¡Veamos qué es exactamente lo que nuestros ojos no ven!

Cómo funciona el formato JPEG

Es fácil dar por sentado la posibilidad de enviar una foto a un amigo y no preocuparse por qué dispositivo, navegador o sistema operativo está usando, pero no siempre fue así. A principios de la década de 1980, las computadoras podían almacenar y mostrar imágenes digitales, pero había muchas ideas en competencia sobre la mejor manera de hacerlo. No se podía simplemente enviar una imagen de una computadora a otra y esperar que funcionara.

Para resolver este problema, en 1986 se reunió un comité de expertos de todo el mundo bajo el nombre "Joint Photographic Experts Group”(Joint Photographic Experts Group, JPEG), fundado como parte del trabajo conjunto de la Organización Internacional de Normalización (ISO) y la Comisión Electrotécnica Internacional (IEC), dos organizaciones internacionales de normalización con sede en Ginebra (Suiza).

Un grupo de personas llamado JPEG creó el estándar de compresión de imágenes digitales JPEG en 1992. Cualquiera que haya utilizado Internet probablemente se haya encontrado con imágenes codificadas en JPEG. Esta es la forma más común de codificar, enviar y almacenar imágenes. Desde páginas web hasta correos electrónicos y redes sociales, JPEG se utiliza miles de millones de veces al día, casi cada vez que vemos o enviamos una imagen en línea. Sin archivos JPEG, la Web sería menos brillante, más lenta y probablemente tendría menos imágenes de gatos.

Este artículo trata sobre cómo decodificar una imagen JPEG. En otras palabras, sobre lo que se requiere para convertir datos comprimidos almacenados en una computadora en una imagen que aparece en la pantalla. Vale la pena saberlo, no sólo porque es importante para entender la tecnología que utilizamos a diario, sino también porque al revelar los niveles de compresión conoceremos mejor la percepción y la visión, así como qué detalles son más importantes para nuestros ojos. sensible a.

Además, es muy interesante jugar con las imágenes de esta forma.

Cómo funciona el formato JPEG

Mirando dentro de un JPEG

En una computadora, todo se almacena como una secuencia de números binarios. Normalmente estos bits, ceros y unos, se agrupan en ochos, formando bytes. Cuando abres una imagen JPEG en tu computadora, algo (navegador, sistema operativo, lo que sea) tiene que decodificar los bytes, restaurando la imagen original como una lista de colores que se pueden mostrar.

Si descargas este lindo foto de un gato y ábrelo en un editor de texto, verás un montón de caracteres mezclados.

Cómo funciona el formato JPEG
Aquí estoy usando Notepad++ para inspeccionar el contenido del archivo, porque los editores de texto comunes como el Bloc de notas de Windows estropearán el binario después de guardarlo y no se ajustará al formato JPEG.

Abrir una imagen en un editor de texto confunde a tu computadora, ¡al igual que confundes a tu cerebro cuando te frotas los ojos y comienzas a ver manchas de colores!

Estos puntos que ves se conocen como fosfenos, y no son el resultado de la exposición a un estímulo luminoso o alucinaciones generadas por la mente. Ocurren porque su cerebro piensa que cualquier señal eléctrica en los nervios ópticos transporta información sobre la luz. El cerebro necesita hacer tales suposiciones, porque no hay forma de saber si la señal es un sonido, una visión u otra cosa. Todos los nervios del cuerpo transmiten exactamente los mismos impulsos eléctricos. Cuando aplicas presión en tus ojos, envías señales que no son visuales, pero activan receptores en el ojo, que tu cerebro interpreta (en este caso, incorrectamente) como algo visual. ¡Literalmente puedes ver la presión!

Es curioso pensar en cuán similares son las computadoras al cerebro, pero también es una analogía útil, que ilustra cuánto depende el significado de los datos, ya sea que los nervios los transmitan a través del cuerpo o los almacenen en una computadora, de cómo se interpretan. Todos los datos binarios se componen de ceros y unos, componentes básicos capaces de transmitir cualquier tipo de información. Su computadora a menudo adivina cómo interpretarlos usando pistas como las extensiones de archivos. Ahora hacemos que los interprete como texto, porque eso es lo que espera el editor de texto.

Para entender cómo decodificar un JPEG, necesitamos ver las señales originales: los datos binarios. Esto se puede hacer con un editor hexadecimal o directamente en página web del artículo original! Hay una imagen junto a la cual, en el campo de texto, todos sus bytes (excepto el encabezado) se presentan en formato decimal. Puede cambiarlos y el script se recodificará y producirá una nueva imagen sobre la marcha.

Cómo funciona el formato JPEG

Puedes aprender mucho simplemente jugando con este editor. Por ejemplo, ¿puedes decir en qué orden se almacenan los píxeles?

En este ejemplo, lo extraño es que cambiar algunos números no afecta en absoluto a la imagen y, por ejemplo, si reemplazas el número 17 por 0 en la primera línea, ¡la foto se arruinará por completo!

Cómo funciona el formato JPEG

Otros cambios, como cambiar el 7 en la línea 1988 a 254, cambian el color, pero solo los píxeles posteriores.

Cómo funciona el formato JPEG

Quizás lo más extraño es que algunos números cambian no solo el color, sino también la forma de la imagen. Cambie 70 en la línea 12 a 2 y mire la fila superior de la imagen para ver a qué me refiero.

Cómo funciona el formato JPEG

Y no importa qué imagen JPEG utilices, siempre encontrarás esos patrones de ajedrez crípticos al editar bytes.

Al jugar con el editor, es difícil descubrir cómo recrear una foto a partir de estos bytes, ya que la compresión JPEG consta de tres tecnologías diferentes que se aplican secuencialmente en niveles. Estudiaremos cada uno de ellos por separado para descubrir el misterioso comportamiento que observamos.

Tres niveles de compresión JPEG:

  1. submuestreo de color.
  2. Transformada de coseno discreta y discretización.
  3. Codificación de longitud de ejecución, delta и huffman

Para darle una idea de la escala de la compresión, tenga en cuenta que la imagen de arriba representa 79 números, lo que equivale aproximadamente a 819 KB. Si tuviéramos que almacenarlo sin compresión, necesitaríamos tres números para cada píxel: para los componentes rojo, verde y azul. Esto equivaldría a 79 números, o aproximadamente. 917 Kb. ¡Como resultado de la compresión JPEG, el archivo final se ha reducido más de 700 veces!

De hecho, esta imagen se puede comprimir mucho más. A continuación se muestran dos imágenes una al lado de la otra: la foto de la derecha fue comprimida a 16 KB, es decir, 57 veces menos que la versión sin comprimir.

Cómo funciona el formato JPEG

Si miras de cerca, verás que estas imágenes no son idénticas. Ambas son imágenes con compresión JPEG, pero la de la derecha tiene un volumen mucho menor. También se ve un poco peor (mira los cuadrados de color de fondo). Por lo tanto, JPEG también se denomina compresión con pérdida; Durante el proceso de compresión, la imagen cambia y pierde algunos detalles.

1. Submuestreo de color

Aquí hay una imagen con solo el primer nivel de compresión aplicado.

Cómo funciona el formato JPEG
(Versión interactiva en el original artículos). Quitar un número destruye todos los colores. Sin embargo, si se eliminan exactamente seis números, tendrá poco o ningún efecto en la imagen.

Ahora los números son un poco más fáciles de descifrar. Esta es casi una simple lista de colores, cada byte cambia exactamente un píxel, pero ya tiene la mitad del tamaño de una imagen sin comprimir (que ocuparía aproximadamente 300 KB en un tamaño tan reducido). ¿Adivina qué?

Puedes ver que estos números no representan los componentes estándar rojo, verde y azul, porque si reemplazamos todos los números con ceros, obtenemos una imagen verde (no blanca).

Cómo funciona el formato JPEG

Esto se debe a que estos bytes representan Y (brillo),

Cómo funciona el formato JPEG

Cb (azul relativo),

Cómo funciona el formato JPEG

y imágenes Cr (enrojecimiento relativo).

Cómo funciona el formato JPEG

¿Por qué no utilizar RGB? Después de todo, así es como funcionan la mayoría de las pantallas modernas. Su monitor puede mostrar cualquier color, incluidos rojo, verde y azul, con diferentes intensidades para cada píxel. El blanco se obtiene encendiendo los tres a máximo brillo y el negro apagándolos.

Cómo funciona el formato JPEG

También es muy similar a cómo funciona el ojo humano. Los receptores de color en nuestros ojos se llaman "conos“, y se dividen en tres tipos, cada uno de los cuales es más sensible a los colores rojo, verde o azul [los conos tipo S son sensibles al azul violeta (S del inglés. Short - espectro de longitud de onda corta), Tipo M: en partes del espectro verde-amarillo (M del inglés. Medium - onda media) y tipo L - en partes del espectro amarillo-rojo (L del inglés. Long - onda larga). La presencia de estos tres tipos de conos (y bastones sensibles en la parte verde esmeralda del espectro) le da a la persona una visión del color. / aprox. traducción]. Palos, el otro tipo de fotorreceptor de nuestros ojos, es capaz de detectar cambios de brillo pero es mucho más sensible al color. Nuestros ojos tienen alrededor de 120 millones de bastones y sólo 6 millones de conos.

Por tanto, nuestros ojos notan mucho mejor los cambios de luminosidad que los cambios de color. Si separas el color del brillo, puedes quitar un poco de color y nadie notará nada. El submuestreo de croma es el proceso de representar los componentes de color de una imagen con una resolución más baja que los componentes de luminancia. En el ejemplo anterior, cada píxel tiene exactamente un componente Y y cada grupo individual de cuatro píxeles tiene exactamente un componente Cb y un componente Cr. Por tanto, la imagen contiene cuatro veces menos información de color que el original.

El espacio de color YCbCr no sólo se utiliza en archivos JPEG. Fue inventado originalmente en 1938 para transmisiones de televisión. No todo el mundo tiene un televisor en color, por lo que separar el color y el brillo permitió que todos obtuvieran la misma señal, y los televisores sin color solo usaban el componente de brillo.

Por lo tanto, eliminar un número del editor destruye por completo todos los colores. Los componentes se almacenan en el formato AAAA Cb Cr (en realidad, no necesariamente en este orden; el orden de almacenamiento se especifica en el encabezado del archivo). Quitar el primer número hará que el primer valor de Cb se perciba como Y, Cr como Cb y, en general, se obtendrá un efecto dominó, cambiando todos los colores de la imagen.

La especificación JPEG no requiere que utilice YCbCr. Pero la mayoría de los archivos lo usan porque ofrece imágenes de mejor calidad después de la reducción de resolución en comparación con RGB. Pero no tienes que creer en mi palabra. Vea usted mismo en la siguiente tabla cómo se vería el submuestreo de cada componente individual tanto en RGB como en YCbCr.

Cómo funciona el formato JPEG
(Versión interactiva en el original artículos).

La eliminación del azul no es tan notoria como la del rojo o el verde. Esto se debe a que de los seis millones de conos que hay en los ojos, aproximadamente el 64 % son sensibles al rojo, el 32 % al verde y el 2 % al azul.

Se ve mejor el submuestreo del componente Y (abajo a la izquierda). Incluso un pequeño cambio se nota.

Convertir una imagen de RGB a YCbCr no reduce el tamaño del archivo, pero facilita la búsqueda de detalles menos visibles que se pueden eliminar. La compresión con pérdidas ocurre en la segunda etapa. Se basa en la idea de presentar los datos en una forma más comprimible.

2. Transformada discreta de coseno y discretización.

Este nivel de compresión, en su mayor parte, define la esencia de JPEG. Después de convertir los colores a YCbCr, los componentes se comprimen individualmente, por lo que de ahora en adelante solo podemos concentrarnos en el componente Y. Y así es como se ven los bytes del componente Y después de aplicar este nivel.

Cómo funciona el formato JPEG
(Versión interactiva en el original artículos). En la versión interactiva, al hacer clic en un píxel, el editor se desplaza hasta la línea que lo representa. Intente eliminar números del final o agregar algunos ceros a un número determinado.

A primera vista parece una compresión muy mala. Hay 100 píxeles en una imagen y se necesitan 000 números para indicar su brillo (componentes Y). ¡Eso es peor que no comprimir nada en absoluto!

Sin embargo, tenga en cuenta que la mayoría de estos números son cero. Además, todos estos ceros al final de las líneas se pueden eliminar sin cambiar la imagen. Quedan alrededor de 26 números, ¡lo que es casi 000 veces menos!

Este nivel contiene el secreto de los patrones de ajedrez. A diferencia de otros efectos que hemos visto, la apariencia de estos patrones no es un problema técnico. Son los pilares de toda la imagen. Cada línea del editor contiene exactamente 64 números, coeficientes de transformada de coseno discreto (DCT) que corresponden a las intensidades de 64 patrones únicos.

Estos patrones se forman basándose en la gráfica del coseno. Así es como se ven algunos de ellos:

Cómo funciona el formato JPEG
8 de 64 probabilidades

A continuación se muestra una imagen que muestra los 64 patrones.

Cómo funciona el formato JPEG
(Versión interactiva en el original artículos).

Estos patrones son de particular importancia ya que forman la base de las imágenes de 8x8. Si no está familiarizado con el álgebra lineal, esto significa que se puede obtener cualquier imagen de 8x8 a partir de estos 64 patrones. DCT es el proceso de dividir imágenes en bloques de 8x8 y convertir cada bloque en una combinación de estos 64 coeficientes.

El hecho de que cualquier imagen pueda estar compuesta por 64 patrones específicos parece mágico. Sin embargo, esto es lo mismo que decir que cualquier lugar de la Tierra se puede describir con dos números: latitud y longitud [que indican los hemisferios / aprox. traducción]. A menudo pensamos que la superficie de la Tierra es bidimensional, por lo que sólo necesitamos dos números. Una imagen de 8x8 tiene 64 dimensiones, por lo que necesitamos 64 números.

Aún no está claro cómo nos ayuda esto en términos de compresión. Si necesitamos 64 números para representar una imagen de 8x8, ¿por qué sería mejor que simplemente almacenar 64 componentes de luminancia? Hacemos esto por la misma razón por la que convertimos tres números RGB en tres números YCbCr: nos permite eliminar detalles sutiles.

Es difícil ver exactamente qué detalles se están eliminando en esta etapa porque JPEG aplica DCT a bloques de 8x8. Sin embargo, nadie nos prohíbe aplicarlo al panorama completo. Así es como se ve la DCT para el componente Y cuando se aplica a la imagen completa:

Cómo funciona el formato JPEG

Se pueden eliminar más de 60 números del final prácticamente sin cambios perceptibles en la foto.

Cómo funciona el formato JPEG

Sin embargo, tenga en cuenta que si ponemos a cero los primeros cinco números, la diferencia será obvia.

Cómo funciona el formato JPEG

Los números al principio representan cambios de baja frecuencia en la imagen y nuestros ojos son los que mejor los captan. Los números hacia el final indican cambios de alta frecuencia que son más difíciles de notar. Para "ver lo que el ojo no puede ver", podemos aislar estos detalles de alta frecuencia poniendo a cero los primeros 5000 números.

Cómo funciona el formato JPEG

Vemos todas las áreas de la imagen donde se produce el mayor cambio de un píxel a otro. Destacan los ojos del gato, sus bigotes, la manta de rizo y las sombras en la esquina inferior izquierda. Puedes ir más allá poniendo a cero los primeros 10 números:

Cómo funciona el formato JPEG

20 000:

Cómo funciona el formato JPEG

40 000:

Cómo funciona el formato JPEG

60 000:

Cómo funciona el formato JPEG

JPEG elimina estos detalles de alta frecuencia durante la etapa de compresión. La conversión de colores a coeficientes DCT no produce pérdidas. Las pérdidas se forman en el paso de muestreo, donde se eliminan valores de alta frecuencia o cercanos a cero. Cuando reduce la calidad de guardado de JPEG, el programa aumenta el umbral para la cantidad de valores que se eliminarán, lo que reduce el tamaño del archivo, pero hace que la imagen esté más pixelada. Entonces la imagen de la primera sección, que era 57 veces más pequeña, se veía así. Cada bloque de 8x8 representaba una cantidad mucho menor de coeficientes DCT en comparación con la versión de mayor calidad.

Puedes hacer algo tan interesante como transmitir imágenes gradualmente. Puede mostrar una imagen borrosa que se vuelve cada vez más detallada a medida que se descargan más coeficientes.

Aquí, sólo por diversión, lo que sucede cuando se utilizan sólo 24 números:

Cómo funciona el formato JPEG

O solo 5000:

Cómo funciona el formato JPEG

¡Muy borroso pero reconocible!

3. Codificación de longitudes de tirada, delta y Huffman

Hasta ahora, todas las etapas de compresión han tenido pérdidas. La última etapa, por el contrario, transcurre sin pérdidas. No elimina información, pero reduce significativamente el tamaño del archivo.

¿Cómo se puede comprimir algo sin descartar información? Imagínese cómo describiríamos un simple rectángulo negro de 700 x 437.

JPEG utiliza 5000 números para esto, pero se pueden lograr resultados mucho mejores. ¿Te imaginas un esquema de codificación que describa dicha imagen en la menor cantidad de bytes posible?

El esquema mínimo que se me ocurrió usa cuatro: tres para el color y un cuarto para la cantidad de píxeles que tiene ese color. La idea de representar valores repetidos de una manera tan comprimida se llama codificación de longitud de ejecución. No tiene pérdidas porque podemos recuperar los datos codificados en su forma original.

El tamaño de un archivo JPEG con un rectángulo negro es mucho mayor que 4 bytes; recuerde que en el nivel DCT, la compresión se aplica a bloques de 8x8 píxeles. Por lo tanto, como mínimo, necesitamos un coeficiente DCT por cada 64 píxeles. Necesitamos uno porque en lugar de almacenar un único coeficiente DCT seguido de 63 ceros, la codificación de longitud de ejecución nos permite almacenar un solo número y denotar "todos los demás son ceros".

La codificación delta es una técnica mediante la cual cada byte contiene una diferencia con respecto a algún valor en lugar de un valor absoluto. Por lo tanto, editar ciertos bytes cambia el color de todos los demás píxeles. Por ejemplo, en lugar de almacenar

12 13 14 14 14 13 13 14

Podríamos comenzar con 12 y luego simplemente escribir cuánto debemos sumar o restar para obtener el siguiente número. Y esta secuencia en codificación delta toma la forma:

12 1 1 0 0 -1 0 1

Los datos convertidos no son más pequeños que los datos originales, pero es más fácil comprimirlos. Aplicar la codificación delta antes de la codificación de longitud de ejecución puede ayudar mucho sin dejar de ser una compresión sin pérdidas.

La codificación delta es una de las pocas técnicas utilizadas fuera de los bloques de 8x8. De los 64 coeficientes DCT, uno es simplemente una función de onda constante (color sólido). Representa el brillo promedio de cada bloque para los componentes de luminancia, o el azul promedio para los componentes Cb, y así sucesivamente. El primer valor de cada bloque DCT se denomina valor DC, y cada valor DC está codificado en delta con respecto a los anteriores. Por lo tanto, cambiar el brillo del primer bloque afectará a todos los bloques.

El último misterio permanece: ¿cómo es que el cambio del número singular arruina por completo todo el panorama? Hasta ahora, los niveles de compresión no tenían tales propiedades. La respuesta está en el encabezado JPEG. Los primeros 500 bytes contienen metadatos sobre la imagen (ancho, alto, etc.) y hasta ahora no hemos trabajado con ellos.

Sin un encabezado, es casi imposible (bueno, muy difícil) decodificar un JPEG. Parecerá que estoy tratando de describirles una imagen y estoy empezando a inventar palabras para transmitir mi impresión. La descripción probablemente será muy concisa, ya que puedo inventar palabras con exactamente el significado que quiero transmitir, pero para todos los demás no tendrán sentido.

Suena tonto, pero así es como sucede. Cada imagen JPEG está comprimida con códigos específicos. El diccionario de códigos se almacena en el encabezado. Esta técnica se llama "código Huffman" y el diccionario se llama tabla de Huffman. En el encabezado, la tabla está marcada con dos bytes: 255 y luego 196. Cada componente de color puede tener su propia tabla.

Los cambios en la tabla afectarán drásticamente cualquier imagen. Un buen ejemplo es cambiar del 15 al 1 en la línea 12.

Cómo funciona el formato JPEG

Esto se debe a que las tablas especifican cómo se deben leer los bits individuales. Hasta ahora sólo hemos trabajado con números binarios en forma decimal. Pero esto nos oculta el hecho de que si desea almacenar el número 1 en un byte, se verá como 00000001, porque cada byte debe tener exactamente ocho bits, incluso si solo se necesita uno de ellos.

Esto es potencialmente una gran pérdida de espacio si tiene muchos números pequeños. El código Huffman es una técnica que nos permite relajar este requisito de que cada número debe ocupar ocho bits. Esto significa que si ve dos bytes:

234 115

Luego, dependiendo de la tabla de Huffman, pueden ser tres números. Para extraerlos, primero debes dividirlos en bits individuales:

11101010 01110011

Luego pasamos a la tabla para entender cómo agruparlos. Por ejemplo, podrían ser los primeros seis bits (111010), o 58 en decimal, seguidos de cinco bits (10011), o 19, y finalmente los últimos cuatro bits (0011), o 3.

Por tanto, es muy difícil entender los bytes en esta etapa de compresión. Los bytes no representan lo que parecen. No entraré en detalles sobre cómo trabajar con la mesa en este artículo, pero materiales sobre este tema en línea suficiente.

Uno de los trucos interesantes que puedes hacer con este conocimiento es separar el encabezado del JPEG y almacenarlo por separado. De hecho, resulta que sólo tú puedes leer el archivo. Facebook hace esto para reducir aún más los archivos.

Lo que más se puede hacer es cambiar bastante la tabla de Huffman. Para otros, parecerá una imagen estropeada. Y sólo tú conocerás la opción mágica para solucionarlo.

En resumen: ¿qué se necesita para decodificar un JPEG? Necesario:

  1. Extraiga la(s) tabla(s) de Huffman del encabezado y decodifique los bits.
  2. Extraiga los coeficientes de transformación de coseno discretos para cada componente de color y luminancia para cada bloque de 8x8 transformando inversamente la codificación de longitud de ejecución y delta.
  3. Combine cosenos según coeficientes para obtener valores de píxeles para cada bloque de 8x8.
  4. Escale los componentes de color si se realizó un submuestreo (esta información se encuentra en el encabezado).
  5. Convierta los valores YCbCr resultantes para cada píxel a RGB.
  6. ¡Trae la imagen a la pantalla!

¡Un trabajo serio por simplemente ver una foto con un gato! Sin embargo, lo que me gusta es que muestra cuán centrada en el ser humano está la tecnología JPEG. Se basa en las características de nuestra percepción, lo que nos permite lograr una compresión mucho mejor que las tecnologías convencionales. Y ahora, al comprender cómo funciona JPEG, podemos imaginar cómo estas tecnologías se pueden transferir a otras áreas. Por ejemplo, la codificación delta en vídeo puede dar como resultado una reducción significativa en el tamaño del archivo, ya que a menudo hay áreas enteras que no cambian de un cuadro a otro (por ejemplo, el fondo).

Código utilizado en el artículo., está abierto y contiene instrucciones para reemplazar las imágenes por las suyas.

Fuente: habr.com

Añadir un comentario