Jak działa algorytm kolorowania listy utworów w iTunes 11? [zamknięte]

Nowy iTunes 11 ma bardzo ładny widok na listę utworów albumu, wybierając kolory czcionek i tła w funkcji okładki albumu. Ktoś wie, jak działa algorytm?

Trzeci Przykład

Author: LuisEspinoza, 2012-11-30

7 answers

Przykład 1

Porównałem algorytm kolorów iTunes 11 w Mathematica, biorąc pod uwagę okładkę albumu jako wejście:

Wyjście 1

Jak to zrobiłem

Metodą prób i błędów wymyśliłem algorytm, który działa na ~80% płyt, z którymi go testowałem.

Różnice Kolorów

Większość algorytmu zajmuje się znalezieniem dominującego koloru obrazu. Warunkiem znalezienia dominujących kolorów jest jednak obliczenie wymiernej różnica między dwoma kolorami. Jednym ze sposobów obliczania różnicy między dwoma kolorami jest obliczenie ich odległości euklidesowej w przestrzeni kolorów RGB. Jednak postrzeganie kolorów przez człowieka nie pasuje zbyt dobrze do odległości w przestrzeni kolorów RGB.

Dlatego napisałem funkcję konwersji kolorów RGB (w postaci {1,1,1}) do YUV , przestrzeni kolorów, która jest znacznie lepsza w przybliżaniu percepcji kolorów:

(EDIT: @cormullion and @Drake wskazał, że wbudowane Przestrzenie Kolorów CIELAB i CIELUV Mathematica byłyby równie odpowiednie... wygląda na to, że zmieniłem trochę koło tutaj)

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
    ]

Następnie napisałem funkcję do obliczania odległości kolorów z powyższą konwersją:

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

Kolory Dominujące

Szybko odkryłem, że wbudowana funkcja Mathematica DominantColors nie pozwala na wystarczającą kontrolę drobnoziarnistą, aby zbliżyć algorytm, którego używa iTunes. Napisałem własną funkcję zamiast tego...

Prostą metodą obliczania koloru dominującego w grupie pikseli jest zebranie wszystkich pikseli w wiadra o podobnych kolorach, a następnie znalezienie największego wiadra.

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

Należy zauważyć, że .1 jest tolerancją dla tego, jak różne kolory muszą być uważane za oddzielne. Zauważ również, że chociaż wejście jest tablicą pikseli w postaci raw triplet ({{1,1,1},{0,0,0}}), zwracam element Mathematica RGBColor, aby lepiej zbliżyć wbudowany DominantColors funkcja.

Moja rzeczywista funkcja DominantColorsNew dodaje opcję powrotu do dominujących kolorów n po odfiltrowaniu danego innego koloru. Wyświetla również tolerancje dla każdego porównania kolorów:

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
    ]

Reszta algorytmu

Najpierw zmieniłem rozmiar okładki albumu(36px, 36px) & redukcja szczegółów dzięki dwustronnemu filtrowi

image = Import["http://i.imgur.com/z2t8y.jpg"]
thumb = ImageResize[ image, 36, Resampling -> "Nearest"];
thumb = BilateralFilter[thumb, 1, .2, MaxIterations -> 2];
ITunes wybiera kolor tła, znajdując kolor dominujący wzdłuż krawędzi albumu. Jednak ignoruje wąskie granice okładki albumu przez przycięcie obrazu.
thumb = ImageCrop[thumb, 34];

Następnie znalazłem kolor dominujący (z nową funkcją powyżej) wzdłuż zewnętrznej krawędzi obrazu z domyślną tolerancją .1.

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

Na koniec zwróciłem 2 dominujące kolory na obrazie jako całości, mówiąc funkcji, aby odfiltrować kolor tła, jak również.

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

Powyższe wartości tolerancji są następujące: .1 jest minimalną różnicą między" oddzielnymi " kolorami; .2 jest minimalna różnica między wieloma dominującymi kolorami (niższa wartość może zwracać czerń i ciemnoszary, podczas gdy wyższa wartość zapewnia większą różnorodność kolorów dominujących); .5 jest minimalną różnicą między dominującymi kolorami a tłem (wyższa wartość daje kombinacje kolorów o wyższym kontraście)

