実現したかったもの開発したアルゴリズムの処理フローより使いやすいアルゴリズムとするために開発中につまづいたところここ最近ドミナントカラーを抽出するアルゴリズムを作っていました。この記事では実現したかったものやアルゴリズムについて、また出来上がるまでの過程を残します。実現したかったもの人間であれば直感的に画像から特徴的な色を識別することができますが、これをプログラムに置き換えられないか?と考えたのがきっかけです。SwitchのeShopではソフトごとに背景色と文字・ボタンカラーが割り振られています。キングダムの購入画面これはパッケージ画像からアルゴリズムが色を抽出してセットされる仕組みで実現されています。SwitchとWeb」という講演で任天堂によって触れられました。eShop開発秘話を聞いてきた)しかしながら、特徴色を画像から抽出するのは案外難しく、パッと思いつく下記のような方法ではうまく抽出できません。画像の全ピクセルの色(RGB値など)を平均し特徴色とする画像の各ピクセルで一番彩度が高く、輝度50%の色を特徴色とする以降は実際に作ったアルゴリズムについて記載します。今回使ってみたのはk-means法によるクラスタリングアルゴリズムです。下記のような流れで処理をしています。下記を定数として設定する。画像から各ピクセルのRGB値を抽出する。ここで、設定した許容彩度より低い彩度のピクセルは計算対象外として無視するものとする。設定したクラスタ数だけランダムな初期値(RGB値など)を設定し、初期クラスタ値とする各ピクセルのRGB値と初期クラスタ値の距離を計算し、1番近いクラスタ値のクラスタとする初期クラスタに所属する各ピクセルのRGB値の平均を計算し、新しいクラスタの値とする4~5をクラスタの値が更新されなくなるまで、あるいは定数として設定した最大ステップ数まで繰り返す1番多くのクラスタが所属するクラスタの値を特徴色とする定数の値をいじることで、彩度の高い色を特徴色として抽出させるようにしたり、クラスタリングの精度を上げたりできます。k-means法自体はクラスタリング手法の中でも基本的なもので、そのアルゴリズムも複雑でなく理解も簡単でした。(数学苦手な私でもなんとかできました。)より使いやすいアルゴリズムとするためにアルゴリズムを作っていて、まだまだ改善できるポイントがあると感じています。個人的に改良したいのは下記の項目です。:処理速度と精度のどちらを優先するかを設定できるパラメータです。処理速度優先の場合はサンプリングしたピクセルのみで特徴色を計算し、精度優先の場合はサンプリングせずに多くのピクセルを計算対象とするようなイメージです。許容彩度のパラメータとケンカする恐れがあります。:画像を見たとき、人は被写体や画像の中央など、特定のピクセルグループに視線がいくと考えられます。これを擬似的に再現する目的で、視線が行きやすいピクセルに対して重みづけをし、他のピクセルよりも計算結果に影響を与えやすくします。開発中につまづいたところ今回では許容彩度というパラメータを用意し、彩度の低いピクセルを無視するアルゴリズムとしました。これを設ける前は思うような結果が出ず2ヶ月くらい悩みました(笑)他にも画像サイズが大きい場合に、ドミナントカラー算出に時間がかかってしまうこともつまづきました。いうかまだつまづきっぱなしですが、これはサンプリングする処理を噛ませることで解決できると考えています。