当前位置:首页 > PHP教程 > php类库 > 列表

分享一个PHP简易的图片相似度比较类

发布:smiling 来源: PHP粉丝网  添加日期:2015-04-15 15:53:32 浏览: 评论:0 

记得以前的港片《杀手之王》有一个镜头,就是用计算机判断一个照片和杀手留下的背影照片的相似度,现在我们来分享一个PHP简单的图片相似度比较类.

由于相似图片搜索的php实现的 API 不怎么符合我的用途,所以我重新定义 API 的架构,改写成比较简单的函数方式,虽然还是用对象的方式包装,代码如下:

  1. <?php     
  2. /**    
  3. * 图片相似度比较    
  4. *    
  5. * @version     $Id: ImageHash.php 4429 2012-04-17 13:20:31Z jax $    
  6. * @author      jax.hu    
  7. *    
  8. * <code>    
  9. *  //Sample_1    
  10. *  $aHash = ImageHash::hashImageFile('wsz.11.jpg');    
  11. *  $bHash = ImageHash::hashImageFile('wsz.12.jpg');    
  12. *  var_dump(ImageHash::isHashSimilar($aHash, $bHash));    
  13. *    
  14. *  //Sample_2    
  15. *  var_dump(ImageHash::isImageFileSimilar('wsz.11.jpg', 'wsz.12.jpg'));    
  16. * </code>    
  17. */     
  18.      
  19. class ImageHash {     
  20.      
  21.    /**取样倍率 1~10    
  22.     * @access public    
  23.     * @staticvar int    
  24.     * */     
  25.    public static $rate = 2;     
  26.      
  27.    /**相似度允许值 0~64    
  28.     * @access public    
  29.     * @staticvar int    
  30.     * */     
  31.    public static $similarity = 80;     
  32.      
  33.    /**图片类型对应的开启函数    
  34.     * @access private    
  35.     * @staticvar string    
  36.     * */     
  37.    private static $_createFunc = array(     
  38.        IMAGETYPE_GIF   =>'imageCreateFromGIF',     
  39.        IMAGETYPE_JPEG  =>'imageCreateFromJPEG',     
  40.        IMAGETYPE_PNG   =>'imageCreateFromPNG',     
  41.        IMAGETYPE_BMP   =>'imageCreateFromBMP',     
  42.        IMAGETYPE_WBMP  =>'imageCreateFromWBMP',     
  43.        IMAGETYPE_XBM   =>'imageCreateFromXBM',     
  44.    );     
  45.      
  46.      
  47.    /**从文件建立图片    
  48.     * @param string $filePath 文件地址路径    
  49.     * @return resource 当成功开启图片则传递图片 resource ID,失败则是 false    
  50.     * */     
  51.    public static function createImage($filePath){     
  52.        if(!file_exists($filePath)){ return false; }     
  53.      
  54.        /*判断文件类型是否可以开启*/     
  55.        $type = exif_imagetype($filePath);     
  56.        if(!array_key_exists($type,self::$_createFunc)){ return false; }     
  57.      
  58.        $func = self::$_createFunc[$type];     
  59.        if(!function_exists($func)){ return false; }     
  60.      
  61.        return $func($filePath);     
  62.    }     
  63.      
  64.      
  65.    /**hash 图片    
  66.     * @param resource $src 图片 resource ID    
  67.     * @return string 图片 hash 值,失败则是 false    
  68.     * */     
  69.    public static function hashImage($src){     
  70.        if(!$src){ return false; }     
  71.      
  72.        /*缩小图片尺寸*/     
  73.        $delta = 8 * self::$rate;     
  74.        $img = imageCreateTrueColor($delta,$delta);     
  75.        imageCopyResized($img,$src, 0,0,0,0, $delta,$delta,imagesX($src),imagesY($src));     
  76.      
  77.        /*计算图片灰阶值*/     
  78.        $grayArray = array();     
  79.        for ($y=0; $y<$delta$y++){     
  80.            for ($x=0; $x<$delta$x++){     
  81.                $rgb = imagecolorat($img,$x,$y);     
  82.                $col = imagecolorsforindex($img$rgb);     
  83.                $gray = intval(($col['red']+$col['green']+$col['blue'])/3)& 0xFF;     
  84.      
  85.                $grayArray[] = $gray;     
  86.            }     
  87.        }     
  88.        imagedestroy($img);     
  89.      
  90.        /*计算所有像素的灰阶平均值*/     
  91.        $average = array_sum($grayArray)/count($grayArray);     
  92.      
  93.        /*计算 hash 值*/     
  94.        $hashStr = '';     
  95.        foreach ($grayArray as $gray){     
  96.            $hashStr .= ($gray>=$average) ? '1' : '0';     
  97.        }   //开源软件:phpfensi.com 
  98.      
  99.        return $hashStr;     
  100.    }     
  101.      
  102.      
  103.    /**hash 图片文件    
  104.     * @param string $filePath 文件地址路径    
  105.     * @return string 图片 hash 值,失败则是 false    
  106.     * */     
  107.    public static function hashImageFile($filePath){     
  108.        $src = self::createImage($filePath);     
  109.        $hashStr = self::hashImage($src);     
  110.        imagedestroy($src);     
  111.      
  112.        return $hashStr;     
  113.    }     
  114.      
  115.      
  116.    /**比较两个 hash 值,是不是相似    
  117.     * @param string $aHash A图片的 hash 值    
  118.     * @param string $bHash B图片的 hash 值    
  119.     * @return bool 当图片相似则传递 true,否则是 false    
  120.     * */     
  121.    public static function isHashSimilar($aHash$bHash){     
  122.        $aL = strlen($aHash); $bL = strlen($bHash);     
  123.        if ($aL !== $bL){ return false; }     
  124.      
  125.        /*计算容许落差的数量*/     
  126.        $allowGap = $aL*(100-self::$similarity)/100;     
  127.      
  128.        /*计算两个 hash 值的汉明距离*/     
  129.        $distance = 0;     
  130.        for($i=0; $i<$aL$i++){     
  131.            if ($aHash{$i} !== $bHash{$i}){ $distance++; }     
  132.        }     
  133.      
  134.        return ($distance<=$allowGap) ? true : false;     
  135.    }     
  136.      
  137.      
  138.    /**比较两个图片文件,是不是相似    
  139.     * @param string $aHash A图片的路径    
  140.     * @param string $bHash B图片的路径    
  141.     * @return bool 当图片相似则传递 true,否则是 false    
  142.     * */     
  143.    public static function isImageFileSimilar($aPath$bPath){     
  144.        $aHash = ImageHash::hashImageFile($aPath);     
  145.        $bHash = ImageHash::hashImageFile($bPath);     
  146.        return ImageHash::isHashSimilar($aHash$bHash);     
  147.    }     
  148.      
  149. ?>

Tags: PHP简易图片 PHP相似度比较

分享到: