"Diff" un'immagine usando ImageMagick


178

Come posso ottenere la differenza tra due immagini? Ho l'immagine originale. Qualcuno ha scritto su un duplicato esatto dell'immagine originale. Ora, devo confrontare l'originale con l'immagine scritta ed estrarre solo la scrittura in formato immagine.

Esempio: ho una foto di una casa. Qualcuno ne prese una copia e scrisse "Ciao!" sulla copia. Voglio in qualche modo confrontare le due immagini, rimuovere la casa ed essere lasciato con un'immagine delle parole "Ciao!".

Questo è possibile con ImageMagick? So che ci sono modi per ottenere la differenza statistica tra le immagini, ma non è quello che sto cercando.


8
Prova questa sezione della guida all'uso di ImageMagick!
Benoit,

1
So che questa domanda riguarda ImageMagick, ma dovevo solo includere un link a Resemble.js per il ricercatore "causale" che potrebbe essere alla ricerca di una soluzione agnostica.
brichins,

Qualcuno sa di uno strumento che confronterà 2 immagini sottraendo i pixel della seconda immagine, dalla prima? Preferirei non scrivere il mio.
MarcusJ,

Imagemagick 7 ha l'hash percettivo, una tecnica che utilizza momenti di immagine invarianti. è bello nel senso che ha lo stesso hash anche dopo rotazione, distorsione a barilotto, ridimensionamento, variazione gamma, introduzione del rumore, filigrana ...
v.oddou

1
@ v.oddou, grazie. Ho letto documenti e fatto qualche altro test. Sembra funzionare male con disegni al tratto che sono scarsamente popolati e densità di pixel estremamente bassa. Sembra che la densità dei pixel sia la chiave in PHASH per identificare la somiglianza.
BReddy

Risposte:


320

I miei preferiti sono questi due:

 compare image1 image2 -compose src diff.png
 compare image1 image2 -compose src diff.pdf

L'unica differenza tra i 2 comandi sopra: il primo mostra la differenza visiva tra le due immagini come file PNG, il secondo come PDF.

Il file diff risultante visualizza tutti i pixel che sono diversi in colore rosso. Quelli che rimangono invariati appaiono bianchi.

Breve e dolce

