やりたいことは、Aの色(たとえば#B97640)とBの色(たとえば#660066)が「似た色かどうか」を判定したいです。
それぞれをhexdecなどでRGBに変換し、数値の差を求めたりしてみたのですが、なかなか似た色かどうかを判定できません。
最終的に作りたいのは、Color extract(http://www.phpclasses.org/browse/package/3370.html)
というclassを使って画像内で最も使用されている色を抽出し、任意に指定した色のカテゴリ(赤、青、黄などの基本色)へ自動的に振り分けるようなものです。
なにか良い方法をご存知でしたらお教えいただけると助かります。
RGB表色系(色空間)から均等色空間の実装のひとつである、CIELAB表色系へ変換の上、
CIE L*a*b*色空間上での距離(差分の二乗和)を求める。
sRGBからCIELABへの変換(javaでの実装例)
RGBではなく、HSVで比較するのはいかがでしょうか。
HSV色空間
http://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93
RGBはコンピュータや電子回路にとって処理しやすい色空間ですが、人間の感覚とは異なります。なので「同じ色」という人間の感覚の比較をするには不向きな色空間です。
比してHSVは色相(Hue)、彩度(Saturation)、明度(Value)という人間の感覚に近い色空間です。そのうち、色相(Hue) が近い値であれば近似色です。
上記のWikipediaにも出ていますがRGBとHSVの変換は容易です。下記URLにRGBをHSVに変換するPHPコードがあるのでご参考になると思います。
PHPとMySQLを用いてカラー情報から画像を検索するプログラムを作成しました(ソース付き)
ありがとうございます。
なるほどHSVなら近似値が求めやすいんですね。
抽出をDBで行うというのは頭にありませんでした。
大変勉強になります。
【追記】
RGBでの比較やHSVでの比較でいろいろと試してみましたが、
やはり完全に似た色を抽出するのは難しいようで、全く似てない色も抽出されることがあります。
(たとえば「#404040(やや薄い黒)」は「#000000(黒)」より「#660066(紫)」に近いと判定される)
QuphondiさんのアプリケーションはRGBのみで比較されているようですが、うまく抽出されているようですね・・・
他に良いアイデアやサンプルをお持ちの方はいませんでしょうか。
>たとえば「#404040(やや薄い黒)」は「#000000(黒)」より「#660066(紫)」に近いと判定される
試してみましたがそのような結果にはならないようですが
// #404040
array(3) {
["h"]=>
int(0)
["s"]=>
int(0)
["v"]=>
string(2) "40"
}
// #000000
array(3) {
["h"]=>
int(0)
["s"]=>
int(0)
["v"]=>
string(2) "00"
}
// #660066
array(3) {
["h"]=>
int(300)
["s"]=>
int(1)
["v"]=>
string(2) "66"
}
検証ありがとうございます。
HSVで判定した場合はうまくいく色もあるのですが、RGBでないと「近い」と判断しにくい場合もあるようです。
このあたりは一長一短のようで・・・。
RGBとHSVを組み合わせれば、ある程度絞れるかもしれないと思い模索中です。
念のためもう少し回答を受け付けてみます。
すみません。javaはまったくわからないもので・・・
PHPでの例をお教えいただけると助かります。