PHP实现搜索相似图片


Posted in PHP onSeptember 22, 2015

感知哈希算法

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;
 }
}

调用方式如下:

require_once "Imghash.class.php";
$instance = ImgHash::getInstance();
$result = $instance->checkIsSimilarImg('chenyin/IMG_3214.png', 'chenyin/IMG_3212.JPG');

如果$result值为true, 则表明2个图片相似,否则不相似。

PHP 相关文章推荐
dedecms后台验证码总提示错误的解决方法
Mar 21 PHP
PHP 字符串编码截取函数(兼容utf-8和gb2312)
May 02 PHP
在smarty中调用php内置函数的方法
Feb 07 PHP
关于url地址传参数时字符串有回车造成页面脚本赋值失败的解决方法
Jun 28 PHP
php 邮件发送问题解决
Mar 22 PHP
linux下为php添加iconv模块的方法
Feb 28 PHP
Zend Framework教程之模型Model基本规则和使用方法
Mar 04 PHP
PHP的Yii框架中Model模型的学习教程
Mar 29 PHP
PHP操作Redis常用技巧总结
Apr 24 PHP
php 实现简单的登录功能示例【基于thinkPHP框架】
Dec 02 PHP
PHP number_format函数原理及实例解析
Jul 14 PHP
Memcached介绍及php-memcache扩展安装
Apr 01 PHP
从刷票了解获得客户端IP的方法
Sep 21 #PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
Sep 20 #PHP
分享ThinkPHP3.2中关联查询解决思路
Sep 20 #PHP
使用PHPCMS搭建wap手机网站
Sep 20 #PHP
求帮忙修改个php curl模拟post请求内容后并下载文件的解决思路
Sep 20 #PHP
PHP执行SQL文件并将SQL文件导入到数据库
Sep 17 #PHP
如何使用PHP对网站验证码进行破解
Sep 17 #PHP
You might like
用php获取本周,上周,本月,上月,本季度日期的代码
2009/08/05 PHP
php中获得视频时间总长度的另一种方法
2011/09/15 PHP
PHP使用strstr()函数获取指定字符串后所有字符的方法
2016/01/07 PHP
JS location几个方法小姐
2008/07/09 Javascript
学习ExtJS 访问容器对象
2009/10/07 Javascript
asp.net HttpHandler实现图片防盗链
2009/11/09 Javascript
Extjs中ComboBoxTree实现的下拉框树效果(自写)
2013/05/28 Javascript
javascript内置对象arguments详解
2014/03/16 Javascript
jquery 重写 ajax提交并判断权限后 使用load方法报错解决方法
2016/01/19 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
JS中微信小程序自定义底部弹出框
2016/12/22 Javascript
jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
2016/12/30 Javascript
js和jquery中获取非行间样式
2017/05/05 jQuery
Nodejs 复制文件/文件夹的方法
2017/08/24 NodeJs
使用Dropzone.js上传的示例代码
2017/10/10 Javascript
深入浅析javascript继承体系
2017/10/23 Javascript
深入理解Node module模块
2018/03/26 Javascript
Angular开发实践之服务端渲染
2018/03/29 Javascript
浅探express路由和中间件的实现
2019/09/30 Javascript
浅析JavaScript中的事件委托机制跟深浅拷贝
2021/01/20 Javascript
[42:24]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第一场 11.01
2020/11/02 DOTA
Django + Uwsgi + Nginx 实现生产环境部署的方法
2018/06/20 Python
python异常处理之try finally不报错的原因
2020/05/18 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
Python如何telnet到网络设备
2021/02/18 Python
施华洛世奇水晶荷兰官方网站:SWAROVSKI荷兰
2017/05/12 全球购物
丝芙兰中国官方商城:SEPHORA中国
2018/01/10 全球购物
留学自荐信
2013/10/10 职场文书
施工材料员岗位职责
2014/02/12 职场文书
财务担保书范文
2014/04/02 职场文书
个人德育工作总结
2015/03/05 职场文书
运动会新闻报道稿
2015/07/22 职场文书
如何使用Python对NetCDF数据做空间相关分析
2021/04/21 Python
MySQL sql_mode修改不生效的原因及解决
2021/05/07 MySQL
python状态机transitions库详解
2021/06/02 Python
html2 canvas svg不能识别的解决方案
2021/06/03 HTML / CSS