PHP で画像比較
2つの画像がどの位違うのかを数値化するプログラムです。
ピクセル毎の色の違いを合計するだけの簡単な比較です。
一応、教科書の初めに出てくるような一般的な手法で、SSD (sum of squared difference) という名前が付いています。
- 画像サイズがだいたい合ってないとダメ (縦、又は横が2倍違うとエラー)
- エラーがマズイ人はエラーの代わりに適切な値を返すように変更して下さい。
- 非対称な画像が回転してたり、部分的に一致してる場合とかは考慮していません。
- あくまで殆ど同じ画像かどうかだけ。
- 最終結果はRGB色空間(0,0,0)-(255,255,255)の平均距離の2乗値です。
- 画像フォーマットは、少なくとも PNG, GIF, JPEG の3種類に対応してます。(後は GD ライブラリ次第)
- コードは見やすさ優先です。
- 速さを追求したい人は while($x) { $x-- ;... とか自分で変えて下さい。
10分で作った割に、意外と使えそうなのでコードを晒します。
<?php /* * dissimilarity measure * sum of squared difference * 2011/10/13- yoya@awm.jp */ function usage() { echo "Usage: php bitmap_comp.php <file1> <file2>\n"; } if (($argc != 3) || (! is_readable($argv[1])) || (! is_readable($argv[2]))) { usage(); exit (1); } $data1 = file_get_contents($argv[1]); $data2 = file_get_contents($argv[2]); $im1 = imagecreatefromstring($data1); $im2 = imagecreatefromstring($data2); if ($im1 === false || $im2 === false) { echo "Error: image1 or image2 has broken."; exit (1); } $width1 = imagesx($im1); $height1 = imagesy($im1); $width2 = imagesx($im2); $height2 = imagesy($im2); $width_ratio = $width2 / $width1; $height_ratio = $height2 / $height1; if ($width_ratio < 0.5 || 2.0 < $width_ratio || $height_ratio < 0.5 || 2.0 < $height_ratio) { echo "Error: image1(".$width1."x".$height1.") image2(".$width2."x".$height2.")\n"; exit (1); } $width = min($width1, $width2); $height = min($height1, $height2); $distance_square_sum = 0; for ($y = 0 ; $y < $height ; $y++) { for ($x = 0 ; $x < $width ; $x++) { $i1 = imagecolorat($im1, $x, $y); $i2 = imagecolorat($im2, $x, $y); $rgb1 = imagecolorsforindex($im1, $i1); $rgb2 = imagecolorsforindex($im2, $i2); $red_diff = $rgb1['red'] - $rgb2['red']; $green_diff = $rgb1['green'] - $rgb2['green']; $blue_diff = $rgb1['blue'] - $rgb2['blue']; $distance_square_sum += $red_diff*$red_diff + $green_diff*$green_diff + $blue_diff*$blue_diff; } } echo $distance_square_sum / ($width * $height) . "\n";