Bagaimana cara algoritma untuk mewarnai daftar lagu di iTunes 11 bekerja? [Tutup]

297

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?

Contoh ketiga

LuisEspinoza
sumber
9
Formula kontras warna w3c mungkin menjadi bagian dari jawabannya. Tes empiris saya sendiri menunjukkan bahwa rumus ini digunakan oleh MS Word untuk memutuskan itu font warna otomatis. Mencari "kecerahan warna ditentukan oleh rumus berikut" [W3C rumus kontras warna] [1] [1]: w3.org/TR/AERT#color-contrast
bluedog
@ Bluedog, saya pikir Anda benar. Saya mencoba banyak sampul album saya dan selalu fontnya cukup kontras dengan latar belakang untuk melihatnya dengan jelas.
LuisEspinoza
1
Hal lain yang perlu diperhatikan adalah tampaknya berbeda antara Mac OS dan Windows: twitter.com/grimfrog/status/275187988374380546
Tom Irving
2
Saya bisa membayangkan bahwa mungkin tidak hanya kuantitas warna, tetapi juga nilai saturasi mereka adalah bagian dari perhitungan: Eksperimen saya membawa saya pada kesimpulan, bahwa warna-warna highlight sering dipilih sebagai warna latar belakang meskipun mereka muncul di beberapa area gambar. Itu sebabnya saya percaya melihat histogram dari gambar sampul dan puncaknya bisa berguna, dan berdasarkan pada beberapa parameter yang disetel dengan halus, warnanya dipilih.
Raffael
2
Lihat jawaban lain di panic.com/blog/2012/12/itunes-11-and-colors
Mark Ransom

Jawaban:

423

Contoh 1

Saya memperkirakan algoritma warna iTunes 11 di Mathematica mengingat sampul album sebagai input:

Output 1

Bagaimana saya melakukannya

Melalui trial and error, saya menemukan algoritma yang bekerja pada ~ 80% dari album yang telah saya uji.

Perbedaan warna

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]

Warna Dominan

Saya dengan cepat menemukan bahwa fungsi built-in Mathematica DominantColorstidak 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 .1toleransi 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 RGBColorelemen Mathematica untuk lebih mendekati DominantColorsfungsi bawaan.

Fungsi saya yang sebenarnya DominantColorsNewmenambahkan opsi untuk kembali ke nwarna 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
    ]

Sisa Algoritma

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: .1adalah perbedaan minimum antara warna "terpisah"; .2adalah 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); .5adalah 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[]}]

Hasil akhir

Catatan

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 DominantColorsNewtidak 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.

Lebih banyak contoh

Lebih banyak contoh

Seth Thompson
sumber
3
OK @eth Thompson, sepertinya sangat menjanjikan. Saya akan mencobanya sendiri, butuh beberapa hari, harap bersabar.
LuisEspinoza
6
Solusi yang sangat mengagumkan. Sekarang perlu port dari Mathematica ke Objective-C, itu adalah perjuangan yang sulit.
loretoparisi
1
+1 untuk jawaban yang sangat terperinci ini!
Marius Schulz
1
@cormullion LUV (dan LAB) keduanya bertujuan untuk keseragaman persepsi. Namun, saya tidak menemukan referensi eksplisit untuk menggunakan jarak euclidean di kedua ruang warna. Dugaan saya adalah bahwa jika tidak ada yang lain, keduanya akan lebih baik dari RGB.
Seth Thompson
6
Inilah yang saya suka sebut "Chuck Norris Answer"
MCKapur
44

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:

  1. Gambar diskalakan ke 36x36 px (ini mengurangi waktu komputasi).
  2. Ini menghasilkan array piksel dari gambar.
  3. Mengubah array piksel ke ruang YUV.
  4. Kumpulkan warna saat kode Seth Thompson melakukannya.
  5. Set warna diurutkan berdasarkan hitungan.
  6. Algoritma memilih tiga warna yang paling dominan.
  7. Yang paling dominan adalah sebagai latar.
  8. Yang paling dominan kedua dan ketiga diuji menggunakan rumus kontras warna w3c, untuk memeriksa apakah warnanya cukup kontras dengan latar belakang.
  9. Jika salah satu warna teks tidak lulus tes, maka ditetapkan ke putih atau hitam, tergantung pada komponen Y.

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.

Tangkapan layar_Mona

LuisEspinoza
sumber
2
+1 - Hal-hal yang sangat keren, dan contoh yang bagus tentang bagaimana pengembangan algoritma dan pengembangan aplikasi keduanya dapat sangat menarik dengan sendirinya
Yuval Karmi
1
+1 untuk memeriksa kontras.
brianmearns
Ya keren tapi bagaimana Anda membulatkan nilai hash untuk setiap warna? Saya pikir saya dapat mematahkan algoritma ini dengan mudah, hanya dengan menambahkan logo "Eksplisit" hitam dan putih kecil di kanan bawah, Anda benar-benar menambahkan fokus untuk hitam dan putih. Bagaimanapun, algoritma ini akan bekerja lebih baik untuk gambar berbasis clip-art, tetapi jika Anda memiliki gambar pada 36x36 kasus-kasus gagal akan menjadi lebih jarang terjadi oleh anti-aliasing
Jack Franzen
Satu kata: FANTASTIS!
Teddy
16

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.

Mike Akers
sumber
15

Anda juga dapat memeriksa ColorTunes yang merupakan implementasi HTML dari tampilan album Itunes yang menggunakan algoritma MMCQ (median cut color quantization).

Matthias
sumber
ya saya sudah memeriksanya. Sedih tampaknya nyaris tidak didokumentasikan.
LuisEspinoza
Komentar penting dalam ColorTunes adalah referensi ke (algoritme kuantisasi cut median) [ leptonica.com/papers/mediancut.pdf] . Saya baru saja mengimplementasikan ini dalam python dalam waktu sekitar 2 jam hanya bentuk deskripsi di koran, dan lebih suka implementasi saya dari algoritma Seth di atas. Saya suka hasilnya sedikit lebih baik, tetapi yang paling penting itu sedikit lebih cepat (tentu saja, saya bisa menerapkan algoritma Seth secara tidak benar).
brianmearns
@ sh1ftst0rm apakah Anda memiliki implementasi python di github atau di suatu tempat? cheers
Anentropic
@Anentropik Maaf, saya tidak. Itu adalah bagian dari proyek pribadi yang sedang saya kerjakan, dan saya belum mengekstraknya sama sekali. Jika saya mendapat kesempatan, saya akan mencoba mempostingnya di suatu tempat, tetapi mungkin tidak akan dalam waktu dekat.
brianmearns
5

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.

Maël Nison
sumber