¿Cómo puedo saber exactamente qué cambió entre dos imágenes?

Por ejemplo, para una conversación reciente sobre la compresión JPEG , quería comparar píxel por píxel qué cambió entre dos archivos JPEG (uno con nivel de compresión 100 y otro con nivel de compresión 95).

¿Cómo genero buenos mapas visuales de lo que cambió sin una tediosa programación de software personalizada?

No enviar esto como respuesta, ya que probablemente no sea una solución viable para las fotos, pero GitHub (el sitio de un programador) tiene algunas formas interesantes de comparar imágenes: github.com/cameronmcefee/Image-Diff-View-Modes/commit/… Intente hacer clic "2-up", "Swipe", "Piel de cebolla" y "Diferencia".

Respuestas (6)

Photoshop + Capas FTW. (Sí, también puede usar Gimp o cualquier otro software de edición con las mismas funciones).

Comience con su imagen base, en el caso anterior, utilicé la imagen de calidad jpeg 100.

  1. crear una nueva capa encima de ella
  2. pega la segunda imagen en esa capa
  3. establezca el estilo de capa en "diferencia" (vea la flecha rosa izquierda en la primera imagen a continuación)
  4. cree una capa de efecto encima de eso (Capa> Nueva capa de ajuste> Umbral)
  5. establezca el efecto en el umbral (vea la flecha rosa derecha en la primera imagen a continuación)
  6. establecer el valor de umbral en 1

En la imagen resultante, cualquier píxel que sea diferente entre las dos imágenes será blanco. Puede ajustarlo para permitir que las cosas sean "un poco diferentes" alterando el valor del umbral.

Ejemplo que muestra MUCHA diferencia entre jpeg 92 y 100 de Lightroom.comparando jpeg 92 y 100 de LR con capas de Photoshop

Ejemplo que no muestra ninguna diferencia entre 95 y 100.comparando jpeg 95 y 100 de LR con capas de Photoshop

No es solo mostrar un binario "cambiado o no", ¿qué sucede si desea obtener más detalles sobre cuánto cambió, por ejemplo, por canal de color?

  1. reemplace la capa de ajuste de umbral con una capa de ajuste de curvas.
  2. editar la curva
  3. activar mostrar recorte
  4. tome el controlador blanco de entrada debajo de la esquina inferior derecha y arrástrelo hacia la izquierda, tan lejos como pueda
  5. muévase lentamente hacia la derecha hasta que no vea ningún recorte (la imagen de vista previa es toda negra)
  6. desactive el recorte y guarde el cambio de curva

Cuanto más brillantes sean los píxeles resultantes, más diferentes serán en ese color. Sin embargo, la desventaja es que terminas con mucho lodo gris... así que a veces es más fácil limitarlo para ver dónde están las diferencias. Es por eso que construyo ambos y alterno cuál es visible.

vista más descriptiva de la diferencia

Pregunta de Newb, pero ¿cómo hacer el paso 4, "crear una capa de efecto encima de eso"? No puedo encontrarlo en ningún lado. También han pasado 7 años y estoy usando la última versión porque quizás también hayan cambiado el nombre.

Todos los paquetes de procesamiento de imágenes deberían hacer esto fácil. Le mostraré cómo hacerlo en Mathematica, si tiene acceso a este sistema. Mathematica es un lenguaje de programación, pero es realmente fácil hacer este tipo de manipulaciones, así que si tiene acceso a él (por ejemplo, a través de una licencia de sitio universitario), ¡le recomiendo que lo pruebe!

Primero, importa la imagen:

img = Import["http://farm1.staticflickr.com/62/171463865_36ee36f70e.jpg"]

Vuelva a comprimirlo usando compresión JPEG

img2 = ImportString@ExportString[img, "JPEG", "CompressionLevel" -> 0.35]

gráficos matemáticos

Ahora tome la diferencia de los valores de píxel, convirtiéndolos primero en números de coma flotante para garantizar que se conserven los valores negativos.

diff = ImageSubtract[Image[img, "Real"], Image[img2, "Real"]]

gráficos matemáticos

No se ve mucho en la imagen de diferencia (la diferencia es pequeña) y los valores negativos se recortan en negro. Así que cambiemos la escala de todos los valores para llenar todo el rango dinámico (el mínimo se escalará a 0, el máximo a 1):

ImageAdjust[diff]

gráficos matemáticos

ImageDifferenceda la diferencia absoluta de las dos imágenes y no produce números negativos. Esta es la operación que es más probable que encuentre en los paquetes de procesamiento de imágenes, especialmente los de GUI (Photoshop, GIMP).

ImageDifference[img, img2]

gráficos matemáticos

También podemos tomar un solo canal RGB, por ejemplo el rojo, y visualizar las diferencias positivas y negativas usando colores 'opuestos':

ArrayPlot[0.5 + ImageData[First@ColorSeparate[diff, "Red"]], 
 ColorFunction -> "RedGreenSplit", ColorFunctionScaling -> False]

