Vídeo: ¿Qué pasa si recodificas una imagen en JPEG 800 veces?

Los que tengan edad para saber qué era una radio de dos pletinas valorarán la diferencia entre una copia analógica y una digital: una copia analógica se va deformando con cada copia (por el inevitable ruido) hasta llegar a ser inservible.

¿Pasará lo mismo con las imágenes digitales codificadas en formato JPEG? Veremos que, sorprendentemente, ¡a veces sí y a veces no!



¿Qué es el formato JPEG?
Una imagen digital, para un ordenador, no es más que una ristra rectangular de píxeles. El color de cada píxel se debe representar con números enteros y como sabrás se muestran por separado los colores rojo, verde y azul o RGB por sus siglas en inglés. Normalmente se usa un rango de números desde 0 hasta 255 para cada uno de estos colores por conveniencia, ya que así cada píxel ocupa 24bits (o sea 3 bytes exactos). En esto consistiría una imagen en bruto, o raw, y aunque sea la forma en que se muestra por pantalla ocupa una barbaridad de memoria y se tardaría mucho en enviar imágenes por Internet. Por eso se inventaron muchas formas de comprimirlas y que no ocupasen tanto.
Uno de esos formatos es el JPEG. Lo primero que se hace en él es transformar de RGB a otro espacio de color (el YCbCr), de forma que se le pueda dar más importancia a la intensidad o brillo (Y) que a las componentes de color (Cb, Cr). Esto se hace así porque el ojo humano es menos sensible a colores que al brillo, por lo que JPEG dará prioridad a este último.
Después, se realiza lo que se conoce como “compresión con pérdidas”: usando una compleja teoría matemática, la transformada del coseno discreta (DCT), se analizan las componentes de frecuencia de la imagen en cada bloque de 8×8 píxeles. La siguiente imagen te ayudará a entender qué quiere decir esto: cada bloque de 8×8 píxeles se aproxima por la suma ponderada de varios de estos bloques patrón:
Funciones base de la DCT. Cada bloque de 8×8 píxeles separado por líneas rojas es una función base. (Créditos)
En teoría, sumando infinitos cuadritos de esos podríamos obtener cualquier imagen, da igual lo compleja que sea. A los que conozcan la teoría de transformada de Fourier todo esto les sonará mucho (y sería lógico porque se trata de exactamente lo mismo pero con otras funciones bases).
Pero si queríamos comprimir una imagen y necesitamos infinitas sumas, las cuentas no nos cuadran, ¿verdad?. En realidad lo que se hace es, en función de un importante parámetro que se llama calidad del JPEG (definido entre 0 y 100), quedarnos sólo con unos pocos de esos cuadritos elementales (las componentes principales). Para visualizarlo mejor, haciendo la equivalencia con una señal unidimensional en vez de una imagen (quizás más difícil de ver), sería aproximar un tren de pulsos perfectamente rectangular por esto:
Si de un pulso rectangular sólo te quedas con las primeras componentes frecuenciales te queda algo así.  (Créditos)
En resumen: la calidad, ese número de 0 a 100 que a veces nos sale a la hora de guardar un fichero JPEG, indica con cuántas componentes frecuenciales de la DCT queremos quedarnos y cuantas descartar. Eso sí, ni siquiera para un valor máximo de 100 se guardarán todas las componentes, por lo que JPEG es un formato que siempre presenta pérdidas; eso sí, casi imperceptibles a simple vista.
Experimento 1: Con una fotografía
Vamos a probar qué pasaría si tomamos una foto, como ésta de un muñeco de nieve (¡no, no es de Málaga!):

y la grabamos a JPEG, la cargamos y la volvemos a guardar a JPEG, una y otra vez. Y todo eso, a distintos niveles de calidad.

Obviamente, nadie debería hacer eso nunca: si quieres hacer una copia digital de una imagen ¡lo lógico es copiar directamente el fichero JPEG original y no recodificarlo de nuevo!. Pero aún así, tenía curiosidad por esta serie de experimentos, así que vamos a ver los resultados.

Para este primer caso de una fotografía, el resultado es sorprendente: para casi todos los niveles de calidad, en como mucho 20 ciclos de re-codificación se llega a un punto de equilibrio del que ya la imagen no empeora.

Observando detenidamente estas dos ampliaciones, para el peor caso que he probado (calidad Q=50), apenas se nota el empeoramiento:

 

Para medir el error introducido con cada ciclo de re-codificación, he calculado el error cuadrático medio (RMS) entre las imágenes recodificadas y la original para cada calidad Q.
Y éste es el resultado:

