PHPとMySQLを用いてカラー情報から画像を検索するプログラムを作成しました
http://moeten.info/maidcafe/?&m=image_search&type=search&color=FF33C5
以前作ってみたときはなんだかうまくいかなったんだけど、今回はうまくいったぽいです。
まず、画像にインデックスを張る方法ですが、今回は簡単に、画像の色情報(RGBとHSV)のそれぞれの平均値を出してMySQLに入れています。
<?php //画像読み込み $im = imagecreatefromjpeg( $url ); //画像の大きさ取得 $img_w = imagesx( $im ); $img_h = imagesy( $im ); //画像の総ピクセル数 $cnt = $img_w * $img_h; //配列初期化 $r = array(); $g = array(); $b = array(); $h = array(); $s = array(); $v = array(); //色をとってくるよ。 for( $i = 0 ; $i < $img_w ; $i ++ ){ for( $j = 0 ; $j < $img_h ; $j ++ ){ //rgb取得 $rgb = imagecolorat($im, $i , $j ); $r[] = ($rgb >> 16) & 0xFF; $g[] = ($rgb >> 8) & 0xFF; $b[] = $rgb & 0xFF; $t_r = ($rgb >> 16) & 0xFF; $t_g =($rgb >> 8) & 0xFF; $t_b = $rgb & 0xFF; //hsv取得 $hsv = rgb2hsv( $t_r , $t_g , $t_b); $h[] = $hsv['h']; $s[] = $hsv['s']*100; $v[] = $hsv['v']; } } //平均値計算 $index_r = intval( array_sum( $r ) / $cnt) ; $index_g = intval( array_sum( $g ) / $cnt ); $index_b = intval( array_sum( $b ) / $cnt ); $index_h = intval( array_sum( $h ) / $cnt) ; $index_s = intval( array_sum( $s ) / $cnt ); $index_v = intval( array_sum( $v ) / $cnt ); //MySQLへ入れる $sql = " INSERT INTO tmp_shop_img_index ( oid , type , index_r , index_g , index_b , index_h , index_s , index_v , print )VALUES( '{$val['id']}' , 'dayinfo' , '{$index_r}' , '{$index_g}' , '{$index_b}' , '{$index_h}' , '{$index_s}' , '{$index_v}' , 1 );"; mysql_query( $sql ); ?>
<?php //rgb -> hsv function rgb2hsv($r,$g,$b){ $h = $s = $v = 0; if ( $r >= $g){ $cmax = $r; }else{ $cmax = $g; } if ( $b > $cmax){ $cmax = $b; } if ( $r <= $g){ $cmin = $r; }else{ $cmin = $g; } if ( $b < $cmin){ $cmin = $b; } $v = $cmax; $c = $cmax - $cmin; if($cmax == 0){ $s = 0; }else{ $s = $c/$cmax; } if($s != 0){ if ($r == $cmax){ $h = ($g - $b)/$c; }else{ if($g == $cmax){ $h = 2 + ($b - $r)/$c; }else{ if($b == $cmax){ $h = 4 + ( $r - $g)/$c; } } } $h = $h * 60; if ($h < 0) $h = $h + 360; } $hsv["h"] = $h; $hsv["s"] = $s; $hsv["v"] = $v; return $hsv; } ?>
画像の数だけデーターベースへ入れていってあげます。
これで下準備が終了です。
ここからは検索したいカラーを用いてからMySQLで計算です。
<?php //カラーを分解 $color = $_GET['color']; $r = hexdec( substr( $color , 0,2 ) ); $g = hexdec( substr( $color , 2,2 ) ); $b = hexdec( substr( $color , 4,2 ) ); //MySQLへ問い合わせ $sql = " SELECT oid ,( POW(({$r}-index_r),2) + POW(({$g}-index_g),2) + POW(({$b}-index_b),2) ) as sa FROM tmp_shop_img_index ORDER BY sa ASC LIMIT 100 "; ?>
以上で$r,$g,$bでの差分の低い順に表示されます。文字のエスケープとは各自してね。