PHP实现图片的汉明码提取与降维

Posted 咚..咚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP实现图片的汉明码提取与降维相关的知识,希望对你有一定的参考价值。

作者感言:数学不好,遇到算法问题分分钟狗带,毫无转寰的余地-_-|||

最近心血来潮,看了相似图片的搜索,最最最初级的方法即提取汉明码,之后匹配汉明距离。当然,在数以亿计的汉明码中,要筛出需要的图片,计算量太大了,满足不了生产要求。作为数学小白,此时完全没折了。这时不小心看到“降维”一说,可以把降维后的哈希码存入数据库,加之分类的约束,基本满足小白初尝电商相似图片搜索的要求了:)

以下直接贴代码吧:

class DFingerPrint
{
    private $hImg=null;
    private $hTargetImg=null;
    private $arrResult=array();
    
    const PRINT_WIDTH=8;
    const PRINT_HEIGHT=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;
        
        //$hexData=base_convert($binData,2,16);    //这一句转出来问题,尾数错误,原因未知
        $hexData=$this->Bin2Hex($binData);
        
        return array(
            ‘bin‘=>$binData,
            ‘hex‘=>$hexData
        );
    }
    
    public function DecendDimension()    //二值降维
    {
        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‘);
$arrHammingCode=$oFingerPrint->CalPrint();
$arrDecendCode$oFingerPrint->DecendDimension();

 

查看资料:

http://blog.csdn.net/lu597203933/article/details/45101859

http://blog.csdn.net/cshilin/article/details/52119682

以上是关于PHP实现图片的汉明码提取与降维的主要内容,如果未能解决你的问题,请参考以下文章

机器学习 - 特征筛选与降维

携英第7期|聚类算法与降维操作

基于词向量使用Pytorch常规自编码器对句子进行向量表示与降维

机器学习40讲学习笔记15 从回归到分类:联系函数与降维

图像视频相似度算法

汉明码(海明码)解析