¿Se garantiza que un JPG produzca los mismos píxeles?

Sé que disparar en RAW tiene muchos beneficios, pero por el momento parece que JPG funciona bien para mí. Los tamaños de archivo son mucho más pequeños, y darktable parece funcionar bien con ellos (aunque, curiosamente, parece que en realidad es más rápido con la edición de archivos RAW, pero eso podría ser solo una alucinación).

Por lo que puedo decir, la forma en que funciona darktable es creando un archivo sidecar que contiene las ediciones para realizar en el archivo JPG original, por lo que, en teoría, las ediciones no son destructivas (es decir, no se vuelve a comprimir la imagen a JPG cada vez).

Teniendo en cuenta todo eso, tenía curiosidad: ¿se garantiza que el mismo archivo JPG produzca los mismos píxeles cuando se renderiza cada vez? Por ejemplo, supongamos que tengo un archivo JPG guardado con una calidad del 98 %. Si lo abro con un zoom del 100 %, ¿tendrá los mismos píxeles cuando lo abra en darktable que cuando lo abra en Google Chrome? ¿O cuando lo abres en Photoshop? ¿Qué pasa con los archivos que tienen una compresión más alta, por ejemplo, 50% de calidad?

Algunos codificadores permiten elegir entre punto flotante y entero DCT. ¿Puede alguien que sepa de lo que está hablando (¡no yo en este caso!) abordar si esto podría almacenarse con valores de punto flotante? ¿O es solo un cálculo intermedio?
Habría diferencias entre ellos, serían pequeñas pero definitivamente matemáticamente diferentes.

Respuestas (7)

¿Se garantiza que el mismo archivo JPG produzca los mismos píxeles cuando se renderiza cada vez?

Sí. Es solo una lista de números que representan valores de color (de una manera inteligente para hacerlo pequeño). No hay información "producida" en el proceso de abrir un archivo jpeg que sería diferente entre dos aplicaciones.

¿Qué pasa con los archivos que tienen una compresión más alta, por ejemplo, 50% de calidad?

Entonces los números en la lista serán diferentes. (más ceros) Aparte de eso, no hay diferencia.

Eso es cierto en lo que respecta a la parte de descompresión. Sin embargo, hay una gran advertencia: un código de gestión de color diferente puede producir resultados diferentes al convertir al espacio de color de destino, especialmente si una aplicación especifica compensación de punto negro y otra no. Y eso sin considerar ningún truncamiento del cálculo intermedio que pueda ocurrir o no.
Entonces, con la misma tasa de compresión, un hash md5 de las imágenes generadas debería permanecer igual sin importar cuántas veces ejecutemos el proceso de compresión en la imagen original.

Respuesta corta

No, no se garantiza que la decodificación sea siempre la misma. Sin embargo, se garantiza que las diferencias serán muy, muy pequeñas.

Especificaciones ISO

Las especificaciones de la Organización Internacional de Normalización (ISO) para JPEG tienen las siguientes especificaciones para decodificadores (énfasis mío):

Un decodificador deberá

a) con la precisión adecuada , convertir en datos de imagen reconstruida cualquier dato de imagen comprimida con parámetros dentro del rango soportado por la aplicación, y que cumplan con la sintaxis de formato de intercambio especificada en el Anexo B para los procesos de decodificación incorporados por el decodificador;

b) aceptar y almacenar adecuadamente cualquier dato de especificación de tabla que cumpla con el formato abreviado para la sintaxis de datos de especificación de tabla especificado en el Anexo B para el proceso o procesos de decodificación incorporados por el decodificador;

c) con la precisión adecuada , convertir en datos de imagen reconstruidos cualquier dato de imagen comprimido que cumpla con el formato abreviado para la sintaxis de datos de imagen comprimidos especificado en el Anexo B para el proceso o procesos de decodificación incorporados por el decodificador, siempre que los datos de especificación de tabla requeridos para decodificar los datos de la imagen comprimida se ha instalado previamente en el decodificador.

La precisión adecuada es muy estricta. Cualquier convertidor que siga estas especificaciones debe compararse con un algoritmo de referencia. Para un solo píxel, cada componente solo puede diferir en un bit de la referencia. Además, el error (cuadrado) sobre cada bloque de 8x8 píxeles y sobre toda la imagen debe ser muy bajo.

