<?php //比較元となる画像 $filepath = "sample.jpg"; //比較対象用画像ディレクトリ $dir = "images/"; $sample = loadImage($filepath); $sample_rgb = colorAverage($sample); imagedestroy($sample); $list = scandir($dir); $files = array(); foreach($list as $value){ if(is_file($dir . $value)){ $files[] = $dir . $value; } } $diff = array(); foreach($files as $file){ $image = loadImage($file); $rgb = colorAverage($image); $name = basename($file); $diff[$name] = colorDistance($sample_rgb, $rgb); } asort($diff); $result = array_keys($diff); echo reset($result); function loadImage($filepath){ $checkimg = getimagesize($filepath); if($checkimg['mime'] == "image/jpeg" || $checkimg['mime'] == "image/pjpeg"){ $extension = "jpg"; } else if ($checkimg['mime'] == "image/gif"){ $extension = "gif"; } else if ($checkimg['mime'] == "image/png" || $checkimg['mime'] == "image/x-png"){ $extension = "png"; } else { return false; } if($extension == 'jpg'){$image = ImageCreateFromJPEG($filepath);} if($extension == 'gif'){$image = ImageCreateFromGIF($filepath);} if($extension == 'png'){$image = ImageCreateFromPNG($filepath);} return $image; } function colorAverage($image){ $width = imagesx($image); $height = imagesy($image); $thumb_width = 16; $thumb_height = 16; $thumb = imagecreatetruecolor($thumb_width, $thumb_height); imagecopyresampled($thumb, $image, 0, 0, 0, 0, $thumb_width, $thumb_height, $width, $height); $red = 0; $green = 0; $blue = 0; for($x=0; $x < $thumb_width; $x++){ for($y=0; $y < $thumb_height; $y++){ $index = imagecolorat($thumb, $x, $y); $rgb = imagecolorsforindex($thumb, $index); $red += $rgb['red']; $green += $rgb['green']; $blue += $rgb['blue']; } } $average = array(); $pixel = $thumb_width * $thumb_height; $average['red'] = round($red / $pixel); $average['green'] = round($green / $pixel); $average['blue'] = round($blue / $pixel); return $average; } function colorDistance($rgb1, $rgb2){ $distance = 0; $distance += abs($rgb1['red'] - $rgb2['red']); $distance += abs($rgb1['green'] - $rgb2['green']); $distance += abs($rgb1['blue'] - $rgb2['blue']); return $distance; }
ある画像のRGB値から平均色を算出し、似た平均色を持つ画像をディレクトリ内から探すというものです。
計算速度を早めるために、一度小さなサムネイルを作ってから色を拾っています。精度を高めるならこのサムネイルサイズを大きくすると良いと思います。
ただ、結論から言うとイマイチです。
計算には間違いないのですが、人間の目は明るく鮮やかな部分に目が行ってしまい、暗く地味な色を無意識に省略してしまいます。
また、明るさの違いよりも色の違いを重視する傾向があります。
このプログラムの計算方法だと、色の違いと明るさの違いを同じ価値として計算するため、同じ色合いで明暗が異なる画像より、多少色が違っても似た明るさを持つ画像が重視されてしまいます。
そのあたりを考慮するのであればHSV色空間(色相・彩度・明度)をもとに比較すべきなのかもしれません。
追記: HSV色空間を利用した画像検索も作りました。
また、Lab 色空間を利用した精度の高い類似画像検索についてはこちらの記事を御覧ください。
Similar Posts:
- [PHP]HSV(HSB)色空間を比較して似た色合いの画像を検索する
- [PHP]似た画像を検索して近い順番に並べる(類似画像検索)
- [PHP]複数の画像をランダムに敷き詰めて一枚の画像に合成
- [PHP]円グラフを表示する(GD)
- [PHP]中心から角度を指定して線を引く(座標の回転)
- [PHP]マスク画像で写真を好きな形に切り抜く(クリッピングマスク)
- [PHP]画像を上下反転、左右反転する(垂直・水平方向の鏡像)
- [PHP]レーダーチャート(クモの巣グラフ)をGDで描画する