100) $u = 100; # 解析にかかった時間 $dt = ''; # とりあえず拡張子で画像を判別する if (preg_match("/\.(gif|jpe?g|png)$/i",$url)) { # 画像を取得 $img = @file_get_contents($url,FILE_BINARY); # 解析にかかる時間を測定するため現在の時刻をマイクロ秒まで取得。 $t = microtime(true); # 解析をして情報を取得。$thresholdを0にしているので解析後のカラーは全て取得。 $ratios = analyze($img,$u,0); # 解析にかかった時間を算出。 $dt = microtime(true) - $t; # サンプルの取得パターンを生成 $pattern = getPattern($img,$u); } # 解析 # 今回の方法は、画像中心から放射状に16方向に、半径を刻み$uで増やして調べていく。 # これは商品などは画像の中央に写っている場合を想定していて、 # 風景などの写真は格子状にサンプルをとってきたほうがいい。 # デフォルトはサンプル全体の10%以上の占有率を持つ色を抽出。 function analyze(&$img,$u,$threshold=0.1) { $o = new Imagick(); $o->readImageBlob($img); $u += 2; $numbers = array(); $ratios = array(); $c = array($o->getImageWidth()/2,$o->getImageHeight()/2); $R = min($c) - 5; for ($r=$R/$u/2;$r<$R-$R/$u;$r+=$R/$u) { for ($Q=0;$Q<2*M_PI;$Q+=M_PI/8) { $rgb = rgb($o,round($c[0]+$r*cos($Q)),round($c[1]+$r*sin($Q))); if ($rgb!='') $numbers[$rgb]++; } } if ($numbers) { $sum = array_sum(array_values($numbers)); foreach ($numbers as $rgb=>$v) if ($v/$sum>=$threshold) $ratios[$rgb] = $v/$sum; } return $ratios; } # 画像上の位置(x,y)のカラー情報を量子化して取得 # 取得したそれぞれの色で4段階で量子化。実際の使用では適切化が必要。 function rgb(&$o,$x,$y) { $p = $o->getImagePixelColor($x,$y)->getColor(); # 真っ白と真っ黒は除外(自然界には存在しない色と仮定) return is_artificial($p) ? '' : quantize($p['r'],4).quantize($p['g'],4).quantize($p['b'],4); } # 量子化 function quantize($o,$n) { return sprintf("%02X",(128+256*floor($o*$n/256))/$n); } # 真っ白(白トビや#FFFFFF)と真っ黒(#000000)を判別 function is_artificial(&$o) { $sum = array_sum($o) - $o['a']; return ( !$o['a'] || $sum==0 || $sum==765 ); } # サンプルの取得パターン function getPattern(&$img,$u) { # 出力するファイル名 $file = '../tmp/'.md5($_SERVER['REMOTE_ADDR'].time()).'.png'; # 元画像のサイズを取得 $o = new Imagick(); $o->readImageBlob($img); $height = $o->getImageHeight(); $width = $o->getImageWidth(); $o->destroy(); # パターン用の画像を生成 $o = new Imagick(); $o->newImage($width,$height,new ImagickPixel('transparent')); $o->setImageFormat('png'); $d = new ImagickDraw(); $d->setFillColor(new ImagickPixel('#F0F')); $u += 2; $c = Array($o->getImageWidth()/2,$o->getImageHeight()/2); $R = min($c) - 5; for ($r=$R/$u/2;$r<$R-$R/$u;$r+=$R/$u) for ($Q=0;$Q<2*M_PI;$Q+=M_PI/8) $d->point(round($c[0]+$r*cos($Q)),round($c[1]+$r*sin($Q))); $o->drawImage($d); $o->writeImage($file); return $file; } ?>  PHPとImagickで画像の色情報を取得

Imagickを使って画像に含まれる色のサンプルを取得して、さらにそれらを64色のうちのどれかの色に近似して分類します。

画像のURL : サンプル数の度合(5-100):
画像の上でマウスをクリックすると、サンプルを取得した画素の位置が確認できます。
解析する画像 解析するためのサンプルを取得したパターン
カラー含有量
解析にかかった時間:

動作に必要なこと・もの

更新履歴
2011/05/20
このページを作り始める。
2011/05/21
このページを公開する。
2011/05/24
サンプルの取得パターンを追加する。
2015/02/25
jQueryをGoogle Hosted Librariesから取得するように変更する。
2016/08/02
このページをhttpsでも表示する。