Pero, ¿por qué sería diferente?

A diferencia de bmp o png, un jpeg no almacena los píxeles sino una descripción de la imagen. Para reconstruir los píxeles individuales se utiliza un algoritmo matemático complejo. Después de cada paso, el algoritmo almacena el resultado en la memoria. Aquí es donde las cosas pueden salir mal: un valor en la memoria tiene una cierta precisión, la precisión de la máquina . Debido a esto, el valor tiene que ser redondeado. Si bien las especificaciones aseguran que se utiliza una precisión mínima, no existe un máximo. Por tanto, el redondeo puede ser diferente para cada implementación. Incluso puede depender del hardware utilizado, ya que algunos procesadores utilizan más bits de precisión de los exigidos. Algunos de los primeros procesadores Pentium incluso lo hacían mal.

Pequeño ejemplo simplificado: calcular 5 * 0,12 mediante sumas repetidas.

Almacenando valores intermedios usando un dígito de precisión, una computadora podría hacer esto: 0.12 + 0.12 = 0.24, almacenar el resultado intermedio como 0.2 (redondeando hacia abajo). Luego calcule 0.2 + 0.12 = 0.32, guárdelo como 0.3 (nuevamente, redondeando hacia abajo). Continúe con este patrón y el resultado será 0,5 en lugar del resultado esperado de 0,6. Si se hubiera utilizado una precisión mayor (dos dígitos, por ejemplo), el resultado habría sido diferente.

Creo que esta es la respuesta correcta. Probé un par de aplicaciones comunes para ver si podía detectar diferencias de 1 bit, pero hasta ahora he fallado.
Descubrí que mi fracaso anterior se debió únicamente a mi inexperiencia con el editor de imágenes que tengo a mano. Una vez que descubrí cómo mejorar adecuadamente las diferencias de imagen, eran obvias. Dejé mi propia respuesta para demostrar.
Genial, en realidad tienes pruebas.
Que exista un estándar ISO no significa que las implementaciones del mundo real lo cumplan comúnmente.

No, no puede depender de que las imágenes JPEG decodificadas sean idénticas bit a bit.

Como ejemplo, intenté ver la imagen en la parte superior de esta página en dos navegadores diferentes: Chrome 53.0.2785.143 e Internet Explorer 11.0.9600.18426. Se ven idénticos, pero puse capturas de pantalla en un editor de imágenes y amplifiqué la diferencia. Puedes ver que no son lo mismo.

Aquí está la imagen original:

Imagen original

Y aquí está la diferencia entre las dos representaciones del navegador, mejoradas:

diferencia mejorada

¿Qué sucede si lo abre en cromo en dos pestañas diferentes? ¿Entonces se le presenta una imagen idéntica?
@WayneWerner Lo intenté hace un momento, y sí, eran idénticos. Como esperaba que fueran. Estoy bastante seguro de que las diferencias se deben a detalles en los algoritmos de decodificación de diferentes programas, como se detalla en otra respuesta.
¿Probó esto también con un PNG, en caso de que Chrome e Internet Explorer estuvieran usando una gestión de color diferente?
@LoganPickup no, no lo hice, pero es una buena idea.

La compresión y los elementos internos de JPEG en sí mismos no influyen en la reproducibilidad del archivo ya comprimido: producirá la misma salida de píxeles en programas que funcionen correctamente dado que

  • el espacio de color de una fotografía coincide con el espacio de color del sistema de gestión del color
  • está viendo la imagen a una escala del 100%, es decir, salida de píxel a píxel al monitor

Si, por ejemplo, el archivo de imagen contiene datos de AdobeRGB, puede generar datos de píxeles diferentes en los sistemas de color sRGB porque se pueden usar diferentes algoritmos para la conversión de AdobeRGB a sRGB y pueden usar una precisión diferente para los cálculos. Es muy probable que Photoshop y Chrome usen diferentes algoritmos para la conversión de color.

Muchos navegadores no están configurados correctamente para fines colorimétricos y es posible que no utilicen el perfil del monitor en absoluto y que muestren la imagen de forma completamente diferente a Photoshop.

Cuando se escala la imagen, la diferencia entre los algoritmos de cambio de tamaño se mostrará de manera similar.