Curiosamente, la mejor calidad (Q=100) no es la que menos error mete tras más de 5 recodificaciones, aunque evidentemente en la primera iteración se cumple estrictamente que a mayor Q, menor error.
En conclusión: para fotos reales, JPEG se porta muy bien, incluso tras varias re-codificaciones.
Experimento 2: Con una imagen sintética
Probamos ahora con una imagen sintética, que les pone las cosas más difíciles a JPEG al existir muchas transiciones abruptas de colores y bordes muy nítidos; cosas que en fotos reales casi nunca se dan.

En este caso, incluso para la máxima calidad (Q=100) el color se va perdiendo rápidamente, y algunos bordes se van diluyendo:

Repitiendo la gráfica de antes, vemos que para las primeras re-codificaciones se cumple que a mayor calidad menor error, como cabría esperar:

Pero a largo plazo, cuando se repiten docenas de ciclos, el error continúa incrementándose más y más, llevándose la palma del mayor error… ¡¡la codificación a máxima calidad de Q=100!!

Dejo a los lectores que piensen por qué precisamente a mayor calidad (Q), mayor error con cada recodificación ;-)

¿Qué lecciones aprendemos de esto?

  • Para codificar imágenes sintéticas, ¡evita JPEG!. Usa algún otro formato sin pérdidas, como GIF o PNG.
  • Y en cualquier caso, no codifiques en JPEG una imagen ya decodificada, como por ejemplo una captura de pantalla, ya que el error no parará de aumentar.
Experimento 3: Con una imagen sintética en movimiento
Y ya para poner las cosas extremadamente difícil a JPEG, he repetido el mismo experimento pero ahora desplazando la imagen 1 píxel hacia la derecha en cada re-codificación. Veamos el vídeo (recomiendo poner el vídeo a la máxima resolución):

¡Eso son pérdidas, sí señor!

Por cosas como ésta es por lo que en algoritmos de compresión de vídeo se incluye un keyframe cada X imágenes de vídeo.

Termino con una pregunta para reflexionar: ¿a qué creéis que se debe que en imágenes estáticas se llegue a un equilibrio tras unas docenas de re-codificaciones, pero eso no ocurra con el vídeo?

Espero vuestras ideas en los comentarios ;-)

Share

