297 votes

Comment fonctionne l’algorithme pour colorer la liste des chansons dans iTunes 11 ?

Le nouvel iTunes 11 a une très belle vue de la liste des morceaux d’un album, choisir les couleurs pour les polices et l’arrière-plan en fonction de la couverture de l’album. Tout le monde figuré dehors comment l’algorithme fonctionne ?

Third Example

423voto

Seth Thompson Points 2236

Example 1

Je l'ai approchée de l'iTunes 11 de la couleur de l'algorithme dans Mathematica, compte tenu de la couverture de l'album en entrée:

Output 1

Comment je l'ai fait

Par essai et erreur, je suis venu avec un algorithme qui fonctionne sur ~80% des albums avec qui je l'ai testé.

Les Différences De Couleur

La majeure partie de l'algorithme traite de la recherche de la couleur dominante de l'image. Une condition préalable à la constatation de couleurs dominantes, cependant, est le calcul d'une différence quantifiable entre les deux couleurs. Une façon de calculer la différence entre deux couleurs est de calculer leur distance Euclidienne dans l'espace de couleurs RVB. Cependant, la perception humaine de la couleur ne correspond pas très bien avec la distance dans l'espace de couleurs RVB.

Donc, j'ai écrit une fonction pour convertir des couleurs RGB ( {1,1,1}) YUV, un espace de couleur qui est beaucoup mieux à rapprocher de la perception des couleurs:

