php实现简单验证码识别

Eddy 发布于2013-3-1 15:44:31 分类: 技术心得 已浏览loading 网友评论0条 我要评论


写了个简单验证码的识别程序,分享下。基本步骤就是二值化、去噪点、取字符、做字模库,最后利用字模库实现验证码识别

部分代码如下:


<?php
header('Content-type:text/html;charset=uft-8');

define('WORD_SPACING',9);//字符间距
define('LEFT',10);
define('TOP',9);
define('HEIGHT',15);
define('WIDTH',10);
define('COLOR', 215);//二值化阀值

$filePath = $_GET['p'].'.png';
list($width,$height) = getimagesize($filePath);
$rs = imagecreatefrompng($filePath);
$sourceData =array();

//取特征值
for ($i=0; $i < $height; $i++) { 
	for ($j=0; $j < $width; $j++) { 
		$index = imagecolorat($rs, $j, $i);
		$rgb = imagecolorsforindex($rs, $index);
		//print_r($rgb);
		if ($rgb['red']>COLOR && $rgb['blue']>COLOR && $rgb['green']>COLOR) {
			//echo '1';
			$sourceData[$i][$j]=0;	
		}else{
			//echo '0';
			$sourceData[$i][$j]=1;
		}
	}
}

//去噪点 阀值5
function clear($sourceData){
	$desData = array();
	$h =count($sourceData,0);
	$w =count($sourceData[0]);

	for ($i=1; $i < $h-1; $i++) { 
		for ($j=1; $j < $w-1; $j++) { 
			$value = $sourceData[$i-1][$j]+$sourceData[$i+1][$j]+$sourceData[$i][$j-1]+$sourceData[$i][$j+1]
                +$sourceData[$i-1][$j-1]+$sourceData[$i+1][$j+1]+$sourceData[$i-1][$j+1]+$sourceData[$i+1][$j-1];
			if ($value>=5) {
				$desData[$i-1][$j-1] = 1;
			}else{
				$desData[$i-1][$j-1] = 0;
			}
		}
	}
	return $desData;
}

//字符分割
function getCH($data){

	//第一个左上角坐标
	$x = LEFT -1;
	$y = TOP -1;

	$ch=0;
	for ($i=$y; $i < $y + HEIGHT; $i++) {
		for ($j=$x; $j < $x + WIDTH; $j++) { 
			$chData[0][$ch] = $data[$i][$j];
			$ch++;
		}
	}

	$ch=0;
	for ($i=$y; $i < $y + HEIGHT; $i++) {
		for ($j=$x + WIDTH + WORD_SPACING; $j < $x + 2 * WIDTH + WORD_SPACING; $j++) { 
			$chData[1][$ch] = $data[$i][$j];
			$ch++;
		}
	}

	$ch=0;
	for ($i=$y; $i < $y + HEIGHT; $i++) {
		for ($j=$x + 2*(WIDTH + WORD_SPACING); $j < $x + 3 * WIDTH + 2 * WORD_SPACING; $j++) { 
			$chData[2][$ch] = $data[$i][$j];
			$ch++;
		}
	}

	$ch=0;
	for ($i=$y; $i < $y + HEIGHT; $i++) {
		for ($j=$x + 3*(WIDTH + WORD_SPACING); $j < $x + 4 * WIDTH + 3 * WORD_SPACING; $j++) { 
			$chData[3][$ch] = $data[$i][$j];
			$ch++;
		}
	}

	return $chData;
}

/*显示
foreach ($desData as $value) {
	foreach ($value as $v) {
		if($v==1){
			echo '■';
		} else{
			echo '□';
		}//echo $v;
	}
	echo "<br />";
}*/

/*学习功能 制作字模库
foreach ($chData as $value) {
	echo "'";
	foreach ($value as $v) {
		echo $v;
	}
	echo "',<br />";
}*/

//识别验证码
function vertifyCode($chData){

	//字模
$typehead = require './zimo.php';

	$ch = array();
	$w = count($chData[0]);
	/*单个字符识别
	for ($i=0; $i < 10; $i++) { 
		$mount=0;
		for ($j=0; $j < $w; $j++) { 
			if ($chData[0][$j]==$typehead[$i][$j]) {
				$mount++;
			}
		}
		if ($w-$mount<15) {
			$ch[0]=$i;
			break;
		}
	}*/
	
	for ($i=0; $i < 4; $i++) { 
		$result = array();
		for ($k=0; $k < 10; $k++) { 
			$mount = 0;
		if (!is_array($typehead[$k])) {
			for ($j=0; $j < $w; $j++) {
					if ($chData[$i][$j]==$typehead[$k][$j]) {
						$mount++;
					}
			}
		}else{
			foreach ($typehead[$k] as $v) {
				$subMount = 0;
				$sub = array();
				for ($m=0; $m < $w; $m++) { 
					if ($chData[$i][$m] == $v[$m]) {
						$subMount++;
					}
				}
				$sub[]=$subMount;
			}
			$mount = max($sub);
		}
			if ($w-$mount<3) {
				$ch[$i]=$k;
				break;
			}else{
				$result[$k]=$w-$mount;
			}
		}
		//未匹配成功则取最优结果
		if (!isset($ch[$i])) {
			$ch[$i]=current(array_keys($result,min($result)));
		}
	}
	
	return $ch;
}

$desData = clear($sourceData);
$chData = getCH($desData);
$digtal = vertifyCode($chData);

$resul = '';
foreach ($digtal as $v) {
	$resul .= $v;
}

//输出识别结果
echo '识别结果:',$resul;

/*test
foreach ($desData as $value) {
	foreach ($value as $v) {
		echo $v;
	}
	echo "<br />";
}
*/

/*test
$im = imagecreate($width-OFFSET_X-RIGHT, $height - OFFSET_Y - BOTTOM);
$black = imagecolorallocate($im, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);
$h = count($desData,0);
$w = count($desData[0]);

for ($i=0; $i < $h; $i++) { 
	for ($j=0; $j < $w; $j++) { 
		if ($desData[$i][$j]==1) {
			imagesetpixel($im, $j, $i, $white);
		}
	}
}
header("Content-type: image/jpeg");
imagejpeg($im);
*/

?>

<?php
//zimo.php 字模数据,利用学习功能扩充字模库
//return array();具体见代码包
?>
完整程序下载:yzm.rar
需要带参数访问:http://127.0.0.1/yzm/index.php?p=具体文件名

已经有(0)位网友发表了评论,你也评一评吧!
原创文章如转载,请注明:转载自Eddy Blog
原文地址:http://www.rrgod.com/technique/871.html     欢迎订阅Eddy Blog

记住我的信息,下次不用再输入 欢迎给Eddy Blog留言