103 votes

Comment puis-je mesurer la similarité entre deux images ?

Je voudrais comparer une capture d'écran d'une application (il peut s'agir d'une page Web) avec une capture d'écran réalisée précédemment afin de déterminer si l'application s'affiche correctement. Je ne veux pas d'une comparaison exacte, car l'aspect pourrait être légèrement différent (dans le cas d'une application Web, selon le navigateur, un élément pourrait se trouver à un endroit légèrement différent). Cela devrait donner une idée de la similarité des captures d'écran.

Existe-t-il une bibliothèque / un outil qui fait déjà cela ? Comment l'implémenteriez-vous ?

1 votes

Il y a quelques bonnes réponses dans cette autre question similaire : stackoverflow.com/questions/75891/

1 votes

1 votes

Il est temps de mettre à jour les réponses à la lumière des récentes avancées dans le domaine de l'apprentissage automatique et plus particulièrement du "Deep Learning".

77voto

Lasse V. Karlsen Points 148037

Cela dépend entièrement de l'intelligence que vous souhaitez donner à l'algorithme.

Par exemple, voici quelques questions :

  • Images recadrées par rapport à une image non recadrée
  • images avec un texte ajouté par rapport à une autre sans
  • images miroirs

Le plus facile et le plus simple algorithme J'ai vu que pour cela, il suffit de faire les étapes suivantes pour chaque image :

  1. réduisez l'échelle à quelque chose de petit, comme 64x64 ou 32x32, ne tenez pas compte du rapport d'aspect, utilisez un algorithme de combinaison d'échelle au lieu du pixel le plus proche.
  2. mettre à l'échelle les gammes de couleurs de façon à ce que la plus sombre soit noire et la plus claire soit blanche.
  3. faites pivoter et retournez l'image de façon à ce que la couleur la plus claire soit en haut à gauche, puis en haut à droite, puis en bas à gauche (dans la mesure du possible, bien sûr).

Editar A algorithme de mise à l'échelle combinée est une fonction qui, lors de la mise à l'échelle de 10 pixels en un seul, utilise la couleur de ces 10 pixels et les combine en un seul. Cela peut être fait avec des algorithmes comme le calcul de la moyenne, la valeur moyenne ou des algorithmes plus complexes comme les splines bicubiques.

Calculez ensuite la distance moyenne, pixel par pixel, entre les deux images.

Pour rechercher une correspondance possible dans une base de données, stockez les couleurs des pixels sous forme de colonnes individuelles dans la base de données, indexez un certain nombre d'entre elles (mais pas toutes, à moins que vous n'utilisiez une très petite image) et effectuez une requête qui utilise une plage pour chaque valeur de pixel, c'est-à-dire toutes les images où le pixel de la petite image se situe entre -5 et +5 de l'image que vous voulez rechercher.

Cette méthode est facile à mettre en œuvre et assez rapide à exécuter, mais elle ne permet pas de gérer la plupart des différences avancées. Pour cela, vous avez besoin d'algorithmes beaucoup plus avancés.

14 votes

Qu'est-ce qu'un "algorithme de combinaison d'échelles" ?

0 votes

L'algorithme de mise à l'échelle combinée est-il similaire au pooling de TensorFlow ?

33voto

Louis Brandy Points 4844

La méthode "classique" de mesure consiste à diviser l'image en un nombre canonique de sections (disons une grille de 10x10), puis à calculer un histogramme des valeurs RVB dans chaque cellule et à comparer les histogrammes correspondants. Ce type d'algorithme est préféré en raison de sa simplicité et de son invariance à l'échelle et à la (petite !) translation.

7 votes

N'est-ce pas la même chose que de faire un seul histogramme pour toute l'image, mais avec l'inconvénient supplémentaire de ne pas être résistant aux miroirs et aux rotations ?

1 votes

Deux histogrammes provenant de deux moitiés de l'image auront une meilleure précision de correspondance qu'un histogramme de l'ensemble. Bien qu'elle ait les inconvénients que vous avez mentionnés, cela dépend du problème que vous résolvez.

27voto

Lehane Points 6776

Utilisez un histogramme de couleur normalisé. (Lisez la section sur les applications ici ), ils sont couramment utilisés dans les systèmes de recherche et de comparaison d'images et constituent une méthode standard de comparaison d'images qui est très fiable, relativement rapide et très facile à mettre en œuvre.

Essentiellement, un histogramme de couleur capture la distribution des couleurs de l'image. Elle peut ensuite être comparée à une autre image pour voir si les distributions de couleurs correspondent.

Ce type de correspondance est assez résistant à la mise à l'échelle (une fois l'histogramme normalisé), à la rotation, au déplacement, etc.

Évitez les comparaisons pixel par pixel, car si l'image subit une légère rotation ou un léger décalage, une grande différence peut être signalée.

Les histogrammes seraient simples à générer vous-même (en supposant que vous puissiez accéder aux valeurs des pixels), mais si vous n'avez pas envie de le faire, la fonction OpenCV La bibliothèque est une excellente ressource pour faire ce genre de choses. Aquí est une présentation powerpoint qui vous montre comment créer un histogramme en utilisant OpenCV.

14voto

mbaird Points 31293

Les algorithmes d'encodage vidéo comme le MPEG ne calculent-ils pas la différence entre chaque image d'une vidéo pour pouvoir simplement encoder le delta ? Vous pourriez étudier la manière dont les algorithmes de codage vidéo calculent ces différences entre les images.

Regardez cette application de recherche d'images à code source ouvert http://www.semanticmetadata.net/lire/ . Il décrit plusieurs algorithmes de similarité d'images, dont trois sont issus de la norme MPEG-7 : ScalableColor, ColorLayout, EdgeHistogram et Auto Color Correlogram.

1 votes

Cela ne répondrait pas à la question posée ici. La question ne porte pas sur la comparaison pixel par pixel.

2 votes

@Kousha Vrai, mais toujours une direction intéressante pour la réflexion.

13voto

Shachar Points 61

Vous pourriez utiliser une approche purement mathématique de O(n^2) mais cela ne sera utile que si vous êtes certain qu'il n'y a pas de décalage ou quelque chose comme ça. (Bien que si vous avez quelques objets avec une coloration homogène, cela fonctionnera encore assez bien).

Quoi qu'il en soit, l'idée est de calculer le produit scalaire normalisé des deux matrices. C = sum(Pij*Qij)^2/(sum(Pij^2)*sum(Qij^2)) .

Cette formule est en fait le "cosinus" de l'angle entre les matrices (bizarre). Plus la similitude est grande (disons Pij=Qij ), C sera égal à 1, et s'ils sont complètement différents, disons que pour chaque i,j Qij = 1 (en évitant la division par zéro), Pij = 255 alors pour la taille nxn le plus grand n sera, plus on s'approchera de zéro. (Par un calcul approximatif : C=1/n^2 ).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X