Yeni iTunes 11, albüm kapağının işlevinde fontların ve arka planın renklerini seçerek bir albümün şarkı listesi için çok güzel bir görünüme sahip. Algoritmanın nasıl çalıştığını anlayan var mı?
Yeni iTunes 11, albüm kapağının işlevinde fontların ve arka planın renklerini seçerek bir albümün şarkı listesi için çok güzel bir görünüme sahip. Algoritmanın nasıl çalıştığını anlayan var mı?
Yanıtlar:
Mathematica'daki iTunes 11 renk algoritmasına yaklaşık albüm kapağı girdi olarak verildi:
Deneme yanılma yoluyla, test ettiğim albümlerin ~% 80'inde çalışan bir algoritma buldum.
Algoritmanın büyük kısmı görüntünün baskın rengini bulmakla ilgilidir. Bununla birlikte, baskın renkleri bulmak için bir ön koşul, iki renk arasında ölçülebilir bir fark hesaplamaktır. İki renk arasındaki farkı hesaplamanın bir yolu, RGB renk uzayındaki Öklid mesafelerini hesaplamaktır. Ancak, insan renk algısı RGB renk uzayındaki mesafe ile çok iyi uyuşmuyor.
Bu nedenle, RGB renklerini (formda {1,1,1}
) YUV'a dönüştürmek için bir işlev yazdım , renk algısını yaklaşık olarak belirlemede çok daha iyi bir renk alanı:
(EDIT: @cormullion ve @Drake , Mathematica'nın yerleşik CIELAB ve CIELUV renk alanlarının da aynı derecede uygun olacağını belirtti ...
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
]
Sonra, yukarıdaki dönüşüm ile renk mesafesini hesaplamak için bir işlev yazdım:
ColorDistance[rawRGB1_, rawRGB2_] :=
EuclideanDistance[convertToYUV @ rawRGB1, convertToYUV @ rawRGB2]
Yerleşik Mathematica işlevinin DominantColors
, iTunes'un kullandığı algoritmaya yaklaşmak için yeterince ince denetime izin vermediğini hemen keşfettim . Bunun yerine kendi fonksiyonumu yazdım ...
Bir piksel grubundaki baskın rengi hesaplamanın basit bir yöntemi, tüm pikselleri benzer renkteki kovalara toplamak ve daha sonra en büyük kovayı bulmaktır.
DominantColorSimple[pixelArray_] :=
Module[{buckets},
buckets = Gather[pixelArray, ColorDistance[#1,#2] < .1 &];
buckets = Sort[buckets, Length[#1] > Length[#2] &];
RGBColor @@ Mean @ First @ buckets
]
.1
Farklı renklerin nasıl ayrı ayrı düşünüleceğine tolerans olduğunu unutmayın . Ayrıca giriş, ham üçlü biçiminde ( {{1,1,1},{0,0,0}}
) bir piksel dizisi olmasına rağmen RGBColor
, yerleşik DominantColors
işleve daha iyi yaklaşmak için bir Mathematica öğesi döndürdüğümü unutmayın .
Gerçek DominantColorsNew
işlevim, n
belirli bir rengi filtreledikten sonra baskın renklere dönme seçeneği ekler . Ayrıca her bir renk karşılaştırması için toleranslar sunar:
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
]
Önce albüm kapağını ( 36px
, 36px
) yeniden boyutlandırdım ve iki taraflı bir filtreyle ayrıntıları azalttım
image = Import["http://i.imgur.com/z2t8y.jpg"]
thumb = ImageResize[ image, 36, Resampling -> "Nearest"];
thumb = BilateralFilter[thumb, 1, .2, MaxIterations -> 2];
iTunes, albümün kenarlarında baskın rengi bularak arka plan rengini seçer. Ancak, görüntüyü kırparak albüm kapağı kenarlıklarını yok sayar.
thumb = ImageCrop[thumb, 34];
Sonra, varsayılan toleransı ile görüntünün en dış kenarı boyunca baskın rengi (yukarıdaki yeni işlevle) buldum .1
.
border = Flatten[
Join[ImageData[thumb][[1 ;; 34 ;; 33]] ,
Transpose @ ImageData[thumb][[All, 1 ;; 34 ;; 33]]], 1];
background = DominantColorsNew[border][[1]];
Son olarak, bir bütün olarak görüntüde 2 baskın renk döndürdüm ve işleve arka plan rengini de filtrelemesini söyledim.
highlights = DominantColorsNew[Flatten[ImageData[thumb], 1], .1, 2, .2,
List @@ background, .5];
title = highlights[[1]];
songs = highlights[[2]];
Yukarıdaki tolerans değerleri aşağıdaki gibidir: .1
"ayrı" renkler arasındaki minimum farktır; .2
çok sayıda baskın renk arasındaki minimum farktır (daha düşük bir değer, siyah ve koyu griye dönebilirken, daha yüksek bir değer, baskın renklerde daha fazla çeşitlilik sağlar); .5
baskın renkler ve arka plan arasındaki minimum fark (Daha yüksek bir değer daha yüksek kontrastlı renk kombinasyonları verecektir)
İşte bu kadar!
Graphics[{background, Disk[]}]
Graphics[{title, Disk[]}]
Graphics[{songs, Disk[]}]
Algoritma genel olarak uygulanabilir. Yukarıdaki ayarları ve tolerans değerlerini, test ettiğim albüm kapaklarının ~% 80'i için genellikle doğru renkleri üretmek için çalıştıkları noktaya kadar değiştirdim. DominantColorsNew
Vurgulamalar için geri dönecek iki renk bulamadığında (örn. Albüm kapağı tek renkli olduğunda) birkaç kenar durumu oluşur . Algoritmam bu durumları ele almıyor, ancak iTunes'un işlevselliğini çoğaltmak önemsiz olacaktır: albüm iki vurgudan daha az vurgu yaptığında, arka planla en iyi kontrasta bağlı olarak başlık beyaz veya siyah olur. Sonra şarkılar varsa vurgulanan renk haline gelir veya başlık rengi arka plana biraz soluklaşır.
@ Seth-thompson'un cevabı ve @ bluedog'un yorumuyla, bir görüntünün işlevinde renk şemaları oluşturmak için küçük bir Objective-C (Cocoa-Touch) projesi inşa ediyorum.
Projeyi şu adresten kontrol edebilirsiniz:
https://github.com/luisespinoza/LEColorPicker
Şimdilik, LEColorPicker şunları yapıyor:
Şimdilik, yeni özellikler için ColorTunes projesini ( https://github.com/Dannvix/ColorTunes ) ve Wade Cosgrove projesini kontrol edeceğim . Ayrıca renk şeması sonucunu iyileştirmek için bazı yeni fikirlerim var.
Panic'ten Wade Cosgrove, iTunes'takine yaklaşan bir algoritma uygulamasını açıklayan güzel bir blog yazısı yazdı . Objective-C'de örnek bir uygulama içerir.
Olabilir de çıkış ColorTunes MMCQ (medyan kesim renk nicemleme) algoritması kullanan Itunes albümü görünümünün bir HTML uygulamasıdır.
@ Seth'in cevabı ile PHP ve Imagick kullanarak bir resmin iki yan kenarındaki baskın rengi elde etmek için algoritmayı uyguladım.
https://gist.github.com/philix/5688064#file-simpleimage-php-L81
Http://festea.com.br adresindeki kapak fotoğraflarının arka planını doldurmak için kullanılıyor
Sadece kabaca @Seth tarafından açıklanan algoritmayı uygulayan bir JS kütüphanesi yazdım . Github.com/arcanis/colibrijs ve NPM olarak ücretsiz olarak kullanılabilir colibrijs
.
Aynı soruyu farklı bir bağlamda sordum ve http://charlesleifer.com/blog/using-python-and-k-means-to-find-the-dominant-colors-in-images/ adresine yönlendirildi . Görüntüdeki rasgele başlangıç noktalarını kullanarak aynı şeyi yapan öğrenme algoritması (k anlamına gelir). Böylece algoritma baskın renkleri kendi başına bulur.