PHP实现图片的汉明码提取与降维
作者感言:数学不好,遇到算法问题分分钟狗带,毫无转寰的余地-_-|||
最近心血来潮,看了相似图片的搜索,最最最初级的方法即提取汉明码,之后匹配汉明距离。当然,在数以亿计的汉明码中,要筛出需要的图片,计算量太大了,满足不了生产要求。作为数学小白,此时完全没折了。这时不小心看到“降维”一说,可以把降维后的哈希码存入数据库,加之分类的约束,基本满足小白初尝电商相似图片搜索的要求了:)
以下直接贴出代码(2017-8-17傍晚对降维做了调整):
class DFingerPrint
{
private $hImg=null;
private $hTargetImg=null;
private $arrResult=array(); private $fullBinData=''; const PRINT_WIDTH=8;
const PRINT_HEIGHT=8; public const DESC_DM_2=2;
public const DESC_DM_4=4;
public const DESC_DM_8=8; public function __construct($imgPath)
{
if(file_exists($imgPath))
{
$ext=$this->GetExt($imgPath);
$create_fun='';
switch($ext)
{
case 'jpg':
case 'jpeg':
$create_fun='imagecreatefromjpeg';
break;
case 'gif':
$create_fun='imagecreatefromgif';
break;
case 'png':
$create_fun='imagecreatefrompng';
break;
case 'bmp':
$create_fun='imagecreatefrombmp';
break;
default:
$create_fun='imagecreatefromgd2';
break;
} $this->hImg=$create_fun($imgPath);
if($this->hImg===false) $this->hImg=null;
} if($this->hImg)
{
$this->hTargetImg=imagecreatetruecolor(self::PRINT_HEIGHT,self::PRINT_HEIGHT);
}
} public function CalPrint()
{
if(!$this->hImg) return false;
if(!$this->SizeCompress()) return false;
if(!$this->ToGray()) return false;
if(!($binData=$this->Binaryzation())) return false; $this->fullBinData=$binData;
//$hexData=base_convert($binData,2,16); //这一句转出来问题,尾数错误,原因未知
$hexData=$this->Bin2Hex($binData); return array(
'bin'=>$binData,
'hex'=>$hexData
);
} public function DecendDimension($dm=8) //可指定降维参数,参数越大,精度缺失越多
{
if(!$this->fullBinData) return false;
if(!in_array($dm,array(self::DESC_DM_2,self::DESC_DM_4,self::DESC_DM_8))) return false; $len=strlen($this->fullBinData);
$newBinData='';
for($i=0,$iTmp=0;$i<$len;$i++)
{
$iTmp+=$this->fullBinData{$i}=='1'?1:-1; if($dm-($i%$dm)==1)
{
$newBinData.=$iTmp>0?1:0;
$iTmp=0;
}
} $hexData=$this->Bin2Hex($newBinData); return array(
'bin'=>$newBinData,
'hex'=>$hexData
);
} /*
public function DecendDimension($dm=1) //二值降维
{
if(!$this->arrResult) return false; $binData='';
for($x=0;$x<self::PRINT_WIDTH;$x++)
{
$rtl=0;
for($y=0;$y<self::PRINT_HEIGHT;$y++)
{
$rtl+=$this->arrResult[$x][$y]==1?1:-1;
}
$binData.=$rtl>0?'1':'0';
} $hexData=$this->Bin2Hex($binData); return array(
'bin'=>$binData,
'hex'=>$hexData
);
}
*/ private function SizeCompress() //尺寸压缩
{
if(!$this->hImg) return false; imagecopyresized($this->hTargetImg,$this->hImg,0,0,0,0,8,8,imagesx($this->hImg),imagesy($this->hImg));
return true;
} private function ToGray() //灰度化
{
for($x=0;$x<self::PRINT_WIDTH;$x++)
{
for($y=0;$y<self::PRINT_HEIGHT;$y++)
{
$color=imagecolorat($this->hTargetImg,$x,$y);
$_red = ($color >> 16) & 0xff;
$_green = ($color >> 8) & 0xff;
$_blue = ($color) & 0xff; $newColor= intval(0.3 * $_red + 0.59 * $_green + 0.11 * $_blue); $this->arrResult[$x][$y]=$newColor;
}
}
return true;
} private function Binaryzation() //二值化
{
if(!$this->arrResult) return false;
if(sizeof($this->arrResult)!=self::PRINT_WIDTH) return false; $totalVal=0;
$avgVal=0;
for($x=0;$x<self::PRINT_WIDTH;$x++)
{
for($y=0;$y<self::PRINT_HEIGHT;$y++)
{
$totalVal+=$this->arrResult[$x][$y];
}
}
$avgVal=$totalVal/(self::PRINT_HEIGHT*self::PRINT_HEIGHT); //开始二值化
$binData='';
for($x=0;$x<self::PRINT_WIDTH;$x++)
{
for($y=0;$y<self::PRINT_HEIGHT;$y++)
{
if($this->arrResult[$x][$y]>=$avgVal) $this->arrResult[$x][$y]=1;
else $this->arrResult[$x][$y]=0; //imagesetpixel($this->hTargetImg,$x,$y,$this->arrResult[$x][$y]==1?0xffffff:0x00);
$binData.=strval($this->arrResult[$x][$y]);
}
} return $binData;
} public function __destruct()
{
if($this->hImg)
{
imagedestroy($this->hImg);
$this->hImg=null;
}
if($this->hTargetImg)
{
imagedestroy($this->hTargetImg);
$this->hTargetImg=null;
} } private function GetExt($path)
{
$arr=explode('.',$path);
return strtolower($arr[sizeof($arr)-1]);
} private function Bin2Hex($bin)
{
$hex='';
$i=1;
while($bin)
{
$tmp_bin=substr($bin,-4,4);
$hex=base_convert($tmp_bin,2,16).$hex; $bin=substr($bin,0,strlen($bin)-4);
}
return $hex;
}
}
调用
$oFingerPrint=new DFingerPrint('1.jpg');
$arrPrint=$oFingerPrint->CalPrint();
$arrDescendPrint=$oFingerPrint->DecendDimension(DFingerPrint::DESC_DM_8);
查看资料:
http://blog.csdn.net/lu597203933/article/details/45101859
http://blog.csdn.net/cshilin/article/details/52119682
附:从MYSQL中查出指定汉明距离的的SQL语句:
SELECT uid,img_path,full_print2,
BIT_COUNT(CONVERT(CONV(full_print2, 16, 10),UNSIGNED) ^ CONVERT(CONV('ffffe229f9ffffff', 16, 10),UNSIGNED) ) as hamming_distance
FROM mvm_img_fingerprint
HAVING hamming_distance < 5
ORDER BY hamming_distance ASC;
PHP实现图片的汉明码提取与降维的更多相关文章
- python画图库及函数,绘制图片从文件提取出来的数据集转化为int,不然作为坐标轴的时候因为是字符串而无法排序
转化int:
- 使用SAP Leonardo上的机器学习服务提取图片的特征向量
要想提取图片的特征向量,首先得知道特征向量是什么. 我们假设这样一个服务场景,技师上门维修某设备,发现上面某零件损坏了,假设这位技师由于种种原因,没能根据自己的经验识别出这个零件的型号.此时技师掏出自 ...
- C# 提取Word文档中的图片
C# 提取Word文档中的图片 图片和文字是word文档中两种最常见的对象,在微软word中,如果我们想要提取出一个文档内的图片,只需要右击图片选择另存为然后命名保存就可以了,今天这篇文章主要是实现使 ...
- R+OCR︱借助tesseract包实现图片文本提取功能
2016年11月,Jeroen Ooms在CRAN发布了tesseract包,实现了R语言对简单图片的文本提取.分析功能. 利用开源OCR引擎进行图片处理,目前可以识别超过100种语言,R语言可以借助 ...
- 网页图片提取助手(支持背景图、选择dom范围)
网页图片提取助手(支持背景图.选择dom范围) 网页图片下载工具.网页图片批量保存. 使用场景: 作为web前端开发首——学习小生的你我,仿学在线页面是常有的事,但是一些在线资源,比如图片,图片有im ...
- Java 提取Word中的文本和图片
本文将介绍通过Java来提取或读取Word文档中文本和图片的方法.这里提取文本和图片包括同时提取文档正文当中以及页眉.页脚中的的文本和图片. 使用工具:Free Spire.Doc for Java ...
- Python opencv提取视频中的图片
作者:R语言和Python学堂链接:https://www.jianshu.com/p/e3c04d4fb5f3 这个函数就是本文要介绍的video2frames()函数,功能就是从视频中提取图片,名 ...
- opencv中对图片的二值化操作并提取特定颜色区域
一.最近因为所在的实习公司要求用opencv视觉库来写一个对图片识别并提取指定区域的程序.看了很多资料,只学会了皮毛,下面附上简单的代码.运行程序之前需要安装opencv库,官网地址为:https:/ ...
- SAP Leonardo图片处理相关的机器学习服务在SAP智能服务场景中的应用
本文作为Jerry最近正在做的一个项目的工作思路的梳理. 我们假设这样一个服务场景,技师上门维修某设备,发现设备上某零件损坏了,假设这位技师由于种种原因,没能根据自己的经验识别出这个零件的型号.此时技 ...
随机推荐
- Python匹马行天下之python之父
龟叔和他的python 经过了漫长的旅程,终于要看到主角Python了.Python是现在非常非常流行的编程语言,在我们能看到的大部分编程语言排行榜中,Python都能在前三甲中拥有一席之地 ,并且发 ...
- 【2018ACM/ICPC网络赛】沈阳赛区
这次网络赛没有打.生病了去医院了..尴尬.晚上回来才看了题补简单题. K Supreme Number 题目链接:https://nanti.jisuanke.com/t/31452 题意:输入一个 ...
- 使用kubeadm安装kubernetes 1.15
1.主机准备篇 使用vmware Workstation 10创建一台虚拟机,配置为2C/2G/50G,操作系统为CentOS Linux release 7.6.1810 (Core). IP地址为 ...
- 火狐浏览器缓存导致JS已经改变的ID没改变
问题主要就是火狐浏览器缓存. 比如,自己写一个JS,如下: $(document).ready(function () { $("#bigRoom").live("cli ...
- php数组的快速排序
function quick($array){ if(count($array)<=1){ return $array; } $key=$array[0]; $right=array(); $l ...
- Windows mkdir
创建目录. MKDIR [drive:]pathMD [drive:]path 如果命令扩展被启用,MKDIR 会如下改变: 如果需要,MKDIR 会在路径中创建中级目录.例如: 假设 \a 不存在, ...
- Spring有关面试问题
问题清单: 什么是Spring框架?Spring框架有哪些主要模块? 使用Spring框架有什么好处? 什么是控制反转(IOC)?什么是依赖注入? 请解释下Spring中的IOC? BeanFacto ...
- 本地项目通过 git 同步到 github
1. github创建仓库并克隆仓库地址 2. 在本地通过git命令:git clone <仓库地址> 生成github仓库文件夹 3. 将本地项目复制到该文件夹 4. 通过git命令:g ...
- 初识OpenCV-Python - 007: 平滑图像
本节内容主要将如何平滑图像.如通过低通道滤波模糊图像.或者自定义滤波处理图像. import cv2import numpy as npfrom matplotlib import pyplot as ...
- 如何在asp.net(C#)里用正则表达式验证手机号码