Eso podría ser demasiado complicado, pero probablemente sea algo que le gustaría saber.

La mayoría de los esquemas de codificación JPEG no están destinados a ser exactamente precisos, son 'perceptivamente sin pérdidas'. Dicho principio se aplicará en implementaciones de algoritmos de codificador y decodificador.

Es razonable esperar que en un decodificador se implementen algunas optimizaciones que favorecen el rendimiento sobre la precisión, que la gestión del color no se implemente en absoluto y que la conversión RGB-Y'CrCb no sea idéntica entre los decodificadores.

JPEG está destinado a ser 'lo suficientemente bueno', las diferencias serían sutiles y ese es el resultado que uno debe esperar. El mismo principio se aplicaría independientemente del nivel de compresión aplicado al archivo de origen.

@Aaganrmu es generalmente correcto. No hay garantía de que un archivo JPEG en particular se procesará exactamente de la misma manera cada vez que se abra , incluso con el mismo programa.

En la práctica, a menos que se haya actualizado un programa, abrir el mismo archivo con el mismo programa producirá los mismos resultados.  Muchos programas también usan las mismas bibliotecas de decodificación y producirán los mismos resultados. Sería demasiado esfuerzo para los programadores introducir intencionalmente una variación en el algoritmo JPEG para producir resultados diferentes cada vez que se abre un archivo. Tampoco es lo que los usuarios esperarían o querrían. (Esto ignora los perfiles de color y la corrección, que es un paso aparte después de la decodificación).

La posibilidad de variación proviene de diferentes entradas que potencialmente dan como resultado la misma salida como resultado de las transformaciones, el redondeo y la cuantificación que ocurren como parte del algoritmo JPEG .  Estas operaciones también son la fuente de artefactos JPEG.

variaciones de JPEG

Los decodificadores JPEG knusperli y jpeg2png están diseñados para reducir los artefactos JPEG dentro de las limitaciones permitidas por el algoritmo JPEG.  Producen una salida que debería proporcionar los mismos datos que se ingresaron si se vuelven a cuantificar con la misma configuración. (Si entiendo su funcionamiento correctamente, ignoran las diferencias que pueden introducir los errores de redondeo). Como resultado, tardan más en decodificarse y su salida es diferente (¿mejor?) que la de otros decodificadores.

Aquí hay cultivos al 100% para mostrar la diferencia entre libjpeg(izquierda) y jpeg2png(derecha):

ejemplo jpeg2png

Un píxel es solo un color, un color promedio muestreado de esa pequeña área de píxeles. El color es cómo vemos los detalles. Vemos un cable de alimentación negro que atraviesa una imagen de un cielo azul solo porque el color es diferente. El color es el detalle.

JPG Quality 50 es solo 50, solo un número, NO es 50%.
JPG 100 no es el 100% de nada. 100 es un JPG bastante bueno, pero sigue siendo JPG.

Los artefactos JPG (causados ​​por un factor de calidad más bajo) alteran el color del píxel. El píxel es de un color diferente, y un píxel es solo color, por lo que es un píxel diferente.

La codificación (creación) de JPG suele ser diferente en cada programa. Hay varias opciones, asumidas de manera diferente en diferentes programas. Es poco probable que la Calidad 80 en un programa coincida con la Calidad 80 en otro programa.

Supongo que decodificar (mostrar) JPG es estándar, mostrando lo que se codificó.

JPG es mejor hoy de lo que solía ser, pero todavía hay artefactos de JPG.

Un tipo de artefacto JPG es que JPG intenta hacer que el color en bloques de 8x8 píxeles sea el mismo color si ya eran de un color similar. La calidad JPG baja tiende a mostrar esos bloques de 8x8 píxeles en áreas de color similar (cielos, paredes, etc.).

Otro tipo de artefacto JPG es una borrosidad o un eco de bordes nítidos desplazados un poco del borde original.

Consulte http://www.scantips.com/basics09b.html para ver algunos ejemplos de artefactos JPG.

La baja calidad de JPG puede hacer que el correo electrónico e Internet sean más pequeños y rápidos, pero para nuestras fotografías reales, simplemente no parece haber una buena razón por la que queramos una baja calidad de JPG. :)