PHP判断两张图片相似

发布时间:2016-04-25 浏览次数:5873 文章来源:个人博客

在工作中,遇到一个需要识别用户上传的图片在当前的图片库中是否已经存在(不可能用高宽去判断),这需要用到图片相似识别。。


感知哈希算法(Perceptual hash algorithm)----它对每一张图片生成指纹字符串,然后我们比较两个图片的“指纹”,如果“指纹”越相近,那么图片就越相似。


第一步,缩小尺寸。

将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。


第二步,简化色彩。

将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。


第三步,计算平均值。

计算所有64个像素的灰度平均值。


第四步,比较像素的灰度。

将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。


第五步,计算哈希值。

将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。


得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算"汉明距离"(Hamming distance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。


这里附带PHP的判断图片相似类:

<?php

class Imghash{

        private static $_instance = null;
        
        public $rate = 2;
        
        public static function getInstance(){
                if(self::$_instance == null){
                        self::$_instance = new self();
                }
        
                return self::$_instance;
        }
        
        public function run($file){
                if(!function_exists('imagecreatetruecolor')){
                        throw new Exception('gd lib need load',1);
                }
                $isString = false;
                if(is_string($file)){
                        $file = array($file);
                        $isString = true;                
                }
                $result = array();
                foreach($file as $f){
                        $result[] = $this->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;$irate) ? 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 8 ) & 0xFF;
				if ([email protected] */" _ue_custom_node_="true">_array($array[$y])){
					$array[$y] = array();
				}
				$array[$y][$x] = $gray;
				$total += $gray;
			}
		}
		$average = intval($total / (64 * $this->rate * $this->rate));
		$result = '';
		for ($y=0;$ygetFileExt($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;
	}
}


以上内容参照于网络~~

key-word
PHP判断图片相似 判断图片是否相似 判断图片内容是否相同 比较图片内容是否相同 匹配图片是否一样