Created
July 2, 2010 08:34
-
-
Save mgng/461109 to your computer and use it in GitHub Desktop.
エセ画像類似度判定
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
100 / 255 がいいのかどうかわからない