ここ最近ドミナントカラーを抽出するアルゴリズムを作っていました。この記事では実現したかったものやアルゴリズムについて、また出来上がるまでの過程を残します。

実現したかったもの

人間であれば直感的に画像から特徴的な色を識別することができますが、これをプログラムに置き換えられないか?と考えたのがきっかけです。例えばこんな感じです。

アルゴリズムによって画像からドミナントカラーを抽出した画像

この記事でも触れていますが、Nintendo SwitchのeShopではソフトごとに背景色と文字・ボタンカラーが割り振られています。

背景色に水色、ボタン色に深緑色がセットされたゼルダの伝説 ティアーズ オブ ザ キングダムの購入画面の画像
背景色に水色、ボタン色に深緑色がセットされたゼルダの伝説 ティアーズ オブ ザ キングダムの購入画面

これはパッケージ画像からアルゴリズムが色を抽出してセットされる仕組みで実現されています。この話は「Nintendo SwitchとWeb」という講演で任天堂によって触れられました。(出典:Nintendo Switchの中ではReactが動いてる!Nintendo eShop開発秘話を聞いてきた

しかしながら、特徴色を画像から抽出するのは案外難しく、パッと思いつく下記のような方法ではうまく抽出できません。

以降は実際に作ったアルゴリズムについて記載します。

開発したアルゴリズムの処理フロー

今回使ってみたのはk-means法によるクラスタリングアルゴリズムです。下記のような流れで処理をしています。

  1. 下記を定数として設定する。

    • クラスタ数 :抽出する色の数
    • 許容彩度 :彩度の低いピクセルを計算対象外とするための境界変数
    • 最大ステップ数 :処理負荷が重くなりすぎないための最適化設定値
  2. 画像から各ピクセルのRGB値を抽出する。ここで、設定した許容彩度より低い彩度のピクセルは計算対象外として無視するものとする。

  3. 設定したクラスタ数だけランダムな初期値(RGB値など)を設定し、初期クラスタ値とする

  4. 各ピクセルのRGB値と初期クラスタ値の距離を計算し、1番近いクラスタ値のクラスタとする

  5. 初期クラスタに所属する各ピクセルのRGB値の平均を計算し、新しいクラスタの値とする

  6. 4~5をクラスタの値が更新されなくなるまで、あるいは定数として設定した最大ステップ数まで繰り返す

  7. 1番多くのクラスタが所属するクラスタの値を特徴色とする

定数の値をいじることで、彩度の高い色を特徴色として抽出させるようにしたり、クラスタリングの精度を上げたりできます。k-means法自体はクラスタリング手法の中でも基本的なもので、そのアルゴリズムも複雑でなく理解も簡単でした。(数学苦手な私でもなんとかできました。。)

より使いやすいアルゴリズムとするために

アルゴリズムを作っていて、まだまだ改善できるポイントがあると感じています。個人的に改良したいのは下記の項目です。

開発中につまづいたところ

今回では許容彩度というパラメータを用意し、彩度の低いピクセルを無視するアルゴリズムとしました。これを設ける前は思うような結果が出ず2ヶ月くらい悩みました(笑)

他にも画像サイズが大きい場合に、ドミナントカラー算出に時間がかかってしまうこともつまづきました。というかまだつまづきっぱなしですが、これはサンプリングする処理を噛ませることで解決できると考えています。

そのうちWebサイト化してより使いやすくしようと思っているのでお楽しみに!

参考文献

この記事の 最終更新:2023.9.7