algorithm - это - Как работает алгоритм для раскладки списка песен в iTunes 11?




скачать itunes 11 (5)

Вы также можете https://github.com/Dannvix/ColorTunes который является HTML-реализацией представления альбома Itunes, в котором используется алгоритм MMCQ (медианный срезанный цвет квантования).

Новый iTunes 11 имеет очень приятное представление о списке песен альбома, который выбирает цвета для шрифтов и фона в функции обложки альбома. Кто-нибудь понял, как работает алгоритм?



Уэйд Косгроув из Panic написал panic.com/blog/2012/12/itunes-11-and-colors описывающий его реализацию алгоритма, который приближается к тому, что есть в iTunes. Он включает пример реализации в Objective-C.


Я задал тот же вопрос в другом контексте и был обращен к http://charlesleifer.com/blog/using-python-and-k-means-to-find-the-dominant-colors-in-images/ для алгоритм обучения (k), который делает ту же самую вещь, используя случайные стартовые точки в изображении. Таким образом, алгоритм находит доминирующие цвета сам по себе.


Я аппроксимировал цветовой алгоритм iTunes 11 в Mathematica, учитывая обложку альбома:

Как я это сделал

Сквозь проб и ошибок я придумал алгоритм, который работает на ~ 80% альбомов, с которыми я его тестировал.

Различия в цвете

Основная часть алгоритма имеет дело с поиском доминирующего цвета изображения. Однако предпосылкой для поиска доминирующих цветов является подсчет количественной разницы между двумя цветами. Одним из способов расчета разницы между двумя цветами является вычисление их евклидова расстояния в цветовом пространстве RGB. Однако восприятие цвета человека не очень хорошо сочетается с расстоянием в цветовом пространстве RGB.

Поэтому я написал функцию для преобразования цветов RGB (в форме {1,1,1} ) в YUV , цветовое пространство, которое намного лучше приближает восприятие цвета:

(EDIT: @cormullion и @Drake отметили, что встроенные цветовые пространства CIELAB и CIELUV Mathematica будут такими же подходящими ... похоже, что я немного изобрел колесо)

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
    ]

Затем я написал функцию для вычисления расстояния между цветами с приведенным выше преобразованием:

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

Доминирующие цвета

Я быстро обнаружил, что встроенная функция Mathematica DominantColors не позволяет достаточно мелкомасштабному управлению аппроксимировать алгоритм, который использует iTunes. Вместо этого я написал свою собственную функцию ...

Простым методом вычисления доминирующего цвета в группе пикселей является сбор всех пикселей в виде кодов одинаковых цветов, а затем поиск самого большого ведра.

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

Обратите внимание, что .1 - это толерантность к тому, как разные цвета должны считаться отдельными. Также обратите внимание, что хотя вход представляет собой массив пикселей в исходной форме триплета ( {{1,1,1},{0,0,0}} ), я возвращаю элемент Mathematica RGBColor чтобы лучше аппроксимировать встроенную функцию DominantColors ,

Моя фактическая функция DominantColorsNew добавляет возможность возврата до n доминирующих цветов после фильтрации другого цвета. Он также предоставляет допуски для каждого сравнения цветов:

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
    ]

Остальная часть алгоритма

Сначала я изменил размер обложки альбома ( 36px , 36px ) и уменьшил детали с помощью двустороннего фильтра

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

iTunes выбирает цвет фона, находя доминирующий цвет по краям альбома. Тем не менее, он игнорирует узкие границы обложки альбома, обрезая изображение.

thumb = ImageCrop[thumb, 34];

Затем я нашел доминирующий цвет (с новой функцией выше) вдоль самого внешнего края изображения с допуском по умолчанию .1 .

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

Наконец, я вернул 2 основных цвета в изображении в целом, сообщив функции также отфильтровать цвет фона.

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

Значения допуска, приведенные выше, следующие: .1 - минимальная разница между «отдельными» цветами; .2 - минимальная разница между многочисленными доминирующими цветами (меньшее значение может возвращать черный и темно-серый, в то время как более высокое значение обеспечивает большее разнообразие доминирующих цветов); .5 - минимальная разница между доминирующими цветами и фоном (более высокое значение даст более контрастные цветовые комбинации)

Вуаля!

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

Заметки

Алгоритм может применяться очень широко. Я изменил приведенные выше настройки и допустимые значения до такой степени, что они работают, чтобы получить в целом правильные цвета для ~ 80% обложек альбомов, которые я тестировал. Несколько краевых случаев возникают, когда DominantColorsNew не находит два цвета для подсветки (например, когда обложка альбома монохромна). Мой алгоритм не решает эти случаи, но было бы тривиально дублировать функциональность iTunes: когда альбом дает менее двух основных моментов, название становится белым или черным в зависимости от лучшего контраста с фоном. Затем песни становятся одним из выделенных цветов, если они есть, или цвет заголовка немного исчез в фоновом режиме.

Другие примеры





itunes