【圖像識別】簡單驗證碼識別

      思路:利用優優雲的驗證碼識別接口實現驗證碼中字符的識別,接口文檔可以到優優雲官網:www.uuwise.com 下載,這個接口不是免費的,得花錢賣虛擬幣,測試,調試時候聯繫技術會可以免費贈送一些虛擬幣,另需要註冊帳戶。我下的是一個PHP的接口在thinkPHP中開發。這個接口需要上傳驗證碼圖片才能識別,而一般驗證碼都是由程序生成,實際並不存在。如果只提供圖片的URL(如:www.abc.com/images/009.jpg)或者驗證碼的生成URL(如:www.abc.com/validateCode)甚至下載文件的隱式路徑(如:www.abc.com/down/1),這個接口是不能做識別的。它的接口demo原理是上傳圖片到一個目錄,在把這個圖片路徑地址傳值給一個uuGetUrl的方法。最後來識別,這樣對於動態是驗證碼是不現實的,我們需要自己寫一個下載程序,讓程序下載圖片到一個目錄,在把這個圖片目錄傳值給接口的uuGetUrl方法,識別成功後刪除這個驗證碼文件。


下載程序如下:

	//下載文件
	protected function downfile($extension)
	{
		$url = "http://nmgk2014.wx.px.teacher.com.cn/validateCode";
		$curl = curl_init($url);
		$filename = 'Runtime/Data/'.date("Ymdhis").".".$extension;
		curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
		$imageData = curl_exec($curl);
		curl_close($curl);
		$tp = @fopen($filename, 'a');
		fwrite($tp, $imageData);
		fclose($tp);	
		return realpath($filename);//dirname(__FILE__).'/../../../'.$filename;
	}

最後修改下UuApi 這個類文件中的upload 方法的上傳功能,因爲上傳功能我們用另外的程序完成。而不是我們手動完成。基本上就是註釋掉上傳功能


<?php
/**
	說明:此類函數是優優雲圖片識別平臺的API接口,調用類中的函數可以進行圖片識別
		 優優雲官網:www.uuwise.com
		 QQ:87280085
	注意:使用之前,需要在本文件同一個目錄下面建立一個everyone用戶可讀可寫的臨時圖片存放目錄,名稱爲:tempimg
	
	類中的公有函數:
		 setSoftInfo($softID,$softKey);				//設置軟件ID和KEY
		 userLogin($userName,$passWord);			//用戶登錄,登錄成功返回用戶的ID
		 getPoint($userName,$passWord);				//獲取用戶剩餘題分
		 upload($imagePath,$codeType);				//根據圖片路徑上傳,返回驗證碼在服務器的ID,$codeType取值查看:http://www.uuwise.com/price.html
		 getResult($codeID);						//根據驗證碼ID獲取識別結果
		 autoRecognition($imagePath,$codeType);		//將upload和getResult放到一個函數來執行,返回驗證碼識別結果
		 reportError($codeID);						//識別結果不正確報錯誤
		 regUser($userName,$userPassword)			//註冊新用戶,註冊成功返回新用戶的ID
		 pay($userName,$Card);						//充值題分,充值成功返回用戶當前題分
	
	類中的公有變量:
		 $macAddress='00e021ac7d';					//客戶機的mac地址,服務器暫時沒有用,後期準備用於綁定mac地址		賦值方法: $obj->macAddress='00e021ac7d'; 
		 $timeOut='60000';							//超時時間,建議不要改動此值									賦值方法: $obj->timeOut=60000;
		 
	函數調用方法:
		 需要先new一個對象
		 $obj=new uuApi;
		 $obj->setSoftInfo('2097','b7ee76f547e34516bc30f6eb6c67c7db');	//如何獲取這兩個值?請查看這個頁面:http://dll.uuwise.com/index.php?n=ApiDoc.GetSoftIDandKEY
		 $obj->userLogin('userName','userPassword');
		 $result=autoRecognition($imagePath,$codeType);
	錯誤代碼:
		-9999  臨時圖片目錄爲空! 需要在uuapi.php同目錄下建立一個everyone用戶可讀寫的tempimg目錄
		-9998  CodeID不是數字
*/

class UuApi{
	
