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




айтюнс это (7)

С ответом @ Seth-thompson и комментарием @bluedog я создаю небольшой проект Objective-C (Cocoa-Touch) для создания цветовых схем в функции изображения.

Вы можете проверить проект по адресу:

https://github.com/luisespinoza/LEColorPicker

Пока что LEColorPicker делает:

  1. Изображение масштабируется до 36x36 px (это уменьшает время вычисления).
  2. Он генерирует пиксельный массив из изображения.
  3. Преобразует пиксельный массив в пространство YUV.
  4. Соберите цвета, как это делает код Сета Томпсона.
  5. Наборы цветов сортируются по счету.
  6. Алгоритм выбирает три наиболее доминирующих цвета.
  7. Наиболее доминирующим является имя фона.
  8. Второе и третье большинство доминантов тестируются с использованием формулы цветового контраста w3c, чтобы проверить, достаточно ли цвета иметь контраст с фоном.
  9. Если один из цветов текста не проходит тест, он присваивается белым или черным, в зависимости от компонента Y.

На данный момент я буду проверять проект ColorTunes ( https://github.com/Dannvix/ColorTunes ) и проект Wade Cosgrove для новых функций. Также у меня есть несколько новых идей для улучшения результата цветовой схемы.

Новый 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: когда альбом дает менее двух основных моментов, название становится белым или черным в зависимости от лучшего контраста с фоном. Затем песни становятся одним из выделенных цветов, если они есть, или цвет заголовка немного исчез в фоновом режиме.

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


Я просто написал JS-библиотеку, реализующую примерно тот же алгоритм, который описан в @Seth . Он свободно доступен на github.com/arcanis/colibrijs , а на NPM - на colibrijs .


Из того, что я понимаю

Функция возвращает значение, находящееся в домене, сопоставляя n элементов с одним членом домена.

Предикат подтверждает, является ли отношение, которое вы пытаетесь сделать, истинно или нет в соответствии с аксиомами и правилами вывода, которые вы выполняете в своей системе.





algorithm user-interface itunes