php怎么实现根据图片搜索图片功能

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;

         

    }

     

}