php实现简单验证码识别

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

[FONT-SIZE=3]

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

部分代码如下:

[CODE=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 "
";
}*/

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

//识别验证码
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 "
";
}
*/

/*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);
*/

?>

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

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

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