Skip to content

Instantly share code, notes, and snippets.

@mgng
Created July 2, 2010 08:34
Show Gist options
  • Save mgng/461109 to your computer and use it in GitHub Desktop.
Save mgng/461109 to your computer and use it in GitHub Desktop.
エセ画像類似度判定
<?php
/**
* エセ画像類似度判定的なもの
*/
/** 画像情報をかえす */
function getImageInfo($file_path)
{
$info = getimagesize($file_path);
if ($info === false) {
return false;
}
// 画像GD
$w = $info[0];
$h = $info[1];
$type = image_type_to_extension($info[2], false);
$gd = call_user_func("imagecreatefrom{$type}", $file_path);
// 作業用GD, 幅99にリサイズして減色
$w_wk = 99;
$h_wk = (int)(99 * $h / $w);
$gd_wk = imagecreatetruecolor($w_wk, $h_wk);
imagecopyresampled($gd_wk, $gd, 0,0, 0,0, $w_wk, $h_wk, $w, $h);
imagetruecolortopalette($gd_wk, false, 255);
// 9分割して各ブロックごとのRGBリストを取得
$p_w = floor($w_wk / 3);
$p_h = floor($h_wk / 3);
$block = array(
getBlockInfo($gd_wk, 1,1, $p_w,$p_h),
getBlockInfo($gd_wk, 2,1, $p_w,$p_h),
getBlockInfo($gd_wk, 3,1, $p_w,$p_h),
getBlockInfo($gd_wk, 1,2, $p_w,$p_h),
getBlockInfo($gd_wk, 2,2, $p_w,$p_h),
getBlockInfo($gd_wk, 3,2, $p_w,$p_h),
getBlockInfo($gd_wk, 1,3, $p_w,$p_h),
getBlockInfo($gd_wk, 2,3, $p_w,$p_h),
getBlockInfo($gd_wk, 3,3, $p_w,$p_h),
);
imagedestroy($gd);
imagedestroy($gd_wk);
// 一番使われているRGB値を取得してreturn
$result = array();
foreach($block as $val) {
$keys = array_keys($val);
$result[] = $keys[0];
}
return $result;
}
/**
* ブロックを1pxずつ走査して色情報取得する。
* R値_G値_B値 => 出現回数 の連想配列を作成してreturn
*/
function getBlockInfo($gd, $x_block, $y_block, $p_w, $p_h)
{
$ret = array();
for ($x = ($p_w * ($x_block-1)); $x < ($p_w * $x_block); $x++) {
for ($y = ($p_h * ($y_block-1)); $y < ($p_h * $y_block); $y++) {
$rgb = imagecolorat($gd, $x, $y);
$idx = imagecolorsforindex($gd, $rgb);
$key = $idx['red'] . '_' . $idx['green'] . '_' . $idx['blue'];
if (!isset($ret[$key])) {
$ret[$key] = 0;
}
$ret[$key]++;
}
}
arsort($ret); // キー名保持して降順ソート
return $ret;
}
/** 類似度判定 */
function similar($check1, $check2)
{
$rgb_list = array('r'=>array(),'g'=>array(),'b'=>array());
for($i=0; $i<9; $i++) {
// RGB値分解して各差の絶対値を格納
$rgb1 = explode('_', $check1[$i]);
$rgb2 = explode('_', $check2[$i]);
$rgb_list['r'][] = abs((int)$rgb1[0] - (int)$rgb2[0]);
$rgb_list['g'][] = abs((int)$rgb1[1] - (int)$rgb2[1]);
$rgb_list['b'][] = abs((int)$rgb1[2] - (int)$rgb2[2]);
}
// RGBの平均と全体の平均
$r_avg = array_sum($rgb_list['r']) / count($rgb_list['r']);
$g_avg = array_sum($rgb_list['g']) / count($rgb_list['g']);
$b_avg = array_sum($rgb_list['b']) / count($rgb_list['b']);
$avg = ($r_avg + $g_avg + $b_avg) / 3;
return array(
'r_avg' => 100 - floor($r_avg * (100/255)),
'g_avg' => 100 - floor($g_avg * (100/255)),
'b_avg' => 100 - floor($b_avg * (100/255)),
'avg' => 100 - floor($avg * (100/255))
);
}
$info1 = getImageInfo('img1.jpg');
$info2 = getImageInfo('img2.jpg');
$result = similar($info1, $info2);
@mgng
Copy link
Author

mgng commented Jul 2, 2010

100 / 255 がいいのかどうかわからない

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment