1. ホーム

[解決済み】iTunes 11の曲リストに色をつけるアルゴリズムはどうなっているのでしょうか?[クローズド]

2022-04-19 03:09:30

質問

新しいiTunes 11では、アルバムの曲目リストに対して、アルバムカバーの機能でフォントと背景の色を選ぶという、とても素晴らしいビューが用意されています。このアルゴリズムの仕組みがわかった方はいらっしゃいますか?

解決方法は?

アルバムカバーを入力として,iTunes 11のカラーアルゴリズムをMathematica で近似してみました.

私のやり方

試行錯誤の結果、私がテストしたアルバムの約80%で動作するアルゴリズムにたどり着きました。

色の違い

アルゴリズムの大部分は、画像のドミナントカラーを見つけることを扱っています。 しかし、ドミナントカラーを見つけるための前提条件として、2つの色の定量的な差を計算することが必要です。2色の差を計算する方法の1つは、RGB色空間におけるユークリッド距離を計算することです。 しかし、人間の色覚とRGB色空間の距離感はあまり一致しません。

そこで、RGBの色を変換する関数(形式は {1,1,1} ) を YUV 色覚に近い色空間である。

<サブ (EDIT。 コーミュリオン ドレイク は,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 は、quot;separate" の色の差の最小値です。 .2 は、多数のドミナントカラーの最小の差です (低い値では黒や濃い灰色が返され、高い値ではドミナントカラーの多様性が保証されます)。 .5 は、ドミナントカラーと背景色の差の最小値です(値が大きいほど、よりコントラストの高い色の組み合わせが得られます)。

ほらね

Graphics[{background, Disk[]}]
Graphics[{title, Disk[]}]
Graphics[{songs, Disk[]}]

<イグ

注意事項

このアルゴリズムは、非常に一般的に適用することができます。 私は上記の設定と許容値を微調整して、テストしたアルバムカバーの ~80% に対して概ね正しい色を生成するようにしました。 いくつかのエッジケースは、以下の場合に発生します。 DominantColorsNew がハイライトに返す2色を見つけられなかった場合(つまり、アルバムカバーがモノクロの場合)。 私のアルゴリズムはこのようなケースには対応していませんが、iTunesの機能を複製するのは簡単でしょう。アルバムのハイライトが2色より少ない場合、タイトルは背景とのコントラストに応じて白か黒になります。 そして、曲はハイライトが1つあればその色になり、タイトル色は少し背景にフェードインします。

その他の例