php怎么实现相似图片的搜索呢?
其中的原理来解释下
1、缩小尺寸。将图片缩小到8×8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。
2、简化色彩。将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。
3、计算平均值。计算所有64个像素的灰度平均值。
4、比较像素的灰度。将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。
5、计算哈希值。将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。
感知哈希算法
count <=5 匹配最相似
count > 10 两张不同的图片
var_dump(ImageHash::run(‘./1.png’, ‘./psb.jpg’));
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; } }