【PHP実践|実務向け】PHPで実現する類似画像検索:色空間を活用した実装手法

導入

Webアプリケーションにおいて、「ユーザーがアップロードした画像と似た画像を検索する」機能は、重複排除やレコメンデーションエンジンにおいて非常に強力なツールとなります。外部APIや機械学習ライブラリを使わず、PHPの標準的な画像処理ライブラリであるGDを使用して、軽量かつシンプルに類似画像を判定する方法を解説します。この手法は、画像の「色味」を数値化して比較することで、視覚的な類似性を算出します。

基礎知識

画像を検索するために重要なのは、画像をそのまま比較するのではなく、特徴を「データ」として抽出することです。
今回の手法では、画像全体のピクセルを平均化して「4×4の小さな画像(サムネイル)」に変換します。これにより、高解像度の画像も16個のピクセル情報へと圧縮されます。
ここでポイントとなるのが「Lab色空間」です。通常のRGB(光の三原色)はコンピュータが扱いやすい形式ですが、人間の目に見える色味の近さを計算するには不向きです。Lab色空間は、輝度(L)と色相(a, b)を分離した形式であり、これを用いることで、人間が感じる「色の近さ」を数学的な距離として算出できるようになります。

実装/解決策

実装のステップは以下の通りです。
1. 画像を読み込み、4×4ピクセルに縮小する。
2. 各ピクセルのRGB値を取得し、それをLab色空間の座標に変換する。
3. 比較対象となる画像との間で、各ピクセルごとのLab座標の距離(ユークリッド距離)を算出する。
4. 合計距離が小さいものほど「似ている」と判断し、昇順でソートする。

サンプルプログラム

以下のコードは、指定ディレクトリ内の画像を読み込み、基準画像との類似度を計算してソートする実用的なスニペットです。

$value){
// Lab座標の距離を積算
$distance += lab_distance($value, $lab[$key]);
}
$diff[basename($file)] = $distance;
}

// 距離が小さい順(似ている順)にソート
asort($diff);

foreach($diff as $filename => $score) {
echo “ファイル名: {$filename} (スコア: {$score})
“;
}

/

  • 画像読み込みとGDリソースの生成

/
function load_image($filepath){
$info = getimagesize($filepath);
switch ($info[‘mime’]) {
case ‘image/jpeg’: return imagecreatefromjpeg($filepath);
case ‘image/png’: return imagecreatefrompng($filepath);
case ‘image/gif’: return imagecreatefromgif($filepath);
default: return null;
}
}

/

  • 画像を4×4に縮小してLab値の配列を返す

/
function image_lab($image){
$thumb = imagecreatetruecolor(4, 4);
imagecopyresampled($thumb, $image, 0, 0, 0, 0, 4, 4, imagesx($image), imagesy($image));
$lab = [];
for($x=0; $x<4; $x++){ for($y=0; $y<4; $y++){ $rgb = imagecolorsforindex($thumb, imagecolorat($thumb, $x, $y)); $lab[] = rgb2lab([$rgb['red'], $rgb['green'], $rgb['blue']]); } } return $lab; } // ※注: rgb2lab, xyz2lab, lab_distance 関数は参考元コードのロジックをそのまま利用してください。 ?>

応用・注意点

1. 計算負荷の管理: 比較する画像の枚数が多い場合、毎回全画像を計算するのは非効率です。事前にDBに各画像のLab値(16ピクセル分)を保存しておき、検索時にはDB上の値と比較するように設計しましょう。
2. 精度の向上: 4×4の解像度では大まかな色味しか判別できません。より詳細な比較が必要な場合は8×8などに上げることが可能ですが、計算時間は指数関数的に増えるため注意が必要です。
3. 限界の理解: この手法は「色味の類似」を判定するものです。構図や対象物の形まで含めた類似検索を行う場合は、PHash(Perceptual Hash)などのアルゴリズムを併用することをお勧めします。

タイトルとURLをコピーしました