導入
Webアプリケーションにおいて、アップロードされた画像の重複チェックや、ユーザーが投稿した画像に関連する「おすすめ画像」を表示させたいというニーズは少なくありません。しかし、単純なファイル名やハッシュ値の比較では、わずかに解像度や圧縮率が異なるだけで「別物」と判定されてしまいます。本記事では、PHPのGDライブラリを活用し、画像の色情報を解析して「視覚的に近い画像」を検索する仕組みを解説します。
基礎知識
類似画像検索の基本原理は、画像を小さなグリッドに分割(または平均化)し、各ピクセルの色情報を数値化して比較することにあります。
色空間の選択が精度を左右します。
・RGB: コンピュータが扱う基本形式ですが、人間の知覚とは乖離があります。
・HSV: 色相(Hue)、彩度(Saturation)、明度(Value)で構成されます。人間の直感に近い色比較が可能です。
・Lab: 人間の視覚に最も近いとされる色空間です。輝度と色の成分を分離して計算できるため、高精度な比較が可能です。
実装/解決策
基本的な手順は以下の通りです。
1. リサイズ: 元画像をそのまま扱うと計算コストが高いため、あえて16×16ピクセル程度に縮小し、処理を高速化します。
2. 色情報の抽出: 縮小した画像の各ピクセルからRGB値を取得します。
3. 空間変換: 必要に応じてRGBをHSVやLabに変換します。
4. 距離計算: 比較元と対象の数値の差分(距離)を計算します。
5. ソート: 距離が小さい順に並べ替えることで、似ている画像順に取得できます。
サンプルプログラム
以下は、HSVモデルを用いて画像の平均的な色合いから類似度を算出する実用的なコード例です。
/
function getAverageHsv($filepath) {
$image = imagecreatefromjpeg($filepath); // 実際にはmimeタイプ判定を推奨
$thumb = imagecreatetruecolor(16, 16);
imagecopyresampled($thumb, $image, 0, 0, 0, 0, 16, 16, imagesx($image), imagesy($image));
$r = $g = $b = 0;
for ($x = 0; $x < 16; $x++) {
for ($y = 0; $y < 16; $y++) {
$rgb = imagecolorsforindex($thumb, imagecolorat($thumb, $x, $y));
$r += $rgb['red']; $g += $rgb['green']; $b += $rgb['blue'];
}
}
imagedestroy($thumb);
imagedestroy($image);
// RGBの平均値を算出してHSVへ変換
return rgbToHsv(['red' => $r/256, ‘green’ => $g/256, ‘blue’ => $b/256]);
}
/
- HSV距離を計算
/
function getHsvDistance($hsv1, $hsv2) {
// 色相(H)は環状なので特殊な計算が必要
$diff_h = abs($hsv1[‘h’] – $hsv2[‘h’]);
$dist_h = min($diff_h, 360 – $diff_h);
return $dist_h + abs($hsv1[‘s’] – $hsv2[‘s’]) 180 + abs($hsv1[‘v’] – $hsv2[‘v’]) 180;
}
// 実行ロジック
$targetHsv = getAverageHsv($filepath);
$results = [];
foreach (glob($dir . “.jpg”) as $file) {
$fileHsv = getAverageHsv($file);
$results[basename($file)] = getHsvDistance($targetHsv, $fileHsv);
}
// 距離が小さい順(似ている順)にソート
asort($results);
print_r(array_keys($results));
?>
応用・注意点
・計算量と精度のトレードオフ: サムネイルサイズを大きくすれば精度は上がりますが、サーバーのCPU負荷は急増します。大量の画像がある場合は、事前に「平均色」を計算してDBに保存しておく運用が必須です。
・モノクロ画像の扱い: 彩度が0の画像では色相(H)が不安定になります。モノクロ画像が多いシステムでは、事前に彩度をチェックし、モノクロの場合はHの比較をスキップするなどの分岐処理を加えることで誤検知を防げます。
・GDライブラリの制限: 高度な画像処理が必要な場合は、PHPのImagick拡張を利用することも検討してください。より高速かつ多機能な色空間変換が可能です。