1. 導入
Webアプリケーションにおいて、アップロードされた画像が既存の画像と重複していないか、あるいは似ている画像を提示したいというニーズは非常に一般的です。しかし、ピクセル単位の完全一致検索は実用的ではありません。本記事では、PHPを用いて画像を特徴量化し、類似度を比較するための実践的なアプローチを解説します。
2. 基礎知識
類似画像検索の基本は、画像を「縮小」してピクセル数を減らし、その各点の「色情報」を数値化して比較することです。
代表的な色空間には以下のものがあります。
RGB: コンピュータが扱う基本形式ですが、人間の知覚とは乖離があります。
HSV: 色相(Hue)、彩度(Saturation)、明度(Value)で構成され、RGBよりも人間の感覚に近い色判定が可能です。
Lab色空間: 色を3次元空間上の座標として扱い、2点間の距離(ユークリッド距離)で色の差を正確に測定できます。精度を求めるならLabが最適です。
3. 実装/解決策
実務レベルでは、まず画像をGDライブラリ等で3×3や8×8のサムネイルに縮小し、各画素のカラーコードを抽出します。その際、単純なRGB比較ではなく、HSV変換を挟むことで精度が向上します。大量の画像を扱う場合は、抽出した色情報をデータベース(MySQL/PostgreSQL)に保存し、インデックスを貼ることで高速なクエリ検索が可能になります。
4. サンプルプログラム
以下は、GDライブラリを使用して画像をリサイズし、RGBからHSVに変換して色情報を取得する基本的なロジックです。
/
function getHsvFromImage($imagePath) {
// 画像リソースを作成
$img = imagecreatefromjpeg($imagePath);
// 3×3ピクセルに縮小
$thumb = imagescale($img, 3, 3);
// 中央(1,1)のピクセル色を取得
$rgb = imagecolorat($thumb, 1, 1);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
// RGBからHSVへの変換処理
$max = max($r, $g, $b);
$min = min($r, $g, $b);
$v = $max / 255;
$s = ($max == 0) ? 0 : ($max – $min) / $max;
$h = 0; // 色相の計算ロジックは別途実装が必要
imagedestroy($img);
imagedestroy($thumb);
return [‘h’ => $h, ‘s’ => $s, ‘v’ => $v];
}
// 使用例
$colorInfo = getHsvFromImage(‘sample.jpg’);
echo “明度(V): ” . $colorInfo[‘v’];
?>
5. 応用・注意点
パフォーマンスの罠
数万件を超える画像に対してリアルタイムに計算を行うのは非常に負荷が高いです。必ず「インデックス化」を行ってください。あらかじめバッチ処理で特徴量(色情報の配列)を計算し、専用のテーブルに保存しておくのが鉄則です。
精度向上のヒント
Lab色空間への変換を導入する場合、計算コストが増大します。その際は、まずHSVの「明度(V)」で大まかにグループ分け(明るい画像・暗い画像)を行い、検索対象を絞り込む手法が有効です。また、ユーザーの過去の選択履歴を学習させるナイーブベイズ分類器を組み合わせることで、検索精度はさらに向上します。
エラーハンドリング
参考本文で見られたような「count(): Parameter must be an array…」といった警告は、外部ライブラリや配列操作時のチェック漏れで頻発します。常にis_array()などで型チェックを行う防御的プログラミングを意識しましょう。