Voila!

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

Wynik Końcowy

Uwagi

Algorytm może być stosowany bardzo ogólnie. Poprawiłem powyższe ustawienia i tolerancję wartości do punktu, w którym pracują, aby uzyskać ogólnie poprawne kolory dla ~80% okładek płyt, które testowałem. Kilka przypadków krawędziowych występuje, gdy DominantColorsNew nie znajdzie dwóch kolorów, aby powrócić do podświetlenia (np. gdy okładka albumu jest Monochromatyczna). Mój algorytm nie odnosi się do tych przypadków, ale byłoby trywialne powielić funkcjonalność iTunes: gdy album daje mniej niż dwa highlights, tytuł staje się biały lub czarny w zależności od najlepszego kontrastu z tłem. Potem piosenki staje się jedynym kolorem podświetlenia, jeśli istnieje, lub kolor tytułu wyblakł nieco w tle.

Więcej Przykładów

Więcej Przykładów

 420
Author: Seth Thompson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:50

Z odpowiedzią @Seth-thompson i komentarzem @ bluedog, buduję mały projekt Objective - C (Cocoa-Touch) do generowania schematów kolorów w funkcji obrazu.

Możesz sprawdzić projekt pod adresem:

Https://github.com/luisespinoza/LEColorPicker

Na razie LEColorPicker robi:

  1. obraz jest skalowany do 36x36 px (skraca to czas obliczeń).
  2. generuje tablicę pikseli z obrazu.
  3. konwertuje tablicę pikseli na YUV space.
  4. Zbieraj kolory tak, jak robi to kod Setha Thompsona.
  5. zestawy kolorów są sortowane według liczby.
  6. algorytm wybiera trzy najbardziej dominujące kolory.
  7. najbardziej dominujący jest przypisany jako tło.
  8. druga i trzecia większość dominantów są testowane przy użyciu formuły kontrastu kolorów w3c, aby sprawdzić, czy kolory mają wystarczająco duży kontrast z tłem.
  9. Jeśli jeden z kolorów tekstu nie przejdzie testu, jest przypisany do białego lub czarnego, w zależności od elementu Y.

Na razie będę sprawdzał projekt ColorTunes ( https://github.com/Dannvix/ColorTunes ) i projekt Wade Cosgrove dla nowych funkcji. Mam też kilka nowych pomysłów na poprawę wyniku kolorystycznego.

Screenshot_Mona

 44
Author: LuisEspinoza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-12 03:57:26

Wade Cosgrove z Panic napisał ładny post na blogu opisujący jego implementację algorytmu zbliżonego do tego w iTunes. Zawiera przykładową implementację w Objective-C.

 16
Author: Mike Akers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-11 20:43:50

Możesz również sprawdzić ColorTunes, która jest HTML implementacją widoku albumu Itunes, która wykorzystuje algorytm MMCQ (median cut color quantization).

 15
Author: Matthias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-09 22:03:37

Z odpowiedzią @ Seth zaimplementowałem algorytm, aby uzyskać kolor dominujący w dwóch bocznych granicach obrazu za pomocą PHP i Imagick.

Https://gist.github.com/philix/5688064#file-simpleimage-php-L81

Służy do wypełniania tła okładek zdjęć w http://festea.com.br

 5
Author: philix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-04 17:58:08

Właśnie napisałem bibliotekę JS implementującą mniej więcej ten sam algorytm, który opisany przez @Seth. Jest on dostępny bezpłatnie na github.com/arcanis/colibrijs , a na NPM jako colibrijs.

 5
Author: Maël Nison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:14

Zadałem to samo pytanie w innym kontekście i zostałem skierowany do http://charlesleifer.com/blog/using-python-and-k-means-to-find-the-dominant-colors-in-images/ dla algorytmu uczenia się (k oznacza), który rougly robi to samo, używając losowych punktów początkowych na obrazie. W ten sposób algorytm sam znajdzie dominujące kolory.

 4
Author: thomi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-07 04:29:10