	private $softID;
	private $softKEY;
	private $userName;
	private $userPassword;
	
	private $uid;
	private $userKey;
	private $softContentKEY;
	
	private $dest_folder = "tempimg/";	//臨時圖片文件夾
	private $uuUrl;
	private $uhash;
	private $uuVersion='1.1.0.1';
	private $userAgent;
	private $gkey;
	private $sessionIsMatch=true;
	
	private $enablelog = true;			//是否啓用日誌功能,true爲開啓,false爲關閉

	public $macAddress='00e021ac7d';	//客戶機的mac地址,服務器暫時沒有用,後期準備用於綁定mac地址		賦值方法: $obj->macAddress='00e021ac7d'; 
	public $timeOut=60000;				//超時時間,建議不要改動此值									賦值方法: $obj->timeOut=60000;
	
	public function setSoftInfo($id,$key)
	{
		if($id&&$key){
			$this->softID=$id;
			$this->softKEY=$key;
			$this->uhash=md5($id.strtoupper($key));
			return 'YES';
		}
		return 'NO';
	}
	private function iswriteable($file){
		if(is_dir($file)){
			$dir=$file;
			if($fp = @fopen("$dir/test.txt", 'w')){
				@fclose($fp);
				@unlink("$dir/test.txt");
				$writeable = true;
			}else{
				$writeable = false;
			}
		}else{
			if($fp = @fopen($file, 'a+')){
				@fclose($fp);
				$writeable = true;
			}else{
				$writeable = false;
			}
		}
		return $writeable;
	}
	private function getServerUrl($Server)
	{
		$url = "http://common.taskok.com:9000/Service/ServerConfig.aspx";
		$result=$this->uuGetUrl($url,array(),$postData=false);
		preg_match_all("/\,(.*?)\:101\,(.*?)\:102\,(.*?)\:103/", $result, $match_index);
		$arr=array_filter($match_index);
		if(empty($arr)){return '-1001';}
		switch($Server)
		{
			case 'service':
				return 'http://'.$match_index[1][0];
				break;
			case 'upload':
				return 'http://'.$match_index[2][0];
				break;
			case 'code':
				return 'http://'.$match_index[3][0];
				break;
			default:
				return '-1006';
				exit();
		}
		curl_close($this->uuUrl);
	}
	public function userLogin($userName,$passWord)
	{
		if(!($this->softID&&$this->softKEY))
		{
			return '-1';
		}
		if(!($userName&&$passWord)){ return '-1';}
		$this->userName=$userName;
		$this->userPassword=$passWord;
		$this->userAgent=md5(strtoupper($this->softKEY).strtoupper($this->userName)).$this->macAddress;
		
		@session_start();
		if(!(@$_SESSION['userKey'])){$this->sessionIsMatch=false;}
		if(!(@$_SESSION['uid'])){$this->sessionIsMatch=false;}

		if($this->sessionIsMatch){
			$this->userKey=$_SESSION['userKey'];
			$this->uid=$_SESSION['uid'];
			$this->softContentKEY=md5(strtolower($this->userKey.$this->softID.$this->softKEY));
			$this->gkey=md5(strtoupper($this->softKEY.$this->userName)).$this->macAddress;
			return $this->uid;
		}

		$url = $this->getServerUrl('service').'/Upload/Login.aspx?U='.$this->userName.'&P='.md5($this->userPassword).'&R='.mktime(time());
		$result=$this->uuGetUrl($url);
		if($result>0)
		{
			$this->userKey=$result;
			$_SESSION['userKey']=$this->userKey;
			$this->uid=explode("_",$this->userKey);
			$this->uid=$this->uid[0];
			$_SESSION['uid']=$this->uid;
			$this->softContentKEY=md5(strtolower($this->userKey.$this->softID.$this->softKEY));
			$this->gkey=md5(strtoupper($this->softKEY.$this->userName)).$this->macAddress;			
			return $this->uid;
		}
		return $result;

	}
	public function getPoint($userName,$passWord)
	{
		if(!($userName&&$passWord)){ return '-1';}
		if($this->softID<1){return '-1';}
		$url = $this->getServerUrl('service').'/Upload/GetScore.aspx?U='.$userName.'&P='.md5($passWord).'&R='.mktime(time()).'&random='.md5($userName.$this->softID);
		$result=$this->uuGetUrl($url);
		return $result;
	}
	public function upload($saveImgPath,$codeType,$auth=false)
	{	
/*		if(!file_exists($imageData["tmp_name"])){return '-1003';}
		if(!$this->iswriteable($this->dest_folder)){ return '-9999';};


		$fname = $imageData["name"];
		$fname_array = explode('.',$fname);
		$extend = $fname_array[count($fname_array)-1];
		$uptypes = array(
			image/jpg',
			image/jpeg',
			image/png',
			image/pjpeg',
			image/gif',
			image/bmp',
			image/x-png'
		);
		if(!in_array($imageData["type"],$uptypes)){return '-3007';}
		$randval = date('Y-m-dgis').'-'.mt_rand(1000000,9999999);
		$saveImgPath=$this->dest_folder.$randval.'.'.$extend;
		move_uploaded_file($imageData["tmp_name"],$saveImgPath);	//修改文件
		if(!file_exists(realpath($saveImgPath))){ return '-1003';};*/
		if(!is_numeric($codeType)){return '-3004';}
		$data=array(
			'img'=>'@'.$saveImgPath,//tempimg/2015-12-251212-1234567.jpg
			'key'=>$this->userKey,
			'sid'=>$this->softID,
			'skey'=>$this->softContentKEY,
			'TimeOut'=>$this->timeOut,
			'Type'=>$codeType
		);
		$ver=array(
			'Version'=>'100',
		);

		if($auth){$data=$data+$ver;}
		$url = $this->getServerUrl('upload').'/Upload/Processing.aspx?R='.mktime(time());
		$result=$this->uuGetUrl($url,$data);
		@unlink($saveImgPath);	//刪除上傳的文件
		return $result;
	}
	public function getResult($codeID)
	{
		if(!is_numeric($codeID)){return '-9998';}
		$url = $this->getServerUrl('code').'/Upload/GetResult.aspx?KEY='.$this->userKey.'&ID='.$codeID.'&Random='.mktime(time());
		$result='-3';
		$timer=0;
		while($result=='-3'&&($timer<$this->timeOut))
		{
			$result=$this->uuGetUrl($url,false,false);
			usleep(100000);	//一百毫秒一次
		}
		curl_close($this->uuUrl);
		if($result=='-3')
		{
			return '-1002';	
		}
		return $result;
	}
	public function autoRecognition($imagePath,$codeType)
	{
		$result=$this->upload($imagePath,$codeType,$auth=true);
		if($result>0){
			$arrayResult=explode("|",$result);
			if(!empty($arrayResult[1])){return $arrayResult[1];}
			return $this->getResult($result);
		}
		return $result;
	}
	private function uuGetUrl($url,$postData=false,$closeUrl=true)
	{
		$log=date('Y-m-d H:i:s').' 請求連接爲:'.$url."\r\n";

		$uid=isset($this->uid)?($this->uid):'100';
		$default=array(
			'Accept: text/html, application/xhtml+xml, */*',
			'Accept-Language: zh-CN',
			'Connection: Keep-Alive',
			'Cache-Control: no-cache',
			'SID:'.$this->softID,
			'HASH:'.$this->uhash,
			'UUVersion:'.$this->uuVersion,
			'UID:'.$uid,
			'User-Agent:'.$this->userAgent,
			'KEY:'.$this->gkey,
		);
		
		$this->uuUrl = curl_init();
		curl_setopt($this->uuUrl, CURLOPT_HTTPHEADER, ($default));
		curl_setopt($this->uuUrl, CURLOPT_TIMEOUT, $this->timeOut);
		curl_setopt($this->uuUrl, CURLOPT_URL,$url);
		curl_setopt($this->uuUrl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($this->uuUrl, CURLOPT_HEADER, false);
		curl_setopt($this->uuUrl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($this->uuUrl, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($this->uuUrl, CURLOPT_VERBOSE, false);
		curl_setopt($this->uuUrl, CURLOPT_AUTOREFERER, true);
		curl_setopt($this->uuUrl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($this->uuUrl, CURLOPT_HTTPGET, true);
		if($postData)
		{
			curl_setopt($this->uuUrl, CURLOPT_POST, true);
			curl_setopt($this->uuUrl, CURLOPT_POSTFIELDS, $postData);
		}

		$info=curl_exec($this->uuUrl);

		$log=$log.date('Y-m-d H:i:s').' 返回結果爲爲:'.$info."\r\n";
		$this->outlogs($log);
		if($info == false)
        {
			 //return "cURL Error (".curl_errno($this->uuUrl)."): ".curl_error($this->uuUrl)."\n"; //curl錯誤

			 $log=$log."cURL Error (".curl_errno($this->uuUrl)."): ".curl_error($this->uuUrl)."\r\n";
			 curl_close($this->uuUrl);
			 $this->outlogs($log);
			 return '-1002';
        }else {
			$this->outlogs($log);
			curl_close($this->uuUrl);
            return trim($info);
        }		
	}
	public function reportError($codeID)
	{
		if(!is_numeric($codeID)){return '-9998';}
		if($this->softContentKEY&&$this->userKey)
		{
			$url = $this->getServerUrl('code').'/Upload/ReportError.aspx?key='.$this->userKey.'&ID='.$codeID.'&sid='.$this->softID.'&skey='.$this->softContentKEY.'&R='.mktime(time());
			$result=$this->uuGetUrl($url);
			if($result=='OK')
			{
				return 'OK';	
			}
			return $result;
		}
		return '-1';
	}
	public function regUser($userName,$userPassword)
	{
		if($this->softID&&$this->softKEY)
		{
			if($userName&&$userPassword)
			{
				$data=array(
					'U'=>$userName,
					'P'=>$userPassword,
					'sid'=>$this->softID,
					'UKEY'=>md5(strtoupper($userName).$userPassword.$this->softID.strtolower($this->softKEY)),
				);
				$url=$this->getServerUrl('service').'/Service/Reg.aspx';
				return $this->uuGetUrl($url,$data);
			}
			return '-1';
		}
		return '-1';
	}
	
	public function pay($userName,$Card)
	{
		if($this->softID&&$this->softKEY)
		{
			if($userName&&$Card)
			{
				$data=array(
					'U'=>$userName,
					'card'=>$Card,
					'sid'=>$this->softID,
					'pkey'=>md5(strtoupper($userName).$this->softID.$this->softKEY.strtoupper($Card)),
				);
				$url=$this->getServerUrl('service').'/Service/Pay.aspx';
				return $this->uuGetUrl($url,$data);
			}
			return '-1';
		}
		return '-1';	
	}
	private function outlogs($str){
		if($this->enablelog){
			$logname=$this->dest_folder.'/UUWiselog'.date('Y-m-d').'.txt';
			if($this->iswriteable($logname)){
				$open=fopen($logname,"a" );
				fwrite($open,$str);
				fclose($open);
			}else{
				return '-9999';
			}
		}
	}
}
?>


最後,在thinkphp中找控制器地方新建這個接口類,上面的下載方法也沒有放在這個地方,比如TestCotroller.class.php 文件中

	//UU雲驗證碼識別
	public function uuapi()
	{

	    import('Vendor.UuApi.UuApi','',".php");
		
	    $obj=new \UuApi();
		$softID=2097;
		$softKey='b7ee76f547e34516bc30f6eb6c67c7db';
		$userName='whaooo';
		$passWord='123qwe';
		$codeType='1004';
		$imagePath=$this->downfile('jpg');
		//echo $imagePath;
		$obj->setSoftInfo($softID,$softKey);
		$loginStatus=$obj->userLogin($userName,$passWord);
		if($loginStatus>0){
			echo '您的用戶ID爲:'.$loginStatus.'<br/>';
			$getPoint=$obj->getPoint($userName,$passWord);
			echo '您帳戶內的剩餘題分還有:'.$getPoint.'<br/><br/>';	//負數就是錯誤代碼
			
			//下面開始識別				
			$result=$obj->autoRecognition($imagePath,$codeType);
		
			echo '您的圖片識別結果爲:'.$result;
		}else{echo '登錄失敗,錯誤代碼爲:'.$loginStatus.'<br/>';}	   
	
	} 

執行結果:



效率不是很高。。。。。。。。。。。。。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章