"Différer" une image avec ImageMagick

178

Comment puis-je faire la différence entre deux images? J'ai l'image originale. Quelqu'un a écrit sur une copie exacte de l'image originale. Maintenant, je dois comparer l'original à l'écrit sur l'image et extraire uniquement l'écriture au format image.

Exemple: j'ai une photo d'une maison. Quelqu'un a pris une copie et a écrit «Bonjour!» sur la copie. Je veux en quelque sorte comparer les deux images, supprimer la maison et me retrouver avec une image des mots «Bonjour!».

Est-ce possible avec ImageMagick? Je sais qu'il existe des moyens d'obtenir la différence statistique entre les images, mais ce n'est pas ce que je recherche.

Justin Noel
la source
8
Essayez cette section du guide d'utilisation d'ImageMagick!
Benoit
1
Je sais que cette question concerne ImageMagick, mais je devais juste inclure un lien vers Resemble.js pour le chercheur "causal" qui pourrait être à la recherche d'une solution agnostique.
brichins
Est-ce que quelqu'un connaît un outil qui comparera 2 images en soustrayant les pixels de la deuxième image, de la première? Je préfère ne pas écrire le mien.
MarcusJ
Imagemagick 7 utilise le hachage perceptif, une technique utilisant des moments d'image invariants. c'est sympa dans le sens où il hache la même chose même après rotation, distorsion en barillet, redimensionnement, changement de gamma, introduction de bruit, tatouage ...
v.oddou
1
@ v.oddou, merci. J'ai lu des documents et fait quelques tests supplémentaires. Il semble mal fonctionner avec les dessins au trait qui sont très peu peuplés et dont la densité de pixels est extrêmement faible. On dirait que la densité de pixels est la clé de PHASH pour identifier la similitude.
BReddy

Réponses:

320

Mes propres favoris sont ces deux:

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

La seule différence entre les 2 commandes ci-dessus: la première montre la différence visuelle entre les deux images sous forme de fichier PNG, la seconde sous forme de PDF.

Le fichier diff résultant affiche tous les pixels de couleur rouge différente. Celles qui restent inchangées apparaissent en blanc.

Court et doux.

