新しいiTunes 11には、アルバムの曲リストを表示する非常に優れたビューがあり、アルバムカバーの機能でフォントと背景の色を選択します。誰かがアルゴリズムがどのように機能するかを理解しましたか?
新しい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
、組み込みDominantColors
関数をより適切に近似するためにMathematica 要素を返します。
私の実際の機能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の機能を複製するのは簡単です。次に、曲がある場合は1つのハイライトカラーになるか、タイトルの色が背景に少しフェードします。
@ Seth-thompsonの回答と@bluedogのコメントを使用して、小さなObjective-C(Cocoa-Touch)プロジェクトを構築し、画像の機能でカラースキームを生成します。
プロジェクトは次の場所で確認できます。
https://github.com/luisespinoza/LEColorPicker
今のところ、LEColorPickerは次のことを行っています:
今のところ、ColorTunesプロジェクト(https://github.com/Dannvix/ColorTunes)とWade Cosgroveプロジェクトの新機能を確認します。また、配色結果を改善するための新しいアイデアもいくつかあります。
パニックのウェイドコスグローヴは、iTunesでのアルゴリズムに近似するアルゴリズムの彼の実装を説明する素晴らしいブログ投稿を書きました。Objective-Cのサンプル実装が含まれています。
また、MMCQ(メディアンカットカラークオンタイズ)アルゴリズムを使用しているItunesアルバムビューのHTML実装であるColorTunesをチェックアウトすることもできます。
@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平均)。このようにして、アルゴリズムはドミナントカラーを自動的に見つけます。