PHP實現(xiàn)搜索相似圖片
更新時間:2015年09月22日 08:40:21 投稿:hebedich
感知哈希的優(yōu)點是簡單快速,不受圖片大小縮放的影響,缺點是圖片的內(nèi)容不能變更。實際應(yīng)用中,往往采用更強大的pHash算法和SIFT算法,它們能夠識別圖片的變形。只要變形程度不超過25%,它們就能匹配原圖。
感知哈希算法
count < =5 匹配最相似
count > 10 兩張不同的圖片
var_dump(ImageHash::run(‘./1.png', ‘./psb.jpg'));
<?php
class ImageHash {
const FILE_NOT_FOUND = '-1';
const FILE_EXTNAME_ILLEGAL = '-2';
private function __construct() {}
public static function run($src1, $src2) {
static $self;
if(!$self) $self = new static;
if(!is_file($src1) || !is_file($src2)) exit(self::FILE_NOT_FOUND);
$hash1 = $self->getHashValue($src1);
$hash2 = $self->getHashValue($src2);
if(strlen($hash1) !== strlen($hash2)) return false;
$count = 0;
$len = strlen($hash1);
for($i = 0; $i < $len; $i++) if($hash1[$i] !== $hash2[$i]) $count++;
return $count <= 10 ? true : false;
}
public function getImage($file) {
$extname = pathinfo($file, PATHINFO_EXTENSION);
if(!in_array($extname, ['jpg','jpeg','png','gif'])) exit(self::FILE_EXTNAME_ILLEGAL);
$img = call_user_func('imagecreatefrom'. ( $extname == 'jpg' ? 'jpeg' : $extname ) , $file);
return $img;
}
public function getHashValue($file) {
$w = 8;
$h = 8;
$img = imagecreatetruecolor($w, $h);
list($src_w, $src_h) = getimagesize($file);
$src = $this->getImage($file);
imagecopyresampled($img, $src, 0, 0, 0, 0, $w, $h, $src_w, $src_h);
imagedestroy($src);
$total = 0;
$array = array();
for( $y = 0; $y < $h; $y++) {
for ($x = 0; $x < $w; $x++) {
$gray = (imagecolorat($img, $x, $y) >> 8) & 0xFF;
if(!isset($array[$y])) $array[$y] = array();
$array[$y][$x] = $gray;
$total += $gray;
}
}
imagedestroy($img);
$average = intval($total / ($w * $h * 2));
$hash = '';
for($y = 0; $y < $h; $y++) {
for($x = 0; $x < $w; $x++) {
$hash .= ($array[$y][$x] >= $average) ? '1' : '0';
}
}
var_dump($hash);
return $hash;
}
}
var_dump(ImageHash::run('./1.png', './psb.jpg'));
方法二:
hash($f);
}
return $isString ? $result[0] : $result;
}
public function checkIsSimilarImg($imgHash, $otherImgHash){
if (file_exists($imgHash) && file_exists($otherImgHash)){
$imgHash = $this->run($imgHash);
$otherImgHash = $this->run($otherImgHash);
}
if (strlen($imgHash) !== strlen($otherImgHash)) return false;
$count = 0;
$len = strlen($imgHash);
for($i=0;$i<$len;$i++){
if ($imgHash{$i} !== $otherImgHash{$i}){
$count++;
}
}
return $count <= (5 * $rate * $rate) ? true : false;
}
public function hash($file){
if (!file_exists($file)){
return false;
}
$height = 8 * $this->rate;
$width = 8 * $this->rate;
$img = imagecreatetruecolor($width, $height);
list($w, $h) = getimagesize($file);
$source = $this->createImg($file);
imagecopyresampled($img, $source, 0, 0, 0, 0, $width, $height, $w, $h);
$value = $this->getHashValue($img);
imagedestroy($img);
return $value;
}
public function getHashValue($img){
$width = imagesx($img);
$height = imagesy($img);
$total = 0;
$array = array();
for ($y=0;$y<$height;$y++){
for ($x=0;$x<$width;$x++){
$gray = ( imagecolorat($img, $x, $y) >> 8 ) & 0xFF;
if (!is_array($array[$y])){
$array[$y] = array();
}
$array[$y][$x] = $gray;
$total += $gray;
}
}
$average = intval($total / (64 * $this->rate * $this->rate));
$result = '';
for ($y=0;$y<$height;$y++){
for ($x=0;$x<$width;$x++){
if ($array[$y][$x] >= $average){
$result .= '1';
}else{
$result .= '0';
}
}
}
return $result;
}
public function createImg($file){
$ext = $this->getFileExt($file);
if ($ext === 'jpeg') $ext = 'jpg';
$img = null;
switch ($ext){
case 'png' : $img = imagecreatefrompng($file);break;
case 'jpg' : $img = imagecreatefromjpeg($file);break;
case 'gif' : $img = imagecreatefromgif($file);
}
return $img;
}
public function getFileExt($file){
$infos = explode('.', $file);
$ext = strtolower($infos[count($infos) - 1]);
return $ext;
}
}
調(diào)用方式如下:
require_once "Imghash.class.php";
$instance = ImgHash::getInstance();
$result = $instance->checkIsSimilarImg('chenyin/IMG_3214.png', 'chenyin/IMG_3212.JPG');
如果$result值為true, 則表明2個圖片相似,否則不相似。
相關(guān)文章
php中session_unset與session_destroy的區(qū)別分析
關(guān)于session_unset()和session_destroy()的函數(shù)使用進行介紹。學(xué)習(xí)php的朋友可以參考下。2011-06-06
使用PHP連接多種數(shù)據(jù)庫的實現(xiàn)代碼(mysql,access,sqlserver,Oracle)
我們今天為大家介紹的PHP連接數(shù)據(jù)庫的方法包括在MYSQL數(shù)據(jù)庫、ACCESS數(shù)據(jù)庫、MS SQL數(shù)據(jù)庫和Oracle數(shù)據(jù)庫中實現(xiàn)2016-12-12
php獲取從百度搜索進入網(wǎng)站的關(guān)鍵詞的詳細代碼
以下是關(guān)于php該如何獲取從百度搜索進入網(wǎng)站的關(guān)鍵詞的詳細代碼,希望本文對廣大php開發(fā)者有所幫助2014-01-01
PHP+Mysql+jQuery查詢和列表框選擇操作實例講解
這篇文章主要介紹了PHP+Mysql+jQuery查詢和列表框選擇操作實現(xiàn)過程,需要的朋友可以參考下2015-10-10

