利用二进制搜索相似图片
因为使用的是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); }