ITunes 11 baru memiliki tampilan yang sangat bagus untuk daftar lagu album, memilih warna untuk font dan latar belakang fungsi sampul album. Adakah yang tahu cara kerja algoritma?
ITunes 11 baru memiliki tampilan yang sangat bagus untuk daftar lagu album, memilih warna untuk font dan latar belakang fungsi sampul album. Adakah yang tahu cara kerja algoritma?
Jawaban:
Saya memperkirakan algoritma warna iTunes 11 di Mathematica mengingat sampul album sebagai input:
Melalui trial and error, saya menemukan algoritma yang bekerja pada ~ 80% dari album yang telah saya uji.
Bagian terbesar dari algoritma berkaitan dengan menemukan warna dominan dari suatu gambar. Namun, prasyarat untuk menemukan warna dominan adalah menghitung perbedaan terukur antara dua warna. Salah satu cara untuk menghitung perbedaan antara dua warna adalah dengan menghitung jarak Euclidean mereka dalam ruang warna RGB. Namun, persepsi warna manusia tidak cocok dengan jarak dalam ruang warna RGB.
Oleh karena itu, saya menulis sebuah fungsi untuk mengubah warna RGB (dalam bentuk {1,1,1}
) ke YUV , ruang warna yang jauh lebih baik dalam mendekati persepsi warna:
(EDIT: @cormullion dan @Drake menunjukkan bahwa ruang warna CIELAB dan CIELUV bawaan Mathatica akan sama sesuai ... sepertinya saya menciptakan kembali kemudi sedikit di sini)
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
]
Selanjutnya, saya menulis fungsi untuk menghitung jarak warna dengan konversi di atas:
ColorDistance[rawRGB1_, rawRGB2_] :=
EuclideanDistance[convertToYUV @ rawRGB1, convertToYUV @ rawRGB2]
Saya dengan cepat menemukan bahwa fungsi built-in Mathematica DominantColors
tidak memungkinkan kontrol berbutir halus untuk mendekati algoritma yang digunakan iTunes. Saya malah menulis fungsi saya sendiri ...
Metode sederhana untuk menghitung warna dominan dalam kelompok piksel adalah mengumpulkan semua piksel ke dalam ember warna yang sama dan kemudian menemukan ember terbesar.
DominantColorSimple[pixelArray_] :=
Module[{buckets},
buckets = Gather[pixelArray, ColorDistance[#1,#2] < .1 &];
buckets = Sort[buckets, Length[#1] > Length[#2] &];
RGBColor @@ Mean @ First @ buckets
]
Perhatikan bahwa .1
toleransi untuk perbedaan warna harus dianggap terpisah. Perhatikan juga bahwa meskipun input adalah array piksel dalam bentuk triplet mentah ( {{1,1,1},{0,0,0}}
), saya mengembalikan RGBColor
elemen Mathematica untuk lebih mendekati DominantColors
fungsi bawaan.
Fungsi saya yang sebenarnya DominantColorsNew
menambahkan opsi untuk kembali ke n
warna dominan setelah menyaring warna lain yang diberikan. Itu juga memperlihatkan toleransi untuk setiap perbandingan warna:
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
]
Pertama saya mengubah ukuran sampul album ( 36px
, 36px
) & mengurangi detail dengan filter bilateral
image = Import["http://i.imgur.com/z2t8y.jpg"]
thumb = ImageResize[ image, 36, Resampling -> "Nearest"];
thumb = BilateralFilter[thumb, 1, .2, MaxIterations -> 2];
iTunes memilih warna latar belakang dengan menemukan warna dominan di sepanjang tepi album. Namun, ia mengabaikan batas sampul album yang sempit dengan memotong gambar.
thumb = ImageCrop[thumb, 34];
Selanjutnya, saya menemukan warna dominan (dengan fungsi baru di atas) di sepanjang tepi terluar gambar dengan toleransi default .1
.
border = Flatten[
Join[ImageData[thumb][[1 ;; 34 ;; 33]] ,
Transpose @ ImageData[thumb][[All, 1 ;; 34 ;; 33]]], 1];
background = DominantColorsNew[border][[1]];
Terakhir, saya mengembalikan 2 warna dominan pada gambar secara keseluruhan, memberi tahu fungsi untuk menyaring warna latar belakang juga.
highlights = DominantColorsNew[Flatten[ImageData[thumb], 1], .1, 2, .2,
List @@ background, .5];
title = highlights[[1]];
songs = highlights[[2]];
Nilai toleransi di atas adalah sebagai berikut: .1
adalah perbedaan minimum antara warna "terpisah"; .2
adalah perbedaan minimum antara banyak warna dominan (Nilai yang lebih rendah mungkin menghasilkan abu-abu hitam dan gelap, sedangkan nilai yang lebih tinggi memastikan lebih banyak keragaman dalam warna dominan); .5
adalah perbedaan minimum antara warna dominan dan latar belakang (Nilai yang lebih tinggi akan menghasilkan kombinasi warna kontras tinggi)
Voila!
Graphics[{background, Disk[]}]
Graphics[{title, Disk[]}]
Graphics[{songs, Disk[]}]
Algoritme dapat diterapkan secara umum. Saya mengubah pengaturan dan nilai toleransi di atas ke titik di mana mereka bekerja untuk menghasilkan warna yang umumnya benar untuk ~ 80% sampul album yang saya uji. Beberapa kasus tepi terjadi ketika DominantColorsNew
tidak menemukan dua warna untuk kembali untuk highlight (yaitu ketika sampul album monokrom). Algoritme saya tidak membahas kasus-kasus ini, tetapi akan sepele untuk menduplikasi fungsionalitas iTunes: ketika album menghasilkan kurang dari dua highlight, judul menjadi putih atau hitam tergantung pada kontras terbaik dengan latar belakang. Kemudian lagu-lagu menjadi warna satu sorot jika ada satu, atau warna judul sedikit memudar ke latar belakang.
Dengan jawaban @ Seth-thompson dan komentar @bluedog, saya membangun proyek Objective-C (Cocoa-Touch) kecil untuk menghasilkan skema warna dalam fungsi gambar.
Anda dapat memeriksa proyek di:
https://github.com/luisespinoza/LEColorPicker
Untuk saat ini, LEColorPicker sedang melakukan:
Itu untuk saat ini, saya akan memeriksa proyek ColorTunes ( https://github.com/Dannvix/ColorTunes ) dan proyek Wade Cosgrove untuk fitur baru. Saya juga punya beberapa ide baru untuk meningkatkan hasil skema warna.
Wade Cosgrove dari Panic menulis posting blog yang bagus menggambarkan penerapan algoritma yang kira-kira sama dengan yang ada di iTunes. Ini termasuk implementasi sampel di Objective-C.
Anda juga dapat memeriksa ColorTunes yang merupakan implementasi HTML dari tampilan album Itunes yang menggunakan algoritma MMCQ (median cut color quantization).
Dengan jawaban @ Seth saya menerapkan algoritma untuk mendapatkan warna dominan di dua batas lateral gambar menggunakan PHP dan Imagick.
https://gist.github.com/philix/5688064#file-simpleimage-php-L81
Ini digunakan untuk mengisi latar belakang foto sampul di http://festea.com.br
Saya baru saja menulis sebuah perpustakaan JS yang mengimplementasikan algoritma yang kira-kira sama dengan yang dijelaskan oleh @Seth . Ini tersedia secara bebas di github.com/arcanis/colibrijs , dan pada NPM sebagai colibrijs
.
Saya mengajukan pertanyaan yang sama dalam konteks yang berbeda dan diarahkan ke http://charlesleifer.com/blog/using-python-and-k-means-to-find-the-dominant-colors-in-images/ untuk sebuah algoritma pembelajaran (k Berarti) yang secara kasar melakukan hal yang sama menggunakan titik awal acak dalam gambar. Dengan begitu, algoritma menemukan warna dominan dengan sendirinya.