Etiquetado con:
Publicado en: Curiosidades, Programación
7 comentarios sobre “Vídeo: ¿Qué pasa si recodificas una imagen en JPEG 800 veces?
  1. kaoD dice:

    Por decir algo, lo de que a mayor Q degenere más creo que es porque cuanto más “acotes” la calidad antes llega al punto de equilibrio en el que se queda sólo con patrones que cuadran con las funciones base, mientras que con la calidad más alta siempre intenta afinar un poco más añadiendo componentes (que no siempre serán exactos y por tanto en cada “pasada” hará una elección diferente.) Si degeneras muy rápido, llegas antes a un punto de auto-equilibrio y por tanto degeneras menos a la larga.

    Esto me lleva a pensar que en una imagen no-sintética no degenera igual porque la imagen original contiene más patrones de las funciones base y se expresan antes con menos componentes (y por tanto afina más la calidad al 100% al no serle tan fácil degenerar, cuadrando antes.)

  2. ZuperTruko dice:

    Termino con una pregunta para reflexionar: ¿a qué creéis que se debe que en imágenes estáticas se llegue a un equilibrio tras unas docenas de re-codificaciones, pero eso no ocurra con el vídeo?

    Yo creo que es porque el formato JPEG cuantiza los números. Es decir, cuando se miden los cuadraditos esos (los de la DCT) tienes algo así (son frecuencias en dos dimensiones, bidimensionales):

    1-1 —> 55.35
    1-2 —> 12.26
    1-3 —> 90.96
    2-1 —> 81.35
    2-2 —> 65.67
    2-3 —> 73.18

    Lo que hace JPEG es dividirlos entre unos números (números diferentes para cada cuadrado y para cada nivel de calidad) y redondearles luego a números enteros.

    Pues bien, imaginemos el primero (55.35), si se divide entre 5 da casi 11 (habría algún que otro decimalillo), con lo que para guardar en el fichero se escoge ese número, un 11 (entero, sin decimales).

    La siguiente vez que se abra el fichero, se descodifica esa frecuencia zona de la imagen (de 8×8 píxeles) se lee un 11 entero y se dibuja en la imagen como si fuera 11 entero. Luego habría que sumar las otras frecuencias y quedaria la imagen casi original.

    Luego, cuando vuelves a guardar, vuelves a sacar el valor de la DCT para cada frecuencia… ¿Y que ocurre? Pues eso, si antes calculaste una zona de la imagen usando varias frecuencias (una de ellas 55 que sale de 5×11), vuelves a calcular y te saldrán esos valores de antes (con nuestro querido 11 que saldría de dividir 55 entre 5), que coinciden en su mayoría con los usados antes de guardar.

    ¿Y porqué la calidad 100 degrada más la imagen a la larga? Yo no se bien, pero creo que es porque el redondeamiento a penas se produce, por lo que es más fácil que ese 55.35 (por ejemplo) se termine guardando como 55, pero como se suman otras frecuencias y luego se redondea todo a 8 bits (256 valores), es posible que cuando se vuelva a aplicar una DCT en vez de quedarte 55, te quede un número muy próximo, por ejemplo, un 54 o un 56, y en la siguiente vuelva pasar lo mismo, hasta que se estabiliza en algún valor.

    Como detalle, el formato JPEG permite “seleccionar” el nivel de detalle del color. Hay una opción que permite dividir la resolución a la mitad (muchos programas la aplican por defecto, sin avisar y sin permitir cambiarlo), lo que puede degradar los colores (sobretodo en imágenes sintéticas). Existen opciones intermedias, dividiendo sólo la resolución en horizontal o en vertical. Yo en general suelo desactivar esta opción, porque es muy agresiva con los pequeños detalles coloridos de las fotos, como unas florecillas o algún semáforo en la lejanía que ocupa poco más de un píxel.

    Otro detalle: existen programas que permiten guardar con el mismo factor de calidad que la imagen original, reduciendo las pérdidas y el tamaño del fichero. Otros van más allá, y recomprimen sólo los bloques que han sido modificados. Y luego están los programas que permiten cortar ficheros JPEG recortando los bloques DCT 8×8 sin descodificarlos, o permiten girar la foto sin pérdidas, siempre y cuando la foto tenga un tamaño múltiplo de 8.

  3. Labuiga dice:

    Yo me invento una respuesta, y si cuela cuela (y sinó me la pela):
    Supuestamente a mayor Q mayor número de armónicos intentará la transformada de fourier conservar.
    Pero con una menor Q la señal visual aun de peor calidad para nuestros ojos será mas nítida a nivel de tratarla matemáticamente. (menos armónicos, menos errores por el limite de representación de 32-64 bits decimales, etc…)

    Y teniendo en cuenta que las operaciones sobre imagenes son operaciones matriciales, habiendo estudiado un poco de teoría de errores aunque ese pequeño error en las primeras iteraciones nos haga el efecto de que la imagen tiene mas calidad en realidad el error acumulado de tener que tratar mas armónicos con un espacio decimal limitado es peor.

    ¿van por ahí los tiros? jajajajaja. bueno, seguiré atento por si pones la verdadera solución y no mi paja mental XD

  4. ZuperTruko dice:

    Añado un detalle: la imagen sintética perdió color por la reducción de resolución del color, no por la cuantización (redondeo) de los valores las frecuencias.

    Sería interesante repetir el experimento desactivando la reducción de resolución (submuestreo) del color.

    Me acuerdo de este fichero:
    http://es.wikipedia.org/wiki/Archivo:Submuestreo_subsampling_zamora_4img.JPG
    Ahí puedes ver el efecto del submuestreo a lo bestia. Fíjate en la ropa de la gente, en el cartel de Caja España o en el árbol.

    Además, la reducción de resolución tiene un efecto de difuminado que no se recupera, y sólo aumenta pasada tras pasada. Es posible que un nivel de calidad bajo JPEG permita “forzar” una recuperación de calidad. Digamos que la difuminación del color modificaría un poco las frecuencias esas, pero al volver a guardar y tener que cuantificar, los valores de las frecuencias vuelven a coincidir con los de antes. En el caso de la calidad 100, es posible que no se produzca ese efecto, y por eso se vaya almacenando la difuminación del color.

  5. javiermm dice:

    Es que se vuelve a recomprimir la imagen cada vez, entiendo que es por eso…

  6. Andres.58 dice:

    HOla, entré por casualidad a tu blog, por lo que se vé es interesante. Te comento que desde hace tiempo me hago una pregunta… por qué será que al comprimir una imagen en JPG, se vé más afectada la calidad de los tonos rojos, en relación a los demás? te pregunto ésto porque al subir una imagen diseñada por mí, a un grupo de Facebook, el resultado de al comressión que hace, es un ruido espantoso en los tonos rojos saturados de mi imagen. A que se deberá? te mando un link para que lo chequees … gracias, muy bueno tu blog…

    http://www.facebook.com/groups/65200342754/10150706023622755/?notif_t=like

    • Hola Andrés,

      Pues depende de la calidad con la que se guarde el JPEG: si tu programa te deja, sube la calidad a un 90 o un 90 y pico y debería verse cada vez mejor.

      Si tu programa de edición no te da esa opción, guardalo a .png o .bmp (que ocupará mucho más) y luego instalas por ejemplo GIMP (SW gratuito) que sí te deja convertir a JPEG controlando la calidad.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Recibir por correo electrónico:

Varios

Naukas   Mapping Ignorance