Notez que vos images ne doivent pas nécessairement être du même type. Vous pouvez même mélanger JPEG, TIFF, PNG - sous une condition: les images doivent être de la même taille (dimension de l'image en pixels). Le format de sortie est déterminé par l'extension du nom de fichier de sortie.

Si, pour une raison quelconque, vous avez besoin d'une résolution plus élevée que la résolution par défaut (72 dpi), ajoutez simplement un -densityparamètre approprié :

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

Exemples illustrés

Voici quelques illustrations des résultats pour les variations de la commande ci-dessus. Remarque: les deux fichiers comparés étaient même des fichiers PDF , donc cela fonctionne aussi avec ceux-ci (du moment qu'il s'agit d'une page)!


Gauche: Image avec texte       Centre: Image originale       Droite: Différences (= texte) en pixels rouges. Pixels de différence rouges uniquement;  les pixels identiques sont blancs

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

C'est la même commande que j'ai suggérée plus haut.


Gauche: Image avec texte       Centre: Image d'origine       Droite: Différences en pixels «vert de mer». Pixels de différence Seagreen uniquement;  les pixels identiques sont blancs

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

Cette commande ajoute un paramètre pour rendre les pixels de différence 'seagreen' au lieu du rouge par défaut.


Gauche: Image avec texte       Centre: Image originale       Droite: Diffs bleus (mais avec un arrière-plan contextuel) Pixels de différence bleue uniquement;  première des images comparées en arrière-plan éclairél

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

Cette commande supprime la -compose srcpartie - le résultat est le comportement par défaut comparequi conserve comme arrière-plan éclairé la première des 2 images différentes. (Cette fois, avec un paramètre ajouté pour faire apparaître les pixels de différence en bleu.)

Kurt Pfeifle
la source
Je ne suis pas en mesure de comprendre d'où vient cette comparaison cli Fait-il partie de l'imagebrick? disponible sur windows?
Krishnom
2
@Krishnom: "Imagebrick" n'existe pas. Voulez-vous dire ImageMagick?
Kurt Pfeifle
2
@Krishnom: La question posée explicitement sur une solution ImageMagick. Une partie de la suite logicielle v6.x d'ImageMagick avait un outil CLI distinct appelé 'compare'. Pour la v7.x d'ImageMagick, vous devriez 'magick compare'plutôt l' exécuter .
Kurt Pfeifle
Ma faute. Merci d'avoir corrigé cela (imagebrick -> imageMagick). Je vais essayer. Je recherche également un outil pour comparer des images en vrac. Merci encore pour l'aide
Krishnom
@Krishnom: Je ne sais pas ce qu'est une "image en masse". Mais je parie toujours que la suite d'outils ImageMagick peut faire ce que vous voulez.
Kurt Pfeifle
53

Bien que cela comparefasse du bon travail pour de nombreuses applications, j'ai trouvé que parfois je préfère une approche différente, en particulier lorsque je compare des images qui sont principalement en niveaux de gris:

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

L'idée est la suivante: convertir les deux file1.pnget file2.pngen niveaux de gris. Puis traitez le premier comme le canal rouge de l'image résultante, le second comme le canal vert. Le canal bleu est formé à partir de ces deux à l'aide de l' darkenopérateur de composition, ce qui signifie essentiellement prendre le minimum.

Ainsi, les éléments blancs sur les deux images restent blancs. Les éléments noirs sur les deux images restent noirs. Les choses qui sont blanches dans la première image mais noires dans la seconde deviennent rouges, et les choses qui sont blanches dans la seconde mais noires dans la première deviennent vertes.

Le résultat vous donne une image joliment codée en couleur où vous pouvez facilement associer le vert à la première entrée et le rouge à la seconde. Voici un exemple où j'utilise ceci pour comparer la sortie de LaTeX avec celle de KaTeX (avant de corriger un bug pour améliorer cela):

entrez la description de l'image ici

Vous pouvez combiner les approches, en utilisant comparepour voir quelque chose a changé, puis en utilisant ce qui précède pour voir plus en détail comment cela a changé.

MvG
la source
2
Agréable! J'avais besoin d'interaction alors j'ai répliqué votre méthode dans Gimp. Pour référence: 1) charger des images en tant que calques, 2) Couleur -> Désaturer les deux calques, 3) supprimer les canaux alpha des deux calques dans l'onglet Calques, 4) sélectionner les canaux G + B sur un calque, tout sélectionner et effacer les canaux avec la couleur noire, la même chose avec les canaux R + B sur la deuxième couche, 4) définir le mode d'écran pour la couche supérieure dans l'onglet Calques.
Matěj Šmíd
1
@Palmstrom: Merci! J'ai fait ces comparaisons d'images à l'origine avec Gimp moi-même, mais je l'ai fait en utilisant le mode de calque «extrait de grain» directement sur les images d'entrée, de sorte que les zones communes deviendraient grises, tandis que le diff serait noir dans un sens et blanc dans l'autre . Plus difficile à lire, mais plus rapide à générer, et il peut contenir des informations de couleur. Je suppose que vous correspondriez encore plus étroitement à ma commande si vous utilisiez «assombrir uniquement» au lieu de «écran», et coloriez les canaux inutilisés en blanc au lieu de noir.
MvG
1
Certaines entrées PDF entraînent une image inversée après la conversion en niveaux de gris pour une raison quelconque. Utiliser -colorspace grayau lieu de -grayscale Rec709Luminancecorriger cela, mais cela gâche la composition. Ajoutez -respect-parenthesescomme première option convertpour prendre soin de cela.
Brecht Machiels
Voici un script pour comparer visuellement deux PDF page par page en utilisant cette méthode: gist.github.com/brechtm/891de9f72516c1b2cbc1 . Il génère un JPG pour chaque page des PDF dans un pdfdiffrépertoire et imprime en outre les numéros des pages qui diffèrent entre les deux PDF.
Brecht Machiels
1
Dans ImageMagick v6.7.7-10, il semble qu'il ne -grayscalesoit pas pris en charge, j'ai dû utiliser -colorspace graycomme @BrechtMachiels l'a suggéré
austinmarton