Quel est un moyen rapide de trier un ensemble d'images donné en fonction de leur similitude.
Pour le moment, j'ai un système qui fait une analyse d'histogramme entre deux images, mais c'est une opération très coûteuse et semble trop exagérée.
Idéalement, je recherche un algorithme qui donnerait à chaque image un score (par exemple un score entier, comme la moyenne RVB) et je peux simplement trier par ce score. Des scores identiques ou des scores côte à côte sont des doublons possibles.
0299393
0599483
0499994 <- possible dupe
0499999 <- possible dupe
1002039
4995994
6004994
RVB La moyenne par image est nulle, y a-t-il quelque chose de similaire?
Il y a eu beaucoup de recherches sur la recherche d'images et les mesures de similitude. Ce n'est pas un problème facile. En général, un seul int
ne sera pas suffisant pour déterminer si les images sont très similaires. Vous aurez un taux de faux positifs élevé.
Cependant, comme il y a eu beaucoup de recherches, vous pourriez en jeter un coup d'œil. Par exemple, cet article (PDF) donne un algorithme d'empreinte digitale compact qui convient pour trouver des images en double rapidement et sans stocker beaucoup de données. Il semble que ce soit la bonne bonne approche si vous voulez quelque chose de robuste.
Si vous cherchez quelque chose de plus simple, mais certainement plus ad hoc, cette SO question a quelques idées décentes.
Je recommanderais d'envisager de ne plus utiliser uniquement un histogramme RVB.
Un meilleur résumé de votre image peut être obtenu si vous prenez une ondelette Haar 2D de l'image (c'est beaucoup plus facile qu'il n'y paraît, c'est juste beaucoup de moyenne et quelques racines carrées utilisées pour pondérer vos coefficients) et conservez simplement le k le plus grand coefficients pondérés dans l'ondelette en tant que vecteur clairsemé, normalisez-le et enregistrez-le pour réduire sa taille. Vous devriez redimensionner R G et B en utilisant au moins des poids perceptifs au préalable ou je recommanderais de passer à YIQ (ou YCoCg, pour éviter le bruit de quantification) afin de pouvoir échantillonner les informations de chrominance avec une importance réduite.
Vous pouvez maintenant utiliser le produit scalaire de deux de ces vecteurs normalisés clairsemés comme mesure de similitude. Les paires d'images avec les produits en points les plus gros vont avoir une structure très similaire. Cela a l'avantage d'être légèrement résistant au redimensionnement, au changement de teinte et au filigrane, et d'être vraiment facile à mettre en œuvre et compact.
Vous pouvez échanger le stockage et la précision en augmentant ou en diminuant k.
Le tri par un seul score numérique va être insoluble pour ce type de problème de classification. Si vous y réfléchissez, il faudrait que les images ne puissent "changer" que sur un axe, mais ce n'est pas le cas. C'est pourquoi vous avez besoin d'un vecteur de fonctionnalités. Dans le cas des ondelettes Haar, c'est approximativement là où les discontinuités les plus nettes de l'image se produisent. Vous pouvez calculer une distance entre les images par paire, mais comme tout ce que vous avez est une mesure de distance, un ordre linéaire n'a aucun moyen d'exprimer un "triangle" de 3 images qui sont toutes également distantes. (c'est-à-dire penser à une image entièrement verte, une image entièrement rouge et une image entièrement bleue.)
Cela signifie que toute véritable solution à votre problème nécessitera des opérations O (n ^ 2) dans le nombre d'images que vous avez. Alors que s'il avait été possible de linéariser la mesure, vous pourriez avoir besoin uniquement de O (n log n), ou O(n) si la mesure était adaptée, disons, à un tri radix. dit, vous n'avez pas besoin de dépenser O (n ^ 2) car dans la pratique, vous n'avez pas besoin de passer au crible l'ensemble, il vous suffit de trouver les trucs qui sont plus proches d'un certain seuil. Donc, en appliquant l'une des techniques pour partitionner votre espace vectoriel clairsemé, vous pouvez obtenir des asymptotiques beaucoup plus rapides pour le problème `` me trouver des images qui sont plus similaires à un seuil donné '' que de comparer naïvement chaque image contre chaque image, vous donnant ce dont vous avez probablement besoin ... si pas exactement ce que vous avez demandé.
Quoi qu'il en soit, j'ai utilisé cela il y a quelques années à bon escient personnellement en essayant de minimiser le nombre de textures différentes que je stockais, mais il y a également eu beaucoup de bruit de recherche dans cet espace montrant son efficacité (et dans ce cas, en comparant à une forme plus sophistiquée de classification d'histogramme):
http://www.cs.princeton.edu/cass/papers/spam_ceas07.pdf
Si vous avez besoin d'une meilleure précision de détection, les algorithmes minHash et tf-idf peuvent être utilisés avec l'ondelette Haar (ou l'histogramme) pour traiter les modifications de manière plus robuste:
http://cmp.felk.cvut.cz/~chum/papers/chum_bmvc08.pdf
Enfin, Stanford propose une recherche d'images basée sur une variante plus exotique de ce type d'approche, basée sur l'extraction de fonctionnalités à partir des ondelettes pour trouver des sections d'images tournées ou à l'échelle, etc., mais cela va probablement bien au-delà de la quantité de travail que vous voudrais faire.
http://wang14.ist.psu.edu/cgi-bin/zwang/regionsearch_show.cgi
J'ai implémenté un algorithme très fiable pour cela appelé Fast Multiresolution Image Querying . Mon code (ancien, non entretenu) pour cela est ici .
Ce que la recherche d'images multirésolution rapide fait est de diviser l'image en 3 morceaux en fonction de l'espace colorimétrique YIQ (mieux pour faire correspondre les différences que RVB). Ensuite, l'image est essentiellement compressée à l'aide d'un algorithme d'ondelettes jusqu'à ce que seules les caractéristiques les plus importantes de chaque espace colorimétrique soient disponibles. Ces points sont stockés dans une structure de données. Les images de requête passent par le même processus et les principales fonctionnalités de l'image de requête sont comparées à celles de la base de données stockée. Plus il y a de correspondances, plus les images sont similaires.
L'algorithme est souvent utilisé pour la fonctionnalité "requête par esquisse". Mon logiciel permettait uniquement de saisir des images de requête via URL, il n'y avait donc pas d'interface utilisateur. Cependant, j'ai trouvé que cela fonctionnait exceptionnellement bien pour faire correspondre les vignettes à la grande version de cette image.
Beaucoup plus impressionnant que mon logiciel est retrievr qui vous permet d'essayer l'algorithme FMIQ en utilisant des images Flickr comme source. Très sympa! Essayez-le via un croquis ou en utilisant une image source, et vous pouvez voir à quel point cela fonctionne.
Une image a de nombreuses fonctionnalités, donc à moins que vous ne vous restreigniez à une seule, comme la luminosité moyenne, vous avez affaire à un espace de problème à n dimensions.
Si je vous demandais d'attribuer un seul entier aux villes du monde, pour que je sache lesquelles sont proches, les résultats ne seraient pas excellents. Vous pouvez, par exemple, choisir le fuseau horaire comme entier unique et obtenir de bons résultats avec certaines villes. Cependant, une ville près du pôle nord et une autre ville près du pôle sud peuvent également être dans le même fuseau horaire, même si elles sont aux extrémités opposées de la planète. Si je vous laisse utiliser deux entiers, vous pourriez obtenir de très bons résultats avec la latitude et la longitude. Le problème est le même pour la similitude d'image.
Cela dit, il existe des algorithmes qui essaient de regrouper des images similaires, ce qui est effectivement ce que vous demandez. C'est ce qui se produit lorsque vous effectuez une détection de visage avec Picasa. Avant même d'identifier des visages, il regroupe les visages similaires de sorte qu'il est facile de parcourir un ensemble de visages similaires et de donner à la plupart d'entre eux le même nom.
Il existe également une technique appelée analyse des composants principaux, qui vous permet de réduire les données à n dimensions à un nombre plus petit de dimensions. Ainsi, une image avec n fonctionnalités pourrait être réduite à une seule fonctionnalité. Cependant, ce n'est toujours pas la meilleure approche pour comparer les images.
Il y a une bibliothèque C ("libphash" - http://phash.org/ ) qui calculera le "hachage perceptuel" d'une image et vous permettra de détecter des images similaires en comparant les hachages (donc vous ne pas besoin de comparer chaque image directement avec toutes les autres images) mais malheureusement, cela ne semblait pas très précis lorsque je l'ai essayé.
Vous devez décider ce qui est "similaire". Contraste? Teinte?
Une image est-elle "similaire" à la même image à l'envers?
Je parie que vous pouvez trouver beaucoup de "rappels" en divisant les images en morceaux 4x4 et en obtenant une couleur moyenne pour chaque cellule de la grille. Vous auriez seize partitions par image. Pour juger de la similitude, vous feriez simplement une somme de carrés de différences entre les images.
Je ne pense pas qu'un seul hachage ait du sens, à moins qu'il ne soit contre un concept unique comme la teinte, la luminosité ou le contraste.
Voici votre idée:
0299393
0599483
0499994 <- possible dupe
0499999 <- possible dupe
1002039
4995994
6004994
Tout d'abord, je vais supposer que ce sont des nombres décimaux qui sont R * (2 ^ 16) + G * (2 ^ 8) + B, ou quelque chose comme ça. Évidemment, ce n'est pas bon parce que le rouge a un poids excessif.
Déplacer dans l'espace HSV serait mieux. Vous pouvez étaler les bits de HSV dans le hachage, ou vous pouvez simplement régler H ou S ou V individuellement, ou vous pouvez avoir trois hachages par image.
Encore une chose. Si vous pesez R, G et B. Pesez le vert le plus haut, puis le rouge, puis le bleu pour correspondre à la sensibilité visuelle humaine.
À l'ère des services Web, vous pouvez essayer http://tineye.com
La question Bon moyen d'identifier des images similaires? semble apporter une solution à votre question.
j'ai supposé que d'autres logiciels de recherche d'images en double effectuent une FFT sur les images et stockent les valeurs des différentes fréquences comme vecteurs:
Image1 = (u1, u2, u3, ..., un)
Image2 = (v1, v2, v3, ..., vn)
puis vous pouvez comparer deux images pour égalité en calculant la distance entre les vecteurs de poids de deux images:
distance = Sqrt(
(u1-v1)^2 +
(u2-v2)^2 +
(u2-v3)^2 +
...
(un-vn)^2);
La plupart des approches modernes de détection de la détection d'images presque dupliquées utilisent une détection de points intéressante et des descripteurs décrivant la zone autour de ces points. Souvent TAMISER est utilisé. Ensuite, vous pouvez quatifier les descripteurs et utiliser des clusters comme vocabulaire visuel Word.
Donc, si nous voyons le rapport des mots visuels communs de deux images à tous les mots visuels de ces images, vous estimez la similitude entre les images. Il y a beaucoup d'articles intéressants. L'un d'eux est Détection d'image presque dupliquée: pondération minHash et tf-idf
Par exemple, en utilisant l'extension IMMI et IMMI, vous pouvez examiner de nombreuses façons différentes de mesurer la similitude entre les images: http://spl.utko.feec.vutbr.cz/en/component/content/article/46-image- extension-de-traitement-pour-rapidminer-5
En définissant un certain seuil et en sélectionnant une méthode, vous pouvez mesurer la similitude.
Une solution consiste à effectuer une comparaison RMS/RSS sur chaque paire d'images requise pour effectuer un tri à bulles. Deuxièmement, vous pouvez effectuer un FFT sur chaque image et faire une moyenne d'axe pour récupérer un seul entier pour chaque image que vous utiliseriez comme index pour trier par . Vous pouvez envisager de faire n'importe quelle comparaison sur une version redimensionnée (25%, 10%) de l'original en fonction de la petite différence que vous choisissez d'ignorer et de la vitesse dont vous avez besoin. Faites-moi savoir si ces solutions sont intéressantes et nous pourrons en discuter ou vous fournir un exemple de code.