gráficos matemáticos

Aquí está lo mismo, con las diferencias amplificadas 5 veces. Los artefactos JPEG son más reconocibles ahora.

ArrayPlot[0.5 + 5 ImageData[First@ColorSeparate[diff, "Red"]], 
 ColorFunction -> "RedGreenSplit", ColorFunctionScaling -> False]

gráficos matemáticos

La ventaja de usar un lenguaje de programación es que podemos automatizar esto fácilmente y ver cómo cambia la diferencia para los "niveles de compresión" entre 0.1 y 1.0:

Grid@Partition[Table[
   ArrayPlot[
    0.5 + ImageData[
      First@ColorSeparate[
        ImageSubtract[Image[img, "Real"], 
         Image[ImportString@
           ExportString[img, "JPEG", "CompressionLevel" -> c], 
          "Real"]], "Red"]], ColorFunction -> "RedGreenSplit", 
    ColorFunctionScaling -> False],
   {c, 0.1, 1, 0.1}
   ], 5]

gráficos matemáticos

¡Siempre es bueno ver una opción con guión/automatizada! :)

Si usa Photoshop, así es como lo haría:

Coloque los dos jpegs en el mismo archivo psd, en dos capas separadas. Deben superponerse exactamente, ya que sus dimensiones son las mismas. (cuál va en la parte superior no importa).

Establezca el modo de fusión de capas en "Diferencia". Verías un resultado mayormente negro. Dependiendo de la diferencia de calidad entre las dos capas originales, es posible que vea más o menos ruido.

ingrese la descripción de la imagen aquí

La diferencia por sí sola no ayuda mucho cuando te quedas con un gran vacío negro como ese. :)
@cabbey seguro, comparando 100% con 95%, lo más probable es que obtenga un negro sólido. Pero eso es lo que preguntaba tu pregunta, ¿no? En su respuesta de propietario, está cambiando los valores de los originales que se comparan, lo que hace que ya no tengan la configuración de compresión original.
Obtiene un negro prácticamente sólido en casi cualquier comparación, porque las diferencias son muy pequeñas. La capa de umbral/curva después de la diferencia no hace nada en la configuración de compresión, solo ayuda a la visualización de los límites inferiores de esa sopa negra que preparó la diferencia. (No estoy 100% seguro de lo que quisiste decir con eso, así que podría estar dirigiéndome en una dirección diferente allí...)
@cabbey si está solicitando una operación pura de bits de la diferencia entre las 2 imágenes, entonces el modo de fusión "Diferencia" solo le da eso. Cuando ajusta el umbral/la curva, aunque el resultado es más obvio a simple vista, no es una representación precisa de lo que ha cambiado. Cuando haces eso, ya no estás comparando un 100% con un 95%.
Seguro que eres. El nivel de compresión dejó de importar la segunda vez que Photoshop cargó la imagen del disco en sus búferes internos, ahora es una matriz de píxeles sin comprimir en la memoria ... si esos píxeles llegaron allí porque la imagen tenía una mancha cuadrada allí o porque son un artefacto del nivel de compresión no es relevante.
Solo tengo curiosidad, con su método, ¿cómo obtendría una representación precisa de la diferencia entre un 100 % frente a un 70 % y un 100 % frente a un 40 %? Parece que solo estás observando hasta que la diferencia es obvia.
El único paso visual es dónde establecer el punto de salida en la curva, o el corte en el umbral (rara vez uso algo más que 1 allí). Siempre que use el mismo punto para ambas visualizaciones, los resultados de lado a lado podrían compararse significativamente. Ambos están configurados para usar la misma "escala" para la visualización de esa manera.
@Jin, lo que dices tiene sentido: solo se necesita el paso de diferencia para obtener una diferencia de bit por bit, y cualquier otro juego es solo para ayudar a visualizar lo que pueden ser pequeñas diferencias. Después de toda esta discusión anterior, ¿tengo la comprensión correcta?

Puede utilizar las herramientas de línea de comandos de Imagemagick.

composite imagesrc1.jpg imagesrc2.jpg -compose difference diffs.jpg

proporcionará el valor absoluto de las diferencias para cada canal RGB.

  1. Abra una de las imágenes en GIMP o Photoshop.
  2. Agregue la segunda imagen como una nueva capa encima de la primera.
  3. Establezca el modo de fusión de la capa superior en "Diferencia"

En la imagen resultante, las partes negras muestran dónde las imágenes originales son idénticas y cualquier cosa más clara muestra diferencias.

La diferencia por sí sola no ayuda mucho cuando te quedas con un gran vacío negro como ese. :)
Siempre puede ajustar los niveles en la imagen resultante. Cada vez que he usado esta técnica he tenido fotos lo suficientemente diferentes como para poder ver los cambios :)

GitHub tiene algunas herramientas de comparación de imágenes interesantes integradas en la web, como se describe aquí y se demuestra en esta demostración .