新しい iTunes 11 では、アルバムの曲リストが非常に見やすく、アルバム カバーの機能に応じてフォントや背景の色を選択できます。アルゴリズムはどのように機能するのでしょうか?
ベストアンサー1
アルバム カバーを入力として、Mathematica で iTunes 11 のカラー アルゴリズムを近似しました。
どうやってやったか
試行錯誤の結果、テストしたアルバムの約 80% で機能するアルゴリズムを思いつきました。
色の違い
アルゴリズムの大部分は、画像の主要な色を見つけることです。ただし、主要な色を見つけるための前提条件は、2 つの色間の定量化可能な差を計算することです。2 つの色間の差を計算する 1 つの方法は、RGB 色空間でユークリッド距離を計算することです。ただし、人間の色覚は、RGB 色空間での距離とあまり一致しません。
そこで、RGBカラー(形式{1,1,1}
)を次のように変換する関数を作成しました。ユーブイ、色の知覚をより正確に近似する色空間です。
(編集:@コルマリオンそして@ドレイク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
は、異なる色を別々に見なすために必要な許容範囲であることに注意してください。また、入力は生のトリプレット形式 ( )のピクセル配列ですが、組み込み関数をより正確に近似するために、Mathematica 要素を{{1,1,1},{0,0,0}}
返すことにも注意してください。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 つ未満の場合、タイトルは背景との最適なコントラストに応じて白または黒になります。次に、曲がハイライト色 (ある場合) になるか、タイトル色が背景に少し溶け込みます。