37 votes

OpenCV / SURF Comment générer un hachage d'image / une empreinte digitale / une signature à partir des descripteurs ?

Il y a quelques sujets ici qui sont très utiles sur la façon de trouver des images similaires.

Ce que je veux faire, c'est obtenir l'empreinte digitale d'une image et retrouver la même image sur différentes photos prises par un appareil photo numérique. L'algorithme SURF semble être le meilleur moyen d'être indépendant de l'échelle, de l'angle et des autres distorsions.

J'utilise OpenCV avec l'algorithme SURF pour extraire les caractéristiques de l'image d'exemple. Je me demande maintenant comment convertir toutes ces données (position, laplacien, taille, orientation, hessian) en une empreinte digitale ou un hash.

Cette empreinte sera stockée dans une base de données et une requête de recherche doit pouvoir comparer cette empreinte avec l'empreinte d'une photo ayant pratiquement les mêmes caractéristiques.

Mise à jour :

Il semble qu'il n'y ait aucun moyen de convertir tous les vecteurs de descripteurs en un simple hachage. Quelle serait donc la meilleure façon de stocker les descripteurs d'images dans la base de données pour une interrogation rapide ?

Les arbres de vocabulaire seraient-ils une option ?

Je serais très reconnaissant pour toute aide.

9voto

elijah Points 926

Les données caractéristiques que vous mentionnez (position, laplacien, taille, orientation, hessien) sont insuffisantes pour votre objectif (ce sont en fait les parties les moins pertinentes du descripteur si vous voulez faire de la correspondance). Les données que vous voulez examiner sont les "descripteurs" (le 4e argument) :

void cvExtractSURF(const CvArr* image, const CvArr* mask, CvSeq** keypoints, CvSeq** descriptors, CvMemStorage* storage, CvSURFParams params)

Ce sont des vecteurs de 128 ou 64 (selon les paramètres) qui contiennent les "empreintes digitales" de la caractéristique spécifique (chaque image contiendra une quantité variable de tels vecteurs). Si vous obtenez la dernière version d'Opencv, ils ont un exemple nommé find_obj.cpp qui vous montre comment il est utilisé pour la correspondance.

mise à jour :

vous pourriez trouver este discussion utile

3voto

user245973 Points 374

Une façon triviale de calculer un hachage serait la suivante. Obtenez tous les descripteurs de l'image (disons, N d'entre eux). Chaque descripteur est un vecteur de 128 nombres (vous pouvez les convertir en nombres entiers entre 0 et 255). Vous avez donc un ensemble de N*128 entiers. Il suffit de les écrire l'un après l'autre dans une chaîne et de l'utiliser comme valeur de hachage. Si vous voulez que les valeurs de hachage soient petites, je crois qu'il existe des moyens de calculer les fonctions de hachage des chaînes de caractères, donc de convertir les descripteurs en chaîne de caractères et d'utiliser la valeur de hachage de cette chaîne.

Cela pourrait fonctionner si vous voulez trouver des doublons exacts. Mais il semble (puisque vous parlez d'échelle, de rotation, etc.) que vous voulez simplement trouver des images "similaires". Dans ce cas, l'utilisation d'un hachage n'est probablement pas une bonne solution. Vous utilisez probablement un détecteur de points d'intérêt pour trouver les points sur lesquels calculer les descripteurs SURF. Imaginez qu'il renvoie le même ensemble de points, mais dans un ordre différent. Soudain, votre valeur de hachage sera très différente, même si les images et les descripteurs sont les mêmes.

Donc, si je devais trouver des images similaires de manière fiable, j'utiliserais une approche différente. Par exemple, je pourrais quantifier vectoriellement les descripteurs SURF, construire des histogrammes de valeurs quantifiées vectoriellement et utiliser l'intersection des histogrammes pour la mise en correspondance. Devez-vous absolument utiliser des fonctions de hachage (peut-être pour des raisons d'efficacité), ou voulez-vous simplement utiliser n'importe quoi pour trouver des images similaires ?

2voto

forefinger Points 1589

Il semble que GIST soit une chose plus appropriée à utiliser.

http://people.csail.mit.edu/torralba/code/spatialenvelope/ a un code MATLAB.

2voto

Stefan Points 378

Min-Hash o min-Hashing est une technique qui pourrait vous aider. Elle permet de coder l'image entière dans une représentation de taille réglable qui est ensuite stockée dans des tables de hachage. Plusieurs variantes comme Mini-hachage géométrique , Partition min-Hash y Bundle min-Hashing existent. L'empreinte mémoire résultante n'est pas l'une des plus petites, mais ces techniques fonctionnent pour une variété de scénarios tels que la recherche de quasi-duplicata et même la recherche de petits objets - un scénario où les autres signatures courtes ne sont souvent pas très performantes.

Il existe plusieurs documents sur ce sujet. La littérature d'entrée serait : Détection d'images quasi-doubles : min-Hash et pondération tf-idf Ondrej Chum, James Philbin, Andrew Zisserman, BMVC 2008 PDF

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