2009-11-10 4 views
5

Supposons qu'il existe 10 000 images JPEG, PNG dans une galerie, comment trouver toutes les images avec des palettes de couleurs similaires à une image sélectionnée triée par similarité décroissante?Trouver des images avec une palette de couleurs similaire avec Python

+2

double possible: http://stackoverflow.com/questions/593925/how-do-i-find-images-with-a -similar-color-using-python-and-pil – ChristopheD

+0

Oui, mais il n'y a pas de bonnes réponses à cette question. :-) –

+0

Il ya beaucoup de discussion similaire ici: http://stackoverflow.com/questions/1034900/near-duplicate-image-detection/1048723#1048723 – Paul

Répondre

10

Construire un histogramme de couleur pour chaque image. Ensuite, lorsque vous voulez faire correspondre une image à la collection, il vous suffit de classer la liste en fonction de la proximité de l'histogramme par rapport à l'histogramme de l'image sélectionnée.

Le nombre de compartiments dépend de la précision que vous souhaitez obtenir. Le type de données combinées pour créer un compartiment définira la manière dont vous priorisez votre recherche.

Par exemple, si vous êtes plus intéressé par la teinte, vous pouvez définir lequel des compartiments votre chaque pixel de l'image passe en tant que:

def bucket_from_pixel(r, g, b): 
    hue = hue_from_rgb(r, g, b) # [0, 360) 
    return (hue * NUM_BUCKETS)/360 

Si vous voulez aussi un matcher général, vous pouvez Choisissez le godet en fonction de la valeur RVB complète.

En utilisant PIL, vous pouvez utiliser la fonction histogram intégrée. Les histogrammes de "proximité" peuvent être calculés en utilisant n'importe quelle mesure de distance que vous voulez. Par exemple, une distance L1 pourrait être:

hist_sel = normalize(sel.histogram()) 
hist = normalize(o.histogram()) # These normalized histograms should be stored 

dist = sum([abs(x) for x in (hist_sel - hist)]) 

un L2 serait:

dist = sqrt(sum([x*x for x in (hist_sel - hist)])) 

Normalize oblige la somme de l'histogramme pour égaler une valeur constante (1.0 fonctionne très bien). Ceci est important pour que les grandes images puissent être comparées correctement aux petites images. Si vous utilisez les distances L1, vous devez utiliser une mesure L1 au normalize. Si L2, alors L2.

+0

@Frank, merci pour vos conseils. Pourriez-vous me donner un exemple de code en Python? La fonction intégrée histogram() de PIL renvoie une liste, comment déterminer la proximité des histogrammes de deux images? – jack

+0

@Frank, on dirait qu'il faut 10 000 calculs de distance lors de la sélection d'images avec un histogramme similaire sur 10 000 candidats? est-il possible d'associer des valeurs numériques à chaque image et de les stocker dans la base de données ainsi la comparaison peut être simplifiée à quelques requêtes sql? – jack

+0

@jack, 10,000 calcs n'est pas vraiment si cher. La meilleure façon d'accélérer le code n'est pas de réduire les histogrammes en nombres entiers (ce qui ne peut pas être fait comme vous le pensez) mais simplement de ** mettre en cache ** les résultats. Mettre en cache l'ordre de tri (par image) dans la base de données ou le mettre en mémoire cache. Assurez-vous également de stocker l'histogramme dans la base de données ou dans la mémoire afin que la reconstruction de ces caches d'ordre de tri ne soit pas coûteuse. –

Questions connexes