利用二进制搜索相似图片

因为使用的是TP5的框架,所以日常用的方法我都会封装好然后直接调用。

  /**  
     * 获取某个条件下的所有数组的指定字段信息
     * 
     * @access public 
     * @param mixed $tableName 数据表名
     * @param mixed $condition 查询条件 
     * @param mixed $order 排序条件
     * @param mixed $field 要查的字段名 
     * @return array 返回数据类型
     */
    function getSelect($tableName, $condition, $order, $field)
    {
        $arr = Db::name($tableName)->field($field)->where($condition)->order($order)->select();
        return $arr;
    }

  /**  
     * 获取分页查询数组信息
     * 
     * @access public 
     * @param mixed $tableName 数据表名
     * @param mixed $condition 查询条件 
     * @param mixed $order 排序条件
     * @param mixed $field 要查的字段名 
     * @param mixed $page 第几页 
     * @param mixed $pagesize 每页显示条数 
     * @return object 返回数据类型
     */
    function getPage($tableName, $condition, $order, $field, $page, $pagesize)
    {
        $arr = Db::name($tableName)->field($field)->where($condition)->order($order)->page($page, $pagesize)->select();
        return $arr;
    }

   /**  
     * 统计某个条件下的所有数组的数量
     * 
     * @access public 
     * @param mixed $tableName 数据表名
     * @param mixed $condition 查询条件 
     * @return int 返回数据类型
     */
    function getCount($tableName, $condition)
    {
        $num = Db::name($tableName)->where($condition)->count();
        return $num;
    }

  /**  
     * 获取某一字段的值
     * 
     * @access public 
     * @param mixed $tableName 数据表名
     * @param mixed $condition 查询条件 
     * @param mixed $field 要查的字段名 
     * @return string 返回数据类型
     */
    function getValue($tableName, $condition, $field)
    {
        $str = Db::name($tableName)->where($condition)->value($field);
        return $str;
    }

  /**
     * @title 通过图片链接将图片转换二进制
     * @description 通过图片链接将图片转换二进制
     * @author 卡卡
     * @param 文件url $imgUrl
     * @return string
     */
    function getHashValue($imgUrl){
        $w = 8;
        $h = 8;
        $img = imagecreatetruecolor($w, $h);

        # 获取图像信息
        $img_info = getimagesize($imgUrl);
        list($src_w, $src_h) = $img_info;

        # 图像的 MIME 信息
        $suffix_info = explode('/',$img_info['mime']);
        $extname = $suffix_info[1];
        if ($extname == 'jpg') {
            $extname = 'jpeg';
        }

        # 把第一个参数作为回调函数调用
        $src = call_user_func('imagecreatefrom'.$extname, $imgUrl);
        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';
            }
        }
        return $hash;
    }
获得要对比图片的二进制码之后,在数据库中进行比对,我取得是相似度80%以上的,拼接成字符串:
  /**
     * @title 要识别图片的ID数组集合
     * @description 获取要识别图片的ID数组集合
     * @author 卡卡
     * @method POST
     */
    public function get_similar_images()
    {
        $imgHashValue = input('imgHashValue');
        $list = getSelect('img_space',['status'=>1],'create_time desc','img_space_id,imgHashValue');
        $img_space_arr = [];
        for ($i=0; $i < count($list); $i++) { 
            $res = similar_text($imgHashValue,$list[$i]['imgHashValue'],$percent);
            if ($percent>=80) {
                array_push($img_space_arr,$list[$i]['img_space_id']);
            }
        }   
        $msg['img_space_ids'] = implode(",",$img_space_arr);
        return successJson($msg);
    }

PHP similar_text() 函数:https://www.w3school.com.cn/php/func_string_similar_text.asp


然后通过上诉方法得到的数组集合,在进行下一步的查询:

/**
     * @title 相似图片列表
     * @description 相似图片列表
     * @author 卡卡
     */
    public function similar_images()
    {
        $page = input('page');
        $pagesize = input('pagesize');
        $img_space_ids = input('img_space_ids');

        # 图片链接、图片id、图片相册id、图片相册名称、图片分类
        $map['type'] = 1;
        $map['status'] = 1;
        $list = getPage('img_space',$map,'create_time desc','img_space_id,img_album_id,category_id,file_path,file_name',$page,$pagesize);
        $msg['total'] = getCount('img_space',$map);
        foreach ($list as $key => $value) {
            $value['img_album_name'] = getValue('img_album',['img_album_id'=>$value['img_album_id']],'album_name');
            $value['cate_name'] = getValue('model_category',['category_id'=>$value['category_id']],'name');
            $list[$key] = $value;
        }
        $msg['list'] = $list;
        return successJson($msg);
    }

 

posted @ 2021-04-16 19:33  爱家家的卡卡  阅读(71)  评论(0编辑  收藏  举报