Nota, le tue immagini non devono necessariamente essere dello stesso tipo. Puoi anche mescolare JPEG, TIFF, PNG - a una condizione: le immagini devono avere le stesse dimensioni (dimensione dell'immagine in pixel). Il formato di output è determinato dall'estensione del nome file di output.

Se per qualche motivo hai bisogno di una risoluzione superiore a quella predefinita (72 dpi), aggiungi semplicemente un -densityparametro appropriato :

 compare -density 300 image1 image2 -compose src diff.jpeg

Esempi illustrati

Ecco alcune illustrazioni dei risultati per le variazioni del comando sopra. Nota: i due file confrontati erano persino file PDF , quindi funziona anche con questi (purché siano 1-cercapersone)!


Sinistra: immagine con testo       Centro: Immagine originale       Destra: Differenze (= testo) in pixel rossi. Solo pixel con differenza di rosso;  i pixel identici sono bianchi

compare \
        porsche-with-scratch.pdf  porsche-original.pdf \
       -compose src \
        diff-compose-default.pdf

Questo è lo stesso comando che ho suggerito in precedenza.


A sinistra: immagine con Centro testo       : immagine originale       Destra: differenze nei pixel "verde mare". Solo pixel di differenza Seagreen;  i pixel identici sono bianchi

compare \
        porsche-with-scratch.pdf  porsche-original.pdf \
       -compose src \
       -highlight-color seagreen \
        diff-compose-default.pdf

Questo comando aggiunge un parametro per rendere i pixel della differenza "verde mare" invece del rosso predefinito.


A sinistra: immagine con centro testo       : immagine originale       Destra: diff blu (ma con alcuni sfondi di contesto) Solo pixel con differenza blu;  prima delle immagini confrontate come sfondo illuminatol

compare \
        porsche-with-scratch.pdf  porsche-original.pdf \
       -highlight-color blue \
        diff-compose-default.pdf

Questo comando rimuove la -compose srcparte: il risultato è il comportamento predefinito di comparecui mantiene come sfondo alleggerito la prima delle 2 immagini diffuse. (Questa volta con il parametro aggiunto per far apparire i pixel diff in blu.)


Non riesco a capire da dove provenga questo cli di confronto? Fa parte di imagebrick? disponibile su windows?
Krishnom

2
@Krishnom: Non esiste "imagebrick". Vuoi dire ImageMagick?
Kurt Pfeifle,

2
@Krishnom: la domanda esplicitamente posta su una soluzione ImageMagick. Parte della suite di software v6.x di ImageMagick aveva uno strumento CLI separato chiamato 'compare'. Per v7.x di ImageMagick dovresti 'magick compare'invece eseguire .
Kurt Pfeifle,

Colpa mia. Grazie per averlo corretto (imagebrick -> imageMagick). Ci proverò. Sto anche cercando uno strumento per confrontare immagini di massa. Grazie ancora per l'aiuto
Krishnom

@Krishnom: non so cosa sia una "immagine in blocco". Ma scommetto ancora che la suite di strumenti ImageMagick può fare quello che vuoi.
Kurt Pfeifle,

53

Mentre comparefa un buon lavoro per molte applicazioni, ho scoperto che a volte preferisco un approccio diverso, in particolare quando si confrontano immagini che sono per lo più in scala di grigi:

convert '(' file1.png -flatten -grayscale Rec709Luminance ')' \
        '(' file2.png -flatten -grayscale Rec709Luminance ')' \
        '(' -clone 0-1 -compose darken -composite ')' \
        -channel RGB -combine diff.png

L'idea è la seguente: converti entrambi file1.pnge file2.pngin scala di grigi. Quindi ritaglia il primo come canale rosso dell'immagine risultante, il secondo come canale verde. Il canale blu è formato da questi due usando l' darkenoperatore compose, che essenzialmente significa prendere il minimo.

Quindi le cose bianche in entrambe le immagini rimangono bianche. Le cose che sono nere in entrambe le immagini rimangono nere. Le cose bianche nella prima immagine ma nere nella seconda diventano rosse, e le cose bianche nella seconda ma nere nella prima diventano verdi.

Il risultato ti dà un'immagine ben codificata in cui puoi facilmente associare il verde al primo input e il rosso al secondo. Ecco un esempio in cui sto usando questo per confrontare l'output di LaTeX con quello di KaTeX (prima di correggere alcuni bug per renderlo migliore):

inserisci qui la descrizione dell'immagine

È possibile combinare gli approcci, usando compareper vedere dove qualcosa è cambiato e quindi usando quanto sopra per vedere più in dettaglio come è cambiato.


2
Bello! Avevo bisogno di un po 'di interazione, quindi ho replicato il tuo metodo in Gimp. Per riferimento: 1) caricare immagini come livelli, 2) Colore -> Desaturare entrambi i livelli, 3) rimuovere i canali alfa da entrambi i livelli nella scheda Livelli, 4) selezionare i canali G + B su un livello, selezionare tutto e cancellare i canali con il colore nero, lo stesso con i canali R + B sul secondo livello, 4) imposta la modalità Schermo per il livello superiore nella scheda Livelli.
Matěj Šmíd,

1
@Palmstrom: grazie! Inizialmente ho fatto questi confronti di immagini usando Gimp me stesso, ma l'ho fatto usando la modalità di livello "estrazione del grano" direttamente sulle immagini di input, quindi le aree comuni sarebbero diventate grigie, mentre il diff sarebbe nero in una direzione e bianco nell'altra . Più difficile da leggere, ma più veloce da generare e può contenere informazioni sul colore. Immagino che abbinerai il mio comando ancora più da vicino se usassi “solo oscuramento” invece di “schermo”, e colora i canali inutilizzati bianchi anziché neri.
MvG,

1
Alcuni input PDF generano un'immagine invertita dopo la conversione in scala di grigi per qualche motivo. Usando -colorspace grayinvece di -grayscale Rec709Luminancerisolverlo, ma questo incasina la composizione. Aggiungi -respect-parenthesescome prima opzione per convertoccupartene.
Brecht Machiels,

Ecco uno script per diffondere visivamente due PDF pagina per pagina usando questo metodo: gist.github.com/brechtm/891de9f72516c1b2cbc1 . Produce un JPG per ogni pagina dei PDF in una pdfdiffdirectory e stampa inoltre i numeri delle pagine che differiscono tra i due PDF.
Brecht Machiels,

1
In ImageMagick v6.7.7-10 sembra che -grayscalenon sia supportato, ho dovuto usare -colorspace graycome suggerito da @BrechtMachiels
austinmarton,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.