Ce message était le point de départ de ma solution, beaucoup de bonnes idées ici, donc je pensais partager mes résultats. L'idée principale est que j'ai trouvé un moyen de contourner la lenteur de la correspondance d'images basée sur des points clés en exploitant la vitesse de phash.
Pour la solution générale, il est préférable d'employer plusieurs stratégies. Chaque algorithme est le mieux adapté à certains types de transformations d'image et vous pouvez en profiter.
En haut, les algorithmes les plus rapides; en bas le plus lent (bien que plus précis). Vous pouvez sauter les plus lents si une bonne correspondance est trouvée au niveau le plus rapide.
- fichier basé sur le hachage (md5, sha1, etc.) pour les doublons exacts
- hachage perceptuel (phash) pour les images redimensionnées
- basé sur les fonctionnalités (SIFT) pour les images modifiées
J'ai de très bons résultats avec phash. La précision est bonne pour les images redimensionnées. Ce n'est pas bon pour les images modifiées (perceptuellement) (recadrées, tournées, inversées, etc.). Pour gérer la vitesse de hachage, nous devons utiliser un cache disque / base de données pour maintenir les hachages pour la botte de foin.
La chose vraiment agréable à propos de phash est qu'une fois que vous avez construit votre base de données de hachage (qui pour moi est d'environ 1000 images / sec), les recherches peuvent être très, très rapides, en particulier lorsque vous pouvez conserver la base de données de hachage entière en mémoire. C'est assez pratique car un hachage ne fait que 8 octets.
Par exemple, si vous avez 1 million d'images, il faudrait un tableau de 1 million de valeurs de hachage 64 bits (8 Mo). Sur certains processeurs, cela tient dans le cache L2 / L3! Dans la pratique, j'ai vu un corei7 comparer à plus de 1 Giga-hamm / sec, ce n'est qu'une question de bande passante mémoire pour le CPU. Une base de données à 1 milliard d'images est pratique sur un processeur 64 bits (8 Go de RAM nécessaires) et les recherches ne dépasseront pas 1 seconde!
Pour les images modifiées / recadrées, il semblerait qu'une fonctionnalité invariante par transformation / détecteur de point clé comme SIFT soit la voie à suivre. SIFT produira de bons points clés qui détecteront le recadrage / rotation / miroir, etc. Cependant, la comparaison des descripteurs est très lente par rapport à la distance de brouillage utilisée par phash. Il s'agit d'une limitation majeure. Il y a beaucoup de comparaisons à faire, car il y a un descripteur IxJxK maximal à comparer pour rechercher une image (I = num images de meule de foin, J = points de clé cible par image de meule de foin, K = points de clé cible par image d'aiguille).
Pour contourner le problème de vitesse, j'ai essayé d'utiliser phash autour de chaque point clé trouvé, en utilisant la taille / le rayon de l'entité pour déterminer le sous-rectangle. L'astuce pour bien faire fonctionner est d'augmenter / rétrécir le rayon pour générer différents niveaux sub-rect (sur l'image de l'aiguille). Généralement, le premier niveau (non mis à l'échelle) correspondra, mais il en faut souvent un peu plus. Je ne suis pas sûr à 100% de la raison pour laquelle cela fonctionne, mais je peux imaginer que cela permet des fonctionnalités trop petites pour que phash fonctionne (phash réduit les images à 32x32).
Un autre problème est que SIFT ne distribuera pas les points clés de manière optimale. S'il y a une section de l'image avec beaucoup de bords, les points clés s'y regrouperont et vous n'en obtiendrez pas dans une autre zone. J'utilise le GridAdaptedFeatureDetector dans OpenCV pour améliorer la distribution. Je ne sais pas quelle taille de grille est la meilleure, j'utilise une petite grille (1x3 ou 3x1 selon l'orientation de l'image).
Vous voudrez probablement redimensionner toutes les images de la botte de foin (et l'aiguille) à une taille plus petite avant la détection des fonctionnalités (j'utilise 210 px le long de la dimension maximale). Cela réduira le bruit dans l'image (toujours un problème pour les algorithmes de vision par ordinateur) et concentrera également le détecteur sur des caractéristiques plus importantes.
Pour les images de personnes, vous pouvez essayer la détection des visages et l'utiliser pour déterminer la taille de l'image à mettre à l'échelle et la taille de la grille (par exemple, le plus grand visage mis à l'échelle pour être de 100 pixels). Le détecteur de caractéristiques prend en compte plusieurs niveaux d'échelle (en utilisant des pyramides) mais il y a une limite au nombre de niveaux qu'il utilisera (cela peut être ajusté bien sûr).
Le détecteur de points clés fonctionne probablement mieux lorsqu'il renvoie moins que le nombre de fonctionnalités que vous vouliez. Par exemple, si vous demandez 400 et récupérez 300, c'est bien. Si vous en récupérez 400 à chaque fois, quelques bonnes fonctionnalités ont probablement dû être omises.
L'image de l'aiguille peut avoir moins de points clés que les images de la botte de foin et toujours obtenir de bons résultats. L'ajout de plus n'obtient pas nécessairement d'énormes gains, par exemple avec J = 400 et K = 40, mon taux de réussite est d'environ 92%. Avec J = 400 et K = 400, le taux de réussite ne monte que jusqu'à 96%.
Nous pouvons profiter de la vitesse extrême de la fonction de hamming pour résoudre l'échelle, la rotation, la mise en miroir, etc. Une technique à passes multiples peut être utilisée. À chaque itération, transformez les sous-rectangles, re-hachez et réexécutez la fonction de recherche.