(EDIT: @cormullion et @Drake a souligné que Mathematica intégré dans CIELAB et CIELUV espaces de couleurs serait tout aussi approprié... regarde comme je l'ai réinventé la roue, un peu ici)

convertToYUV[rawRGB_] :=
    Module[{yuv},
        yuv = {{0.299, 0.587, 0.114}, {-0.14713, -0.28886, 0.436},
            {0.615, -0.51499, -0.10001}};
        yuv . rawRGB
    ]

Ensuite, j'ai écrit une fonction pour calculer la couleur de la distance avec le dessus de la conversion:

ColorDistance[rawRGB1_, rawRGB2_] := 
    EuclideanDistance[convertToYUV @ rawRGB1, convertToYUV @ rawRGB2]

Couleurs Dominantes

J'ai rapidement découvert que le construit en fonction de Mathematica DominantColors n'a pas assez de contrôle fin de l'approximation de l'algorithme utilisé par iTunes. J'ai écrit ma propre fonction de la place...

Une méthode simple pour calculer la couleur dominante dans un groupe de pixels est de collecter tous les pixels dans des seaux de couleurs similaires et ensuite trouver le plus grand seau.

DominantColorSimple[pixelArray_] :=
    Module[{buckets},
        buckets = Gather[pixelArray, ColorDistance[#1,#2] < .1 &];
        buckets = Sort[buckets, Length[#1] > Length[#2] &];
        RGBColor @@ Mean @ First @ buckets
    ]

Notez que .1 est la tolérance pour combien de couleurs différentes doit être considéré comme distinct. Notez également que même si l'entrée est un tableau de pixels en raw, triplet de la forme ({{1,1,1},{0,0,0}}), je reviens un Mathematica RGBColor élément afin de mieux reproduire le haut- DominantColors fonction.

Ma fonction réelle DominantColorsNew ajoute la possibilité de retourner jusqu'à n couleurs dominantes après le filtrage une autre couleur. Il expose également les tolérances pour chaque couleur de comparaison:

DominantColorsNew[pixelArray_, threshold_: .1, n_: 1, 
    numThreshold_: .2, filterColor_: 0, filterThreshold_: .5] :=
    Module[
        {buckets, color, previous, output},
        buckets = Gather[pixelArray, ColorDistance[#1, #2] < threshold &];
        If[filterColor =!= 0, 
        buckets = 
            Select[buckets, 
                ColorDistance[ Mean[#1], filterColor] > filterThreshold &]];
        buckets = Sort[buckets, Length[#1] > Length[#2] &];
        If[Length @ buckets == 0, Return[{}]];
        color = Mean @ First @ buckets;
        buckets = Drop[buckets, 1];
        output = List[RGBColor @@ color];
        previous = color;
        Do[
            If[Length @ buckets == 0, Return[output]];
            While[
                ColorDistance[(color = Mean @ First @ buckets), previous] < 
                    numThreshold, 
                If[Length @ buckets != 0, buckets = Drop[buckets, 1], 
                    Return[output]]
            ];
            output = Append[output, RGBColor @@ color];
            previous = color,
            {i, n - 1}
        ];
        output
    ]

Le Reste de l'Algorithme

D'abord j'ai redimensionné la couverture de l'album (36px, 36px) et réduit en détail avec un filtre bilatérale

image = Import["http://i.imgur.com/z2t8y.jpg"]
thumb = ImageResize[ image, 36, Resampling -> "Nearest"];
thumb = BilateralFilter[thumb, 1, .2, MaxIterations -> 2];

iTunes sélectionne la couleur d'arrière-plan par trouver la couleur dominante le long des bords de l'album. Toutefois, il ignore étroite de la couverture de l'album frontières par le recadrage de l'image.

thumb = ImageCrop[thumb, 34];

Ensuite, j'ai trouvé la couleur dominante (avec la nouvelle fonction ci-dessus) le long du bord extérieur de l'image avec une tolérance par défaut de .1.

border = Flatten[
    Join[ImageData[thumb][[1 ;; 34 ;; 33]] , 
        Transpose @ ImageData[thumb][[All, 1 ;; 34 ;; 33]]], 1];
background = DominantColorsNew[border][[1]];

Enfin, je suis retourné 2 couleurs dominantes dans l'ensemble d'une image, en disant à la fonction de filtre de la couleur d'arrière-plan.

highlights = DominantColorsNew[Flatten[ImageData[thumb], 1], .1, 2, .2, 
    List @@ background, .5];
title = highlights[[1]];
songs = highlights[[2]];

Les valeurs de la tolérance ci-dessus sont comme suit: .1 est le minimum de différence entre les "séparer" les couleurs; .2 est la différence minimale entre de nombreuses couleurs dominantes (Une valeur plus faible peut retourner en noir et gris foncé, tandis qu'une valeur plus élevée assure une plus grande diversité dans les couleurs dominantes); .5 est le minimum de différence entre les couleurs dominantes et l'arrière-plan (Une valeur supérieure à rendement élevé-couleur de contraste combinaisons)

Voila!

Graphics[{background, Disk[]}]
Graphics[{title, Disk[]}]
Graphics[{songs, Disk[]}]

Final Output

Notes

L'algorithme peut être appliqué de manière très générale. J'ai modifié les paramètres ci-dessus et les valeurs de la tolérance à l'endroit où ils travaillent pour produire généralement de corriger les couleurs pour ~80% de l'album couvre que j'ai testé. Quelques cas se produire lors de l' DominantColorsNew ne trouve pas de deux couleurs pour le retour, les faits saillants (c'est à dire lorsque la couverture de l'album est monochrome). Mon algorithme ne tient pas compte de ces cas, mais il serait difficile à reproduire iTunes fonctionnalités: quand l'album des rendements de moins de deux points forts, le titre devient blanc ou noir selon le meilleur contraste avec le fond. Puis les chansons sont devenues l'un couleur de surbrillance si il y en a un, ou la couleur du titre de la estompe un peu.

D'Autres Exemples

More Examples

44voto

LuisEspinoza Points 4917

Avec la réponse de @Seth-thompson et le commentaire de @bluedog, j'ai construit un peu Objective-C (Cacao-Touch) projet de générer des schémas de couleurs en fonction d'une image.

Vous pouvez consulter le projet :

https://github.com/luisespinoza/LEColorPicker

Pour l'instant, LEColorPicker est en train de faire:

  1. L'Image est redimensionnée à 36x36 px (dans le but de réduire le temps de calcul).
  2. Il génère un réseau de pixels de l'image.
  3. Convertit le réseau de pixels à l'entrée YUV de l'espace.
  4. Recueillir des couleurs que Seth Thompson code ne.
  5. La couleur du jeux sont triés par le comte.
  6. L'algorithme de sélectionner les trois couleurs dominantes.
  7. Le plus dominant est asigned comme arrière-plan.
  8. Les deuxième et troisième plus dominantes sont testés à l'aide de la w3c contraste des couleurs de la formule, afin de vérifier si les couleurs a assez de contraste avec le fond.
  9. Si l'une des couleurs de texte ne passe pas le test, alors il est asigned à blanc ou noir, en fonction de la composante y.

Qui est pour maintenant, je vais vérifier la ColorTunes projet (https://github.com/Dannvix/ColorTunes) et les Wade Cosgrove projet pour de nouvelles fonctionnalités. Aussi, j'ai quelques nouvelles idées pour améliorer le schéma de couleur de résultat.

Screenshot_Mona

16voto

Mike Akers Points 4866

Wade Cosgrove de panique a écrit un post de blog sympa décrivant son implémentation d’un algorithme qui se rapproche de celui d’iTunes. Il inclut un exemple d’implémentation en Objective-C.

15voto

Matthias Points 353

Vous pouvez également commander ColorTunes qui est une implémentation de HTML de l’affichage d’album Itunes qui utilise l’algorithme de MMCQ (quantification de couleur coupe médiane).

5voto

philix Points 479

Réponse de @Seth j’ai implémenté l’algorithme pour obtenir la couleur dominante dans les deux bordures latérales d’une image à l’aide de PHP et Imagick.

https://GIST.github.com/philix/5688064#file-SimpleImage-php-L81

Il est utilisé pour remplir l’arrière-plan de photos de la couverture en http://festea.com.br

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