38 votes

Trouver des correspondances entre des images pixelisées de haute qualité et de basse qualité - est-ce possible? Comment?

J'ai un problème. Mon entreprise m'a donné terriblement ennuyeuse tâche. Nous avons deux bases de données de boîtes de dialogue. L'une de ces bases de données contient des images horribles de la qualité, de l'autre de très haute qualité.

Malheureusement, les boîtes de dialogue d'horribles qualité contiennent d'importantes correspondances avec d'autres infos.

J'ai été chargé de, manuellement, en passant par toutes les mauvaises images et les faire correspondre à des images de bonne qualité.

Serait-il possible d'automatiser ce processus à n'importe quel degré? Voici un exemple de deux boîtes de dialogue (tiré au hasard à partir de Google images) :

Good quality image

Bad Quality image

Donc, je suis en train d'essayer d'écrire un programme en C# pour tirer ces photos à partir de la base de données, cycle, à travers eux, de trouver ceux avec des formes communes, et de retour theird Id. Quelles sont mes meilleures options ici ?

29voto

Running Wild Points 1917

Je vois vraiment pas de raison d'utiliser toutes les bibliothèques externes pour cela, j'ai fait ce genre de chose de nombreuses fois et l'algorithme suivant fonctionne très bien. Je suppose que si vous comparez les deux images qu'ils ont les mêmes dimensions, mais vous pouvez tout simplement redimensionner si ils ne le font pas.

badness := 0.0
For x, y over the entire image:
  r, g, b := color at x,y in image 1
  R, G, B := color at x,y in image 2
  badness += (r-R)*(r-R) + (g-G)*(g-G) + (b-B)*(b-B)
badness /= (image width) * (image height)

Maintenant vous avez un normalisée de la méchanceté de valeur entre les deux images, le bas de la méchanceté, plus il est probable que les images du match. C'est simple et efficace, il existe une variété de choses qui rendent le travail mieux ou plus vite, dans certains cas, mais vous n'avez probablement pas besoin de quoi que ce soit. Vous n'avez même pas vraiment besoin de normaliser la méchanceté, mais de cette façon, vous pouvez juste venir avec un seuil unique pour cela, si vous voulez regarder plusieurs correspondances possibles manuellement.


Depuis que cette question a reçu un peu plus d'attention j'ai décidé d'ajouter un moyen pour accélérer le processus dans le cas où vous êtes le traitement de nombreuses images à plusieurs reprises. J'ai utilisé cette approche lorsque j'ai eu plusieurs dizaines de milliers d'images que j'avais besoin de comparer, et j'étais sûr qu'un type paire d'images serait très différent. Je savais aussi que toutes mes images seraient exactement les mêmes dimensions. Dans une situation dans laquelle vous êtes en comparant les boîtes de dialogue typique d'images peut être principalement gris-ish, et certaines de vos images peut exiger de redimensionnement (bien que peut-être, qui indique juste une mis-match), dans ce cas, cette approche peut ne pas gagner autant.

L'idée est de former un quad-arbre où chaque nœud représente la moyenne des valeurs RVB de la région qui nœud représente. Ainsi, un 4x4 de l'image aurait un nœud racine RVB avec des valeurs égales à la moyenne de la valeur RVB de l'image, ses enfants auraient valeurs RVB, représentant la moyenne de la valeur RVB de leur 2x2 régions, et leurs enfants représentent les pixels individuels. (Dans la pratique c'est une bonne idée de ne pas aller plus loin qu'une région d'environ 16x16, à ce point, vous devez simplement commencer à comparer les pixels).

Avant de commencer à comparer des images, vous aurez également besoin de décider sur un méchanceté seuil. Vous n'aurez pas à calculer badnesses au-dessus de ce seuil avec toute la fiabilité de la précision, c'est donc essentiellement le seuil à partir duquel vous êtes prêt pour une image de "ne pas être un match".

Maintenant, quand vous comparez l'image A image B, d'abord comparer les nœuds racine de leur quad-arbre de représentations. Calculer la méchanceté comme vous le feriez pour un seul pixel de l'image, et si la méchanceté dépasse le seuil de retourner immédiatement et le rapport de la méchanceté à ce niveau. Parce que vous êtes à l'aide normalisé badnesses, et depuis badnesses sont calculés à l'aide de différences au carré, la méchanceté, à quelque niveau égal ou inférieur à la méchanceté à des niveaux inférieurs, de sorte que si elle dépasse le seuil de points vous savez il permettra également de dépasser le seuil au niveau de chacun des pixels.

