新しいiTunes 11は、アルバムの曲リストを非常に見やすく表示し、アルバムカバーの機能でフォントと背景の色を選択します。アルゴリズムがどのように機能するかを誰もが理解しましたか?
アルバムカバーを入力として、MathematicaのiTunes 11カラーアルゴリズムを近似しました。
試行錯誤を通して、私がテストしたアルバムの〜80%で機能するアルゴリズムを思いつきました。
アルゴリズムの大部分は、画像の主要な色を見つけることを扱います。ただし、支配的な色を見つけるための前提条件は、2つの色の間の定量可能な差を計算することです。 2つの色の差を計算する1つの方法は、RGB色空間でユークリッド距離を計算することです。ただし、人間の色の知覚は、RGB色空間の距離とあまり一致しません。
したがって、RGBカラーを({1,1,1}
の形式で) YUV に変換する関数を作成しました。これは、色知覚を近似するのにはるかに優れた色空間です。
(編集: @ cormullion および @ Drake は、Mathematicaに組み込まれているCIELABおよびCIELUV色空間が同様に適切であることを指摘しました...車輪を少し再発明したように見えますここに)
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}}
)のピクセルの配列ですが、組み込みのRGBColor
関数をより良く近似するためにMathematica 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
がハイライト用に返す2色を見つけられない場合(つまり、アルバムカバーがモノクロの場合)に発生します。私のアルゴリズムはこれらのケースに対処しませんが、iTunesの機能を複製するのは簡単です。アルバムのハイライトが2つ未満になると、背景との最高のコントラストに応じてタイトルが白または黒になります。次に、曲があればハイライト色になります。またはタイトルの色が少し背景にフェードインします。
@ Seth-thompsonの回答と@bluedogのコメントを使用して、画像の機能でカラースキームを生成するための小さなObjective-C(Cocoa-Touch)プロジェクトを作成します。
プロジェクトは次の場所で確認できます。
https://github.com/luisespinoza/LEColorPicker
今のところ、LEColorPickerは次のことを行っています。
それは今のところ、ColorTunesプロジェクト( https://github.com/Dannvix/ColorTunes )とWade Cosgroveプロジェクトの新機能を確認します。また、配色結果を改善するためのいくつかの新しいアイデアがあります。
PanicのWade Cosgroveが Nice blog post を書いて、iTunesのアルゴリズムに近いアルゴリズムの実装を説明しました。 Objective-Cのサンプル実装が含まれています。
ColorTunes もチェックアウトできます。これは、MMCQ(メディアンカットカラークオンタイズ)アルゴリズムを使用しているiTunesアルバムビューのHTML実装です。
@Sethの回答では、PHPとImagickを使用して、写真の2つの横方向の境界線で主要な色を取得するアルゴリズムを実装しました。
https://Gist.github.com/philix/5688064#file-simpleimage-php-L81
http://festea.com.br のカバー写真の背景を埋めるために使用されています
@ Seth で説明されているアルゴリズムとほぼ同じアルゴリズムを実装するJSライブラリを作成しました。 github.com/arcanis/colibrijs 、およびNPMではcolibrijs
として無料で入手できます。
別のコンテキストで同じ質問をし、 http://charlesleifer.com/blog/using-python-and-k-means-to-find-the-dominant-colors-in- images / 学習アルゴリズム(k平均)の場合、画像内のランダムな開始点を使用して同じことを繰り返し行います。そのようにして、アルゴリズムはそれ自体で支配的な色を見つけます。