Trouver des images similaires dans (pur) PHP / MySQL
Mes utilisateurs sont des images de chargement de mon site et je voudrais tout d'abord leur offrir déjà téléchargé les images de la première. Mon idée est de
1. créer une sorte d'image "hash" de chaque image existante
2. créer une table de hachage de récemment téléchargé l'image et de la comparer avec les autres dans la base de données
j'ai trouvé quelques solutions intéressantes comme http://www.pureftpd.org/project/libpuzzle ou ou http://phash.org/ etc. mais ils ont eu un ou plusieurs problèmes
- ils ont besoin de certains non standard extension de PHP (ou ne sont pas en PHP) - il serait OK pour moi, mais je voudrais créer un plugin pour mon CMS populaires, qui est utilisé sur de nombreux environnements d'hébergement sans mon contrôle.
- ils sont de la comparaison de deux images, mais j'ai besoin de comparer un à plusieurs (par exemple, des milliers) et de le faire un par un serait très uneffective /lent ...
...
Je serais OK pour ne trouver que TRÈS similaire images (si par exemple la taille différente, réenregistré jpg ou différents jpg facteur de compression).
La seule idée que j'ai est pour redimensionner l'image, par exemple de 5px*5px* 256 couleurs, créer une représentation de chaîne, et puis de trouver la même. Mais je suppose que ça peut avoir de créer de petites différences dans les couleurs, même avec seulement deux mêmes images avec différentes tailles, afin de trouver juste le 100 % même serait inutile.
J'ai donc besoin d'un peu de bon format de cette chaîne de la représentation de l'image qui peut être utilisée avec la fonction SQL pour trouver similaire, ou d'une autre belle façon. E. g. phash créer validation de hachages, de sorte que lorsque les deux nombres sont proches, les images doivent être proches, donc j'ai juste besoin de trouver le plus proche distances. Mais c'est encore une bibliothèque externe.
Est-il un moyen facile?
- votre idée n'était pas mauvaise, et 256 couleurs ne vous donnera pas de "petites différences". Si oui, à diminuer le nombre. Une autre question importante: votre image de hachage doit être bien assez à faire avec la petite image de la rotation.
- Une idée que j'ai juste eu à propos de la manipulation de l'image rotations dans la table de hachage est de diviser la valeur de hachage en quatre parts égales de la taille des pièces et de faire pivoter l'image, de sorte que celui avec la plus petite valeur moyenne sur le bas à gauche.
- pHash n'est pas "comparer deux images". Il calcule une valeur de hachage pour chaque image avec l'idée que les mêmes images ont les mêmes valeurs de hachage. Vous pouvez ensuite utiliser des structures de données pour stocker votre image hachages et efficacement look pour le hachage (par exemple, des images) similaire à la valeur de hachage de l'image téléchargée.
Vous devez vous connecter pour publier un commentaire.
J'ai eu ce exacte même problème avant.
N'hésitez pas à copier ce que j'ai fait, et j'espère qu'il va vous aider ou aider à résoudre votre problème.
Comment je l'ai résolu
Ma première idée qui a échoué, similaire à ce que vous pouvez penser, est j'ai fini par faire des chaînes pour chaque image (n'importe quelle taille). Mais j'ai rapidement travaillé sur ce remplit votre base de données ultra-rapide, et n'était pas efficace.
Option suivante (qui fonctionne) était une image plus petite (comme votre
5px
idée), et j'ai fait exactement cela, mais avec10px
*10px
images. La façon dont j'ai créé le "hash" pour chaque image a été laimagecolorat()
fonction.Voir php.net ici.
Lors de la réception de la
rgb
couleurs pour l'image, j'ai arrondi au plus proche50
, de sorte que les couleurs étaient moins précis. Ce nombre (50
) est ce que vous voulez changer en fonction de la façon dont spécifiques vous voulez que vos recherches.par exemple:
Après avoir fait cela à chaque pixel (
10px
*10px
vous donnera 100rgb()
de revenir), j'ai ensuite transformé en un tableau, et stockées dans la base de données commebase64_encode()
etserialize()
.Lors de la recherche d'images semblables, je n'ai exactement le même processus à l'image qu'ils voulaient à télécharger, et ensuite d'en extraire une image "hashs" à partir de la base de données de comparer tous les, et de voir ce qu'était l'appariement arrondie
rgb
's.Conseils
La Plus que
50
est dans lergb
l'arrondissement, la moins spécifiques votre recherche sera (et vice versa).Si vous voulez que votre SQL pour être plus précis, il peut être préférable de les stocker extra/spécifique info à propos de l'image dans la base de données, de sorte que vous pouvez limiter la recherche que vous obtenez dans la base de données. par exemple. si le ratio d'aspect est
4:3
, tirer uniquement des images autour de4:3
à partir de la base de données. (etc)Il peut être difficile d'obtenir cette perfection
5px
*5px
, donc une suggestion est phpthumb. Je l'ai utilisé avec la syntaxe:Bonne chance mate, j'espère que je pourrais aider.
array_unique()
fonction, cette vidé tous les doublons et m'a laissé avec seulement 28 couleurs de magasin - une moindre quantité de s'inquiéter.Pour un facile en php de mise en œuvre découvrez: https://github.com/kennethrapp/phasher
Cependant je me demande si il est natif mySql fonction "compare" (voir la classe php ci-dessus)
Je l'échelle vers le bas de l'image à 8x8 puis-je convertir RVB de 1 octet HSV donc le résultat de hachage est de 172 octets chaîne de caractères.
Il n'est pas précis à 100% (certains doublons ne sont pas disponibles), mais il fonctionne de nice et regarde comme il n'y a pas de résultats faux positifs.
De la mettre dans un académique façon, ce que vous êtes à la recherche d'une fonction de similarité qui prend dans les deux images et renvoie un indicateur de la façon dont la mesure/similaires, les deux images. Cet indicateur pourrait facilement être un nombre décimal allant de -1 à 1 (éloignés de très près). Une fois que vous avez cette fonction, vous pouvez définir une image comme une référence et la comparaison de toutes les images contre elle. Ensuite, trouver les images similaires à l'un est aussi simple que de trouver le plus proche de facteur de similitude qui est fait avec une simple recherche sur un champ double dans un SGBDR comme MySQL.
Maintenant tout ce qui reste est de savoir comment définir la fonction de similarité. Pour être honnête, ce problème est spécifique. Cela dépend de ce que vous appelez similaire. Mais la covariance est généralement un bon point de départ, il a juste besoin de vos deux images de la même taille, ce qui je pense est pas une grosse affaire. Pourtant, vous pouvez trouver beaucoup d'autres idées de la recherche pour " des mesures de similarité entre deux images.