金箱 遼

2013.06.06

カラー検索を実装するときにぶつかった2つの壁と、その対処方法について

こんにちは。グロースハッカーの金箱です。

新サービスで実装したいなーと思って作ったカラー検索について書きます。

カラー検索とは

今回のカラー検索は、「色”を”探す」のではなくて「色”で”探す」検索です。
キレイメの画像が集まるサービスや、ファッション系ECなどで見かける機能です。

全自動でこれができたら捗るなあーと思って挑戦してみました。

ITの力で全自動カラー検索

全自動でカラー検索するシステムには、乗り越えなければいけない壁が2つ存在します。

1つは写真の中に複数の色がある中で、いったいそれは何色の画像であるかを判定することです。
もう1つは、ある色とある色が近い色だと判定するロジックです。

1.その色は何色なのか?

画像には、モノトーンの画像でない限り、複数の色が混在しています。例えば山と空が写った写真を撮った場合、その画像は何色の画像といえばいいのかという問題です。空の青なのか、山の緑なのかという問題です。

Catskill Mountain Sunset
Catskill Mountain Sunset / Justin Lowery

確実なのは人間に判断を仰ぐことです。しかし、その確実な方法をとったとしても感覚も人それぞれなので確実ではありません。
ということで、正解がない分野でもあります。

だから今回はあまり考えずに、色の平均をとるという方法を採用してみます。
ピクセルごとのRGBを抽出して、平均をとると良いでしょう。
マシンパワーが心配な人は、画像のサムネイルを作成してから平均をとる方法を使ってみてください。平均をとるピクセル数が少なくなるので、幸せになれるはずです。

ところが、単純に平均をとるだけでは良い結果が出ません。(良い結果が出る分野もあると思います)

良い結果ではない(と感じる)理由は様々あると思いますが、目立つ色や、色の位置がかなり影響を与えます。
例えば、薄いオレンジの背景にワンポイントで強い青がある場合は、青い画像だと感じるかもしれません。
また、青い背景の画像の中央に黒丸がある場合、黒い画像だと感じるかもしれません。どうしても人間は周囲の視野より、中心部の視野に強い刺激を受けるためです。

Volume red
Volume red / Rob Brewer

これらを意識して、目的に応じてチューニングする必要があります。

今回の作ったカラー検索は、被写体が比較的中央に寄りがちな画像が多かったので、特にそれを意識して、画像の中心に加重をかけた平均値を採用しました。
おおむね満足する結果を得ました。

2.視覚が感じる近い色をデジタルに処理する方法

画像の色を抽出して喜んでいたところ、次の壁にぶつかりました。
どうやって人間の視覚が近い色だと感じるのかという問題です。

はじめは簡単に、RGB空間を3次元空間としてとらえて、距離で近い色を検索する方法を採用しました。
つまり、検索したいRGBと、画像のデータベースから、単純に距離を計って近い結果を返すというロジックです。

色1(r1, g1, b1), 色2(r2, g2, b2)
距離d = √( r1 – r2 )^2 + √( g1 – g2 )^2 + √( b1 – b2 )^2

ところが、これで実行してみたところまったくいい結果が出ませんでした。
というか驚くほど悪い結果でした。

その時に気付いたのが、コンピューターが色を認識する空間(RGB)と、人間が色を認識する空間の形が異なるということです。
RGB空間を人間が眺めたときに、濃淡があるように感じるのがそれです。

RGBは、コンピューターにとっては機械的に分布している濃いも薄いもない正確に分布した空間です。一方で、人間にとっては濃淡がある(ように感じる)空間です。
つまるところ、人間の視覚の持つ色を認識する空間がゆがんでいるということです。ゆがんだ空間から見ているため、電子信号的には正確な空間が歪んで見えるわけです。

この条件下で近い色を探すのは難しい問題です。逆に、これほどまで難しい問題なら先人がチャレンジしているはずだということで、調べてみたところ発見しました。
ということで今回は、先人の知恵を借りました。ありがたいですね。

世の中には色差というジャンルがあって、きちんと体系化された学問になっています。

色差
http://en.wikipedia.org/wiki/Color_difference

色差の学問にもいろいろ派閥というかロジックが分かれているようです。
今回は「CMC l:c」と「CIEDE2000」の2つを試してみました。
いずれも、CIE LCh色空間をベースとしたモデルです。

最終的には「CIEDE2000」を採用しました。

なぜ「CIEDE2000」を採用したかというと、
こっちのほうが自分の感覚に近かったためです。
たぶん、用途や好みによって変わると思います。

どちらも、若干のチューニングをかけられるように設計されています。
「CMC l:c」の場合はlとc(lightnessとchroma、通常は1:1)
「CIEDE2000」の場合はlとcとhです。(通常は1:1:1)

今回検索したかった画像群は、暗い画像が多かったので通常の計算式にチューニングをかけました。

灰色がかった青/灰色がかった赤など暗めの画像を、青/赤に分類するべきなのか灰色に分類するべきなのかという問題への対応です。

以上2つの要素をクリアすれば、晴れてカラー検索が完成します。
カラー検索を、ユーザーに「良いものだなあ」と感じてもらうためには、2つの要素でそれぞれしっかりとチューニングをかけていく地道な作業が必須になります。
のちのち怠ける(全自動)ために、最初に苦労するのがITですよね。

というわけで、この地道な作業に共感したら、ぜひこの記事に「いいね!」をお願いします。(笑)

作る上で参考にしたサイトたち

http://colormine.org/color-converter
色の変換部分の動作が正しく動いているかの確認に大変役立ちました。

http://commons.wikimedia.org/wiki/File:Adobergb-in-cielab.png
CIELABの色空間。概念図ってのはありがたいですね。

http://en.wikipedia.org/wiki/Color_difference
色科学について学びました。