计算图片相似性

帼民哥哥李小二 2021/9/15 13:05:00

判断两张图片的相似性(可用来实现根据缩略图查找原图功能)话不多说直接上代码<?php //引入图片相似度计算类 include_once "./imageDHASH.php";$img = new ImgCompareDHASH();//计算两个图片相似性 - 返回相似度百分比 $count1 = $img->ComparePic(./i…

判断两张图片的相似性(可用来实现根据缩略图查找原图功能)

话不多说直接上代码

<?php
//引入图片相似度计算类
include_once "./imageDHASH.php";

$img = new ImgCompareDHASH();

//计算两个图片相似性 - 返回相似度百分比
$count1 = $img->ComparePic('./images/pic1.jpg','./images/pic2.png');

echo '相似度:'.$count1."%\n";

imageDHASH类代码如下:
<?php
/* 差异值哈希
 * 1.将图片缩小为8*8的尺寸(这里把传来的图片全部转成统一大小)
 * 2.将第一步转换的图片再次转换为灰度图像
 * 3.计算每个像素的灰度的差值(如果大于平均值就取1,否则取0),得到图片指纹
 * 4.然后对比两个图片的指纹依次进行比较,数字相同多的即为相似度较高
 * */
class ImgCompareDHASH{

    //设定需要转换的图片尺寸
    public $width = 8;
    public $height = 8;
    public $scalar = 8;

    /**
     * 主方法 - 对比两张图片,得到相似度
     */
    public function ComparePic($img1, $img2){
	    //获得img1的指纹
        $hash1 = $this->getHash($img1);
        //获得img2的指纹
        $hash2 = $this->getHash($img2);
        //对比长度
        if(strlen($hash1) !== strlen($hash2)) {
            return false;
        }
        
        //计算汉明距离(可参考我另一篇文章[《计算两数的汉明距离》](https://www.imooc.com/article/317960))
        $result = $this->hd($hash1, $hash2);
        
        //计算相似度
        $result_percent = ($result / ($this->scalar * $this->scalar)) * 100;
	
		//返回相似度
        return $result_percent;

    }

    /**
     * 计算汉明距离
     */
    public function hd($h1, $h2)
    {
        $len = strlen($h1);
        $dist = 0;
        for ($i = 0;$i < $len; $i++) {
            if ( $h1[$i] == $h2[$i] )
                $dist++;
        }
        return $dist;
    }

    // 获得图片指纹
    public function getHash($url){

        /**
         * 新建一个 width * height 真彩色图像
         * 返回一个图像标识符
         */
        $im = imagecreatetruecolor($this->width, $this->height);   

        //获取图片宽和高
        list($ex_w, $ex_h) = getimagesize($url);
        // 获得图片文件的后缀名
        $name = pathinfo($url, PATHINFO_EXTENSION);
        
        /**
         * 根据扩展名判断使用什么方法进行处理
         * [PHP图像处理集合函数](https://www.php.net/manual/zh/book.image.php)
         * $allowedTypes = array(
          *  1,  // [] gif
          *  2,  // [] jpg
          *  3,  // [] png
          *  6   // [] bmp
          *  );
          *
          * switch ($type) {
          *     case 1 :
          *         $im = imageCreateFromGif($filepath);
          *     break;
          *     case 2 :
          *         $im = imageCreateFromJpeg($filepath);
          *     break;
          *     case 3 :
          *         $im = imageCreateFromPng($filepath);
          *     break;
          *     case 6 :
          *         $im = imageCreateFromBmp($filepath);
          *     break;
          * }   
         */
        $ex_img = call_user_func('imagecreatefrom'. ( $name == 'jpg' ? 'jpeg' : $name ) , $url);

        //重采样拷贝部分图像并调整大小(把原图进行采样,然后给到$im,变换图片大小)
        imagecopyresampled($im, $ex_img, 0, 0, 0, 0, $this->width, $this->height, $ex_w, $ex_h);

        //对图像使用过滤器 - 转换图片为灰度图
        imagefilter($im, IMG_FILTER_GRAYSCALE);
        
        //销毁缓存
        imagedestroy($ex_img);

        //记录每个像素值
        $pixels = [];
        for($i = 0; $i < $this->scalar; $i++){
            for($j = 0; $j < $this->scalar; $j++){

                /**
                 * 获得每个位置像素的索引值
                 * 0xFF:表示16进制 相当于 十进制 的 255
                 * 1111 1111
                 * 计算图片灰度值
                 */
                $gray = ImageColorAt($im, $i, $j) & 255;
                //记录每个点的像素值
                $pixels[] = $gray;     
            }
        }

		//销毁缓存
        imagedestroy($im);

        /*计算所有像素的灰阶平均值*/    
       $average = intval(array_sum($pixels) / count($pixels));    
    
       //获取图片指纹
       $hashStr = '';    
       foreach ($pixels as $gray){    
           $hashStr .= ($gray >= $average) ? '1' : '0';
       }
       return $hashStr;

    }
}


效果如下:

图片描述


以上程序测试用图如下

图片描述
图片描述
图片描述

随时随地学软件编程-关注百度小程序和微信小程序
关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[计算图片相似性]http://www.zyiz.net/tech/detail-228487.html

上一篇:聊聊使用lombok @Builder踩到的坑

下一篇:java语法基础:

赞(0)
关注微信小程序
程序员编程王-随时随地学编程

扫描二维码或查找【程序员编程王】

可以随时随地学编程啦!

技术文章导航 更多>
扫一扫关注最新编程教程