web-dev-qa-db-fra.com

Moyen rapide d'obtenir la couleur dominante d'une image

J'ai une question sur la façon d'obtenir la couleur dominante d'une image (une photo). J'ai pensé à cet algorithme: parcourir tous les pixels et obtenir leur couleur, soit rouge, vert, jaune, orange, bleu, magenta, cyan, blanc, gris ou noir (avec une certaine marge bien sûr) et c'est l'obscurité (clair, sombre ou normal) et vérifiez ensuite quelles couleurs se sont le plus produites. Je pense que c'est lent et pas très précis. Y a-t-il une meilleure façon?


Si cela est important, il s'agit d'un UIImage provenant d'un appareil photo iPhone ou iPod touch qui est au maximum de 5 Mpx. La raison pour laquelle cela doit être rapide est que le simple fait de montrer un indicateur de progression n'a pas beaucoup de sens, car il s'agit d'une application pour les personnes malvoyantes, ou pas du tout. Parce que c'est pour un appareil mobile, cela peut ne pas prendre beaucoup de mémoire (au plus 50 Mo).

34
user142019

Votre approche générale devrait fonctionner, mais je voudrais souligner certains détails.

Au lieu de votre liste de couleurs donnée, générez un certain nombre de "bacs" de couleurs dans le spectre de couleurs pour compter les pixels. Voici une autre question qui a des algorithmes pour cela: Génération de palettes de couleurs de spectre Rendez le nombre de bacs configurable, afin que vous puissiez expérimenter pour obtenir les résultats que vous voulez.

Ensuite, pour chaque pixel que vous envisagez, vous devez trouver le bac de couleur "le plus proche" à incrémenter. Vous devrez définir "le plus proche"; voir cet article sur la "différence de couleur": http://en.wikipedia.org/wiki/Color_difference

Pour des performances, vous n'avez pas besoin de regarder chaque pixel. Étant donné que les éléments d'image couvrent généralement de grandes zones (par exemple, le ciel, l'herbe, etc.), vous pouvez obtenir le résultat souhaité en n'échantillonnant que quelques pixels. Je suppose que vous pourriez obtenir de bons résultats en échantillonnant tous les 10 pixels, voire tous les 100. Vous pouvez également expérimenter avec ce facteur.

[Note de l'éditeur: le paragraphe ci-dessous a été modifié pour tenir compte du commentaire de Mike Fairhurst.]

La moyenne des pixels peut également être effectuée, comme dans cette démo: jsfiddle.net/MUsT8/

30
payne