Comment puis-je quantifier la différence entre les deux images?
Voici ce que je voudrais faire:
Je vais prendre des photos avec une webcam à intervalles réguliers. Comme une sorte de time lapse chose. Toutefois, si rien n'a vraiment changé, c'est l'image assez bien semble le même, je ne veux pas stocker le dernier instantané.
J'imagine qu'il y a un moyen de quantifier la différence, et j'aurais à déterminer empiriquement un seuil.
Je suis à la recherche de la simplicité plutôt que la perfection.
Je suis à l'aide de python.
- Connexes: stackoverflow.com/questions/25977/...
Vous devez vous connecter pour publier un commentaire.
Idée générale
Option 1: Charger à la fois des images sous la forme de tableaux (
scipy.misc.imread
) et de calculer un élément-sage (pixel par pixel) de différence. Calculer la norme de la différence.Option 2: Charger les deux images. Calculer certaines disposent d'vecteur pour chacun d'eux (comme un histogramme). Calculer la distance entre les fonction de vecteurs plutôt que des images.
Cependant, il ya quelques décisions à prendre en premier.
Questions
Vous devez répondre à ces questions d'abord:
Sont des images de la même forme et la même dimension?
Si non, vous devrez peut-être redimensionner ou recadrer. PIL bibliothèque aidera à le faire en Python.
Si elles sont prises avec les mêmes paramètres et la même dispositif, ils sont probablement les mêmes.
Images sont bien alignées?
Si pas, vous pouvez exécuter l'inter-corrélation d'abord, pour trouver le meilleur alignement de la première. SciPy a des fonctions pour le faire.
Si la caméra et la scène sont toujours, les images sont susceptibles d'être bien alignés.
Est l'exposition des images toujours le même? (Est-luminosité/contraste le même?)
Si pas, vous pouvez pour normaliser images.
Mais attention, dans certaines situations, cela peut faire plus de mal que de bien. Par exemple, un pixel défectueux sur un fond sombre fera l'normalisé de l'image très différente.
Est la couleur de l'information importante?
Si vous voulez l'avis des changements de couleur, vous aurez un vecteur de valeurs de couleur par point, plutôt qu'une valeur scalaire comme en échelle de gris de l'image. Vous avez besoin plus d'attention lors de la rédaction d'un tel code.
Sont là bords distincts dans l'image? Sont-ils susceptibles de se déplacer?
Si oui, vous pouvez appliquer bord de l'algorithme de détection de la première (par exemple, calculer un gradient de Sobel ou de Prewitt transformer, appliquez un peu de seuil), puis de comparer les bords sur la première image, sur les bords de sur la deuxième.
Est-il du bruit dans l'image?
Tous les capteurs de polluer l'image avec une certaine quantité de bruit. Faible coût des capteurs ont le plus de bruit. Vous pouvez appliquer un peu de réduction de bruit avant de comparer les images. Le flou est plus simple (mais pas le meilleur) approche ici.
Quels changements voulez-vous un avis?
Cela peut influer sur le choix de la norme à utiliser pour la différence entre les images.
Envisager l'utilisation de Manhattan norme (la somme des valeurs absolues) ou zéro norme (le nombre d'éléments n'est pas égale à zéro) pour mesurer combien l'image a changé. Les anciens vous diront combien l'image est désactivé, ce dernier sera seulement dire le nombre de pixels différents.
Exemple
Je suppose que vos images sont bien alignées, de la même taille et de la forme, peut-être avec différents niveaux d'exposition. Pour des raisons de simplicité, je les convertir en niveaux de gris, même si elles sont de couleur (RVB) des images.
Vous aurez besoin de ces importations:
Principale fonction de lire les deux images, les convertir en niveaux de gris, de comparer et d'imprimer les résultats:
Comment comparer.
img1
etimg2
sont en 2D SciPy tableaux ici:Si le fichier est une image en couleur,
imread
retourne un tableau 3D, la moyenne des canaux RVB (le dernier tableau de l'axe) pour obtenir l'intensité. Pas besoin de le faire pour les images en niveaux de gris (par exemple.pgm
):La normalisation est trivial, vous pouvez choisir de normaliser à [0,1] au lieu de [0,255].
arr
est un SciPy tableau ici, de sorte que toutes les opérations sont l'élément de sage:Exécuter le
main
fonction:Maintenant vous pouvez mettre tout cela dans un script et l'exécuter à l'encontre de deux images. Si l'on compare l'image de lui-même, il n'y a pas de différence:
Si nous le flou de l'image et de la comparer à l'original, il y a une certaine différence:
P. S. Toute compare.py script.
Mise à jour: les techniques pertinentes
Que la question est à propos d'une séquence vidéo, où les images sont susceptibles d'être presque le même, et vous cherchez quelque chose d'inhabituel, je voudrais mentionner quelques approches alternatives qui pourraient être utiles:
Je recommande fortement de prendre un coup d'oeil à “l'Apprentissage de l'utilisation d'OpenCV” livre, les Chapitres 9 (Image des pièces et de la segmentation) et 10 (Suivi et de mouvement). L'ancienne enseigne à utiliser soustraction d'arrière-plan de la méthode, ce dernier donne des informations sur le flux optique méthodes. Toutes les méthodes sont implémentées dans la bibliothèque OpenCV. Si vous utilisez Python, je suggère d'utiliser OpenCV ≥ 2.3, et son
cv2
module Python.La version la plus simple de la soustraction du bruit de fond:
D'autres versions plus évoluées de les prendre en compte à la fois de la série pour chaque pixel et gérer les non-scènes statiques (comme le déplacement d'arbres ou de l'herbe).
L'idée de flux optique est de prendre deux ou plusieurs images, et d'attribuer vecteur de vélocité pour chaque pixel (dense flux optique) ou à certains d'entre eux (sparse flux optique). Pour estimer éparses du flux optique, vous pouvez utiliser Lucas-Kanade méthode (il est également mis en œuvre dans OpenCV). De toute évidence, si il y a beaucoup de débit (haute moyenne sur les valeurs maximales du champ de vitesse), alors quelque chose est en mouvement dans le cadre et à la suite des images sont de plus en plus différents.
La comparaison des histogrammes peut aider à détecter les changements brusques entre les images consécutives. Cette approche a été utilisée dans Courbon et al, 2010:
RuntimeWarning: invalid value encountered in double_scalars
sur la ligne 44 (return (arr-amin)*255/rng
) et unValueError: array must not contain infs or NaNs
à la ligne 30 (z_norm = norm(diff.ravel(), 0)
)rng
est égal à zéro. Il suffit d'ajouter un contrôle et réglage de l'rng = 1
Une solution simple:
Coder l'image en tant que jpeg et de regarder pour un changement substantiel dans filesize.
J'ai mis en place quelque chose de similaire avec les vignettes des vidéos, et ont eu beaucoup de succès et d'évolutivité.
Vous pouvez comparer deux images à l'aide de fonctions de PIL.
La diff objet est une image dans laquelle chaque pixel est le résultat de la soustraction des valeurs de couleur de ce pixel dans la seconde image de la première image. À l'aide de la diff de l'image vous pouvez faire plusieurs choses. Le plus simple est le
diff.getbbox()
fonction. Il vous dira le minimum de rectangle qui contient toutes les modifications entre vos deux images.Vous pouvez probablement mettre en œuvre des approximations des autres choses mentionnées ici à l'aide de fonctions de PIL ainsi.
Deux populaire et relativement simples méthodes sont les suivantes: (a) la distance Euclidienne déjà suggéré, ou (b) corrélation croisée normalisée. Corrélation croisée normalisée tend à être nettement plus robuste aux variations de l'éclairage que de la simple corrélation croisée. Wikipédia donne une formule pour la corrélation croisée normalisée. Des méthodes plus sophistiquées existent aussi, mais ils nécessitent un peu plus de travail.
Utilisation de numpy syntaxe,
en supposant que
i1
eti2
sont en 2D image en niveaux de gris des tableaux.Une chose banale à essayer:
Rééchantillonner les deux images pour les petites vignettes (par exemple, 64 x 64) et comparer les vignettes pixel-par-pixel avec un certain seuil. Si les images d'origine sont presque les mêmes, le nombre de vignettes seront très similaires, voire identiques. Cette méthode prend soin de bruit qui peut se produire en particulier dans les scènes à faible luminosité. Il peut même être préférable si vous pouvez aller en niveaux de gris.
Je m'adresse plus précisément à la question de la manière de calculer si ils sont "assez différents". Je suppose que vous pouvez comprendre comment soustraire les pixels un par un.
D'abord, je voudrais prendre un tas d'images avec rien de changer, et de connaître le montant maximal que tout changement pixel seulement en raison de variations dans la capture, le bruit dans le système d'imagerie, les artefacts de compression JPEG, et d'instant en instant changements dans l'éclairage. Peut-être que vous trouverez que 1 ou 2, peu de différences sont à prévoir, même quand rien ne bouge.
Puis le "vrai" test, vous voulez un critère comme ceci:
Alors, peut-être, si E = 0.02, P = 1000, cela signifierait (environ) qu'il serait "différent" si un seul pixel de changement de plus de ~5 unités (en supposant que les images 8 bits), ou si plus de 1000 pixels avait des erreurs à tous.
C'est destiné principalement comme un bon "triage" technique pour identifier rapidement les images qui sont assez proches pour ne pas avoir besoin d'un nouvel examen. Les images qui "échouent" peut alors plus à une version plus élaborée/cher technique qui n'aurait pas de faux positifs si l'appareil photo a secoué bits, par exemple, ou a été plus robuste aux variations de l'éclairage.
- Je exécuter un projet open source, OpenImageIO, qui contient un utilitaire appelé "idiff" qui permet de comparer les différences avec les seuils de cette façon (même les plus élaborées, en fait). Même si vous ne souhaitez pas utiliser ce logiciel, vous voudrez peut-être chercher à la source pour voir comment nous l'avons fait. Il est utilisé à des fins commerciales un peu et ce seuillage technique a été développée pour que nous puissions avoir une suite de tests pour le rendu et le logiciel de traitement d'image, avec des "images de référence" qui pourrait avoir de petites différences par rapport à la plate-forme à plate-forme ou que nous avons fait quelques changements mineurs à tha algorithmes, nous avons donc voulu un "match à l'intérieur de la tolérance de l'opération".
La plupart des réponses données ne seront pas traiter avec des niveaux d'éclairage.
Je voudrais d'abord normaliser l'image d'un standard de lumière de niveau avant de faire la comparaison.
Une jolie, manière simple de mesurer la similarité entre deux images:
Si d'autres sont intéressés par un moyen plus puissant pour comparer les images similaires, j'ai mis en place un tutoriel et web app pour la mesure et la visualisation des images similaires à l'aide de Tensorflow.
skimage
est vraiment agréable à utiliser pour cette application. J'utilisefrom skimage.measure import compare_ssim, compare_mse
beaucoup. skimage.mesure docs.J'ai eu un problème similaire au travail, j'ai été la réécriture de notre image de transformation des systèmes d'extrémité et je voulais vérifier que la nouvelle version a été la production de la même ou presque la même sortie que l'ancienne version. J'ai donc écrit ceci:
https://github.com/nicolashahn/diffimg
Qui opère sur des images de la même taille, et au niveau des pixels, des mesures de la différence dans les valeurs des canaux: R, G, B, A), prend la moyenne de la différence de ces canaux, puis les moyennes de la différence sur tous les pixels, et renvoie un rapport.
Par exemple, avec un 10x10 image de pixels blancs, et la même image, mais d'un pixel a changé au rouge, la différence à ce pixel est de 1/3 ou 0,33... (RVB 0,0,0 vs 255,0,0) et à tous les autres pixels est de 0. Avec 100 pixels total de 0,33.../100 = a ~0.33% de différence dans l'image.
Je crois que cela fonctionnerait parfaitement pour des OP de projet (je réalise que c'est un très vieux post aujourd'hui, mais l'affichage pour l'avenir StackOverflowers qui veulent aussi de comparer des images en python).
Avez-vous vu le Algorithme pour trouver des images similaires question? Check it out pour voir des suggestions.
Je suggère une transformation en ondelettes de vos images (j'ai écrit un C extension pour que l'utilisation de Haar de transformation); puis, en comparant les indices de la plus grande (proportionnellement) ondelettes facteurs entre les deux images, vous devez obtenir un numéro d'similitude rapprochement.
Je m'excuse si c'est trop tard pour répondre, mais depuis que j'ai fait quelque chose de similaire, je pensais que je pouvais contribuer en quelque sorte.
Peut-être avec OpenCV vous pouvez utiliser le modèle de mise en correspondance. En supposant que vous êtes à l'aide d'une webcam comme vous l'avez dit:
Astuce: max_val (ou min_val selon la méthode utilisée) va vous donner des chiffres, un grand nombre. Pour obtenir la différence de pourcentage, utiliser un modèle d'appariement avec la même image, le résultat sera à 100%.
Pseudo code pour illustrer:
Espère que cela aide.
Terre de déménageurs à distance pourrait être exactement ce dont vous avez besoin.
Il peut être abit lourdes à mettre en œuvre en temps réel si.
Que sur le calcul de l' Distance Manhattan des deux images. Qui vous donne le n*n valeurs. Ensuite, vous pourriez faire quelque chose comme une ligne moyenne à réduire à n des valeurs et une fonction de plus que, pour obtenir une valeur unique.
J'ai eu beaucoup de chance avec jpg images prises avec le même appareil sur un trépied par
(1) simplifier grandement (comme allant de 3000 pixels de large et 100 pixels de large ou même moins)
(2) l'aplatissement de chaque jpg tableau en un seul vecteur
(3) paires de corrélation d'images séquentielles avec une simple corrélation algorithme pour obtenir le coefficient de corrélation
(4) la quadrature du coefficient de corrélation pour obtenir le r-carré (j'.e fraction de la variabilité dans une image expliquée par la variation de la prochaine)
(5) en général dans ma demande si r-carré < 0.9, je dis que les deux images sont différentes, et quelque chose s'est passé entre les deux.
C'est robuste et rapide dans mon application (Mathematica 7)
Il vaut la peine de jouer autour de la partie de l'image qui vous intéresse et en se concentrant sur que par la culture de toutes les images de cette petite partie, sinon un lointain-de-la-caméra mais changement important sera raté.
Je ne sais pas comment utiliser Python, mais je suis sûr qu'il ne corrélations, trop, non?
vous pouvez calculer l'histogramme de la fois les images et ensuite calculer la Bhattacharyya Coefficient, c'est un très algorithme rapide et je l'ai utilisé pour détecter le tir des changements dans une cricket de la vidéo (en C à l'aide d'openCV)
Découvrez comment les Ondelettes de Haar sont mis en œuvre par isk-démon. Vous pouvez l'utiliser de imgdb de code C++ pour calculer la différence entre les images à la volée:
J'ai eu le même problème et a écrit un simple module python qui compare deux de même taille des images à l'aide d'oreiller de ImageChops pour créer un noir/blanc diff image et résume l'histogramme des valeurs.
Vous pouvez obtenir ce score directement, ou un pourcentage de la valeur par rapport à un noir vs blanc diff.
Il contient également un simple is_equal fonction, avec la possibilité de fournir un floue-seuil à (et y compris) l'image passe comme égaux.
L'approche n'est pas très élaboré, mais peut-être est de les utiliser pour d'autres là aux prises avec le même problème.
https://pypi.python.org/pypi/imgcompare/
Un peu plus de principe de l'approche est d'utiliser un descripteur global pour comparer les images, telles que les GIST ou CENTRISTE. Une fonction de hachage, comme décrit ici, fournit également une solution similaire.
de sortie:
Faux
Vrai
image2\5.jpg image1\815.jpg
image2\6.jpg image1\819.jpg
image2\7.jpg image1\900.jpg
image2\8.jpg image1\998.jpg
image2\9.jpg image1\1012.jpg
les images de l'exemple:
815.jpg
5.jpg
Je pense que vous pourriez tout simplement calculer la distance euclidienne (c'est à dire sqrt(somme des carrés des différences, pixel par pixel)) entre la luminance des deux images, et qui les considèrent comme égaux si cela tombe sous un certain seuil empirique. Et vous serait mieux de le faire la recouvrant d'une fonction C.
Il y a beaucoup de métriques pour évaluer si deux images ressemblent/combien ils ressemblent.
Je n'entrerai pas dans le code ici, parce que je pense que cela devrait être un problème scientifique, d'autres que d'un problème technique.
Généralement, la question est liée à la perception sur les images, de sorte que chaque algorithme s'appuie sur le système visuel humain traits.
Approches classiques sont:
Différences visibles prédicteur: un algorithme pour l'évaluation de la fidélité de l'image (https://www.spiedigitallibrary.org/conference-proceedings-of-spie/1666/0000/Visible-differences-predictor--an-algorithm-for-the-assessment-of/10.1117/12.135952.short?SSO=1)
Image Évaluation de la Qualité: De l'Erreur de la Visibilité à la Similarité Structurelle (http://www.cns.nyu.edu/pub/lcv/wang03-reprint.pdf)
FSIM: UNE Caractéristique Indice de Similarité pour la Qualité de l'Image de l'Évaluation (https://www4.comp.polyu.edu.hk/~cslzhang/IQA/TIP_IQA_FSIM.pdf)
Parmi eux, SSIM (Image Évaluation de la Qualité: De l'Erreur de la Visibilité à la Similarité Structurelle ) est le plus facile à calculer et de ses frais généraux est aussi petit, comme rapporté dans un autre document "Image de la Qualité de l'Évaluation Basée sur le Gradient de Similitude" (https://www.semanticscholar.org/paper/Image-Quality-Assessment-Based-on-Gradient-Liu-Lin/2b819bef80c02d5d4cb56f27b202535e119df988).
Il y a beaucoup plus d'autres approches. Jetez un oeil à Google Scholar et la recherche de quelque chose comme "différence visuelle", "la qualité de l'image de" l'évaluation, etc, si vous êtes intéressé/se soucient vraiment de l'art.