新しいiTunes11は、アルバムの曲リストを非常によく表示し、アルバムカバーの機能でフォントと背景の色を選択します。アルゴリズムがどのように機能するかを理解した人はいますか?
7 に答える
アルバムカバーを入力として、MathematicaでiTunes11のカラーアルゴリズムを概算しました。
どうやってやったの?
試行錯誤の末、テストしたアルバムの約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}}
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
ハイライトに返す2つの色が見つからない場合(つまり、アルバムカバーがモノクロの場合)、いくつかのエッジケースが発生します。私のアルゴリズムはこれらのケースに対処していませんが、iTunesの機能を複製するのは簡単です。アルバムのハイライトが2つ未満の場合、背景との最適なコントラストに応じて、タイトルが白または黒になります。次に、曲が1つのハイライト色になるか、タイトルの色が背景に少し薄くなります。
その他の例
@ Seth-thompsonの回答と@bluedogのコメントを使用して、画像の機能で配色を生成するための小さなObjective-C(Cocoa-Touch)プロジェクトを構築します。
あなたはでプロジェクトをチェックすることができます:
https://github.com/luisespinoza/LEColorPicker
今のところ、LEColorPickerは次のことを行っています。
- 画像は36x36ピクセルに拡大縮小されます(これにより計算時間が短縮されます)。
- 画像からピクセル配列を生成します。
- ピクセル配列をYUV空間に変換します。
- Seth Thompsonのコードが行うように、色を収集します。
- 色のセットはカウントでソートされます。
- アルゴリズムは、最も支配的な3つの色を選択します。
- 最も支配的なのは背景として割り当てられています。
- 2番目と3番目に多いドミナントは、w3cカラーコントラスト式を使用してテストされ、色が背景と十分にコントラストがあるかどうかを確認します。
- テキストの色の1つがテストに合格しなかった場合、Yコンポーネントに応じて、白または黒に割り当てられます。
今のところ、ColorTunesプロジェクト(https://github.com/Dannvix/ColorTunes)とWadeCosgroveプロジェクトで新機能を確認します。また、配色の結果を改善するためのいくつかの新しいアイデアがあります。
PanicのWadeCosgroveは、iTunesのアルゴリズムに近いアルゴリズムの実装について説明した素晴らしいブログ投稿を書きました。これには、Objective-Cのサンプル実装が含まれています。
また、MMCQ(メディアンカットカラー量子化)アルゴリズムを使用しているItunesアルバムビューのHTML実装であるColorTunesをチェックアウトすることもできます。
@Sethで説明されているものとほぼ同じアルゴリズムを実装するJSライブラリを作成しました。github.com/arcanis/colibrijs、およびNPMで無料で入手できますcolibrijs
。
@Sethの回答を使用して、PHPとImagickを使用して、画像の2つの横方向の境界線でドミナントカラーを取得するアルゴリズムを実装しました。
https://gist.github.com/philix/5688064#file-simpleimage-php-L81
http://festea.com.brのカバー写真の背景を埋めるために使用されています
私は別のコンテキストで同じ質問をし、http://charlesleifer.com/blog/using-python-and-k-means-to-find-the-dominant-colors-in-images/を参照しました。画像内のランダムな開始点を使用して同じことを大まかに行う学習アルゴリズム(k Means)。このようにして、アルゴリズムはそれ自体で支配的な色を見つけます。