Si le test de seuil passe sur un nxn image, il suffit de le déposer au niveau suivant vers le bas et de la comparer comme si c'était un 2nx2n image. Une fois que vous obtenez assez bas il suffit de comparer les pixels individuels. En fonction de votre corpus d'images, cela peut vous permettre de sauter beaucoup de comparaisons.

14voto

Paolo Moretti Points 9519

Je serais personnellement d'aller pour une image algorithme de hachage.

L'objectif de l'image de hachage est de transformer le contenu de l'image en fonction de la séquence, afin d'obtenir un condensé de la représentation. Cette caractéristique de la séquence (c'est à dire un vecteur de bits) doit être suffisamment court pour rapide d'appariement et de préserver distinguer les caractéristiques de la similitude mesure du possible.

Il existe plusieurs algorithmes sont disponibles gratuitement dans les communautés open source.

Un simple exemple peut être trouvé dans cet article, où le Dr Neal Krawetz montre comment la Moyenne de l'algorithme de Hachage œuvres:

  1. Pour réduire la taille. Le moyen le plus rapide pour supprimer les hautes fréquences et de détail est de rétrécir l'image. Dans ce cas, la réduire à 8x8 de sorte qu'il y a 64 pixels au total. Ne pas la peine de garder le ratio d'aspect, d'écraser vers le bas pour s'adapter à un 8x8 carré. De cette façon, le hash correspond à toute variation de l'image, quelle que soit l'échelle ou de ratio d'aspect.
  2. Réduire de couleur. Le petit 8x8 l'image est convertie en niveaux de gris. Cela modifie la valeur de hachage à partir de 64 pixels (64 rouges, 64 vertes, et 64 bleu) à 64 couleurs.
  3. La moyenne des couleurs. Calculer la valeur moyenne de la 64 couleurs.
  4. Calculer les bits. C'est la partie amusante. Chaque bit est simplement défini sur la base si la valeur de la couleur est au-dessus ou au-dessous de la moyenne.
  5. Construire la table de hachage. Définir le 64 bits dans un entier de 64 bits. L'ordre n'a pas d'importance, aussi longtemps que vous êtes cohérent. (J'ai mis les bits de gauche à droite, de haut en bas à l'aide de big-endian.)

David Oftedal a écrit un C# application de ligne de commande qui permet de classer et comparer des images en utilisant la Moyenne de l'algorithme de Hachage. (J'ai testé sa mise en œuvre avec vos images d'exemple et j'ai eu un 98,4% de similarité).

Le principal avantage de cette solution est que vous lisez chaque image une seule fois, de créer les hachages et les classer selon leur similiarity (en utilisant, par exemple, la distance de Hamming).

De cette façon, vous dissocier la fonction de phase d'extraction de la phase de classification, et vous pouvez facilement passer à un autre algorithme de hachage si vous trouvez qu'il n'est pas assez précis.


Modifier

Vous pouvez trouver un exemple simple ici (Il comporte un ensemble de test de 40 images et il obtient un 40/40 score).

6voto

Jeremy Thompson Points 14428

L' API commerciale TinEye est une très bonne option.

J'ai déjà travaillé sur des programmes de comparaison d'images. La technologie de traitement d'image est étonnante de nos jours, elle est tellement avancée.

ps voici d'où viennent ces deux images aléatoires que vous avez extraites de Google: http://www.tineye.com/search/1ec9ebbf1b5b3b81cb52a7e8dbf42cb63126b4ea/

5voto

Dmitriy Points 718

Voici un sujet traitant de la similarité d’images avec des algorithmes, déjà implémenté dans la bibliothèque OpenCV . Vous ne devriez avoir aucun problème à importer des fonctions de bas niveau dans votre application C #.

4voto

Gene Points 20184

Puisque c'est un one-off de l'emploi, je voudrais le faire avec un script (choisissez votre langue préférée; je serais probablement prendre Perl) et ImageMagick. Vous pouvez utiliser le C# pour accomplir la même chose que le script, mais avec plus de code. Il suffit d'appeler le utilitaires de ligne de commande et analyser les résultats.

Le script pour vérifier une paire pour la ressemblance serait d'environ 10 lignes comme suit:

D'abord récupérer les tailles, identify et de vérifier les proportions presque le même. Si non, pas de match. Si oui, alors l'échelle la plus grande image à la taille de la plus petite, avec convert. Il est préférable d'essayer un peu à l'avance avec filter options pour trouver celui qui produit le plus de similitude dans l'équivalent d'images. Neuf d'entre eux sont disponibles.

Ensuite, utilisez l' compare fonction de produire une métrique de similarité. Comparer est suffisamment intelligente pour gérer la traduction et de culture. Faites des essais pour trouver un seuil de similarité qui n'a pas trop de faux positifs.

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