PHP验证码识别实例
PHP验证码识别实例
PHP验证码识别实例,识别的过程包括对图像的二值化、降噪、补偿、切割、倾斜矫正、建库、匹配,最后会提供实例代码,能够直接运行识别。
简述

要识别的验证码相对比较简单,没有粘连字符,但是会有几种不同程度的字体加粗,以及大约0-30度的倾斜,还有字符的个数会在4-5个之间变化,相对来说还是使用Python进行验证码识别比较简单,如果有需要可以参考文章
强智教务系统验证码识别 OpenCV
强智教务系统验证码识别 Tensorflow CNN
二值化
图像都是由各个像素点组成,每个像素点可以量化成为rgb三种颜色值,根据验证码的颜色,调整三种颜色的阈值,将背景与字符过滤出来,背景置1,字符置0。
// 二值化
private static function binaryImage($image){
$img = [];
for($y = 0;$y < self::$width;$y++) {
for($x =0;$x < self::$height;$x++) {
if($y === 0 || $x === 0 || $y === self::$width - 1 || $x === self::$height - 1){
$img[$x][$y] = 1;
continue;
}
$rgb = imagecolorat($image, $y, $x);
$rgb = imagecolorsforindex($image, $rgb);
if($rgb['red'] < 255 && $rgb['green'] < 230 && $rgb['blue'] < 220) {
$img[$x][$y] = 0;
} else {
$img[$x][$y] = 1;
}
}
}
return $img;
}
1111111111111111111111111111011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111100000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111110000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111110000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100100111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111100111111111111111111111111111111111111111111111111000111111111111111111111111111111111111111111100000011111111111111111111111111111111111111
1111111111111111000000000000001111111111111111111111111111110000000011111111100000001111111111111111111111000000000000111111111111111111111111111111111111110000000000011111111111111111111111111111111111000000000000001111111111111111111111111111111111
1111111111111111100000100000001111111111111111111111111111110000000111111111000000001111111111111111111110000000000000001111111111111111111111111111111111100000000000000111111111111111111111111111111110000000000000000111111111111111111111111111111111
1111111111111111100000000000001111111111111111111111111111110000000111111111000000001111111111111111111100000000000000000111111111111111111111111111111110000000000000000011111111111111111111111111111100000000000000000001111111111111111111111111111111
1111111111111111100000000011101111111111111111111111111111110000100111111111000000011111111111111111111000000111110000000111111111111111111111111111111110000000000000000001111111111111111111111111111000000000000000000001111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000100111111111000000011111111111111111111000011111111100000111111111111111111111111111111100000000000000000000111111111111111111111111111000000000010000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000101111111111000000011111111111111111110000011111111110000011111111111111111111111111111000000001111110000000111111111111111111111111110000000111111110000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000001111111111000000011111111111111111110000011111111110000011111111111111111111111111111001000011111110000000011111111111111111111111110000000111111110000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000001111111110000000011111111111111111110000011111111111111111111111111111111111111111110000000011111111000000011111111111111111111111110000000111111111001111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000001111111110000000111111111111111111111000001111111111111111111111111111111111111111110000000111111111000000011111111111111111111111110000000000111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111110000000111111111111111111111000000011111111111111111111111111111111111111110100000111111111100000001111111111111111111111111000000000001111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111110000000111111111111111111111000000000001111111111111111111111111111111111100000000001010111100000001111111111111111111111111000000000000000011111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111100000000111111111111111111111100000000000001111111111111111111111111111111100000000000000000000000001111111111111111111111111000000000000000000011111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111100000001111111111111111111111110000000001000001111111111111111111111111111100000000000010110000011001111111111111111111111111100000000000000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111100000001111111111111111111111111100000000000000011111111111111111111111111100000000000000010000110001111111111111111111111111110000000000000110000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000011111111100000001111111111111111111111111111100000000000011111111111111111111111111110000000000000000000000001111111111111111111111111111100000000000000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000111111111000000001111111111111111111111111111111110000000001111111111111111111111111110000000111111111111111111111111111111111111111111111111110000000000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000111111111000000001111111111111111111111111111111111110000001111111111111111111111111110000000111111111111111111111111111111111111111111111111111110000000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000001111111111000000001111111111111111111111110111111111111000001111111111111111111111111110000000111111111011111111111111111111111111111111111101111111111000000001111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000001111111110000000011111111111111111111110000111111111111100001111111111111111111111111110000000011111111000001011111111111111111111111100000000111111111001000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000001111111100000000011111111111111111111110000011111111111100001111111111111111111111111111000000011111110000000011111111111111111111111100000000111111111001000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000000111111000000000011111111111111111111110000011111111111000001111111111111111111111111111000000001111110000000011111111111111111111111100000000011111111000100011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000000001000000000000111111111111111111111111000001111111110000011111111111111111111111111111000000000000000000000111111111111111111111111110000000000000000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000000000000000000111111111111111111111111000000001111100000011111111111111111111111111111100000100000000000000111111111111111111111111111000000000000000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000000000011000100111111111111111111111111100000000000000000011111111111111111111111111111110000000000000000001111111111111111111111111111100000000000000000001111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000000000110000000111111111111111111111111110001000010000001111111111111111111111111111111111100000000000000011111111111111111111111111111110000000000000000011111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000000001110000000111111111111111111111111111000000000000011111111111111111111111111111111111110000000000001111111111111111111111111111111111000000000000001111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111000011111111111111111111111111111111111111111111100000111111111111111111111111111111111111111111111000011111111111111111111111111111111111111111110000111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
降噪 补偿
验证码经常会加入一些噪点,这些噪点一般都是单独的点,有时候会加入几个单像素点连成干扰线,降噪的时候就需要去掉噪点与干扰线,我采用了将每个像素点周围四个像素点的值取出,计算如果周围四个像素点有两个以上是背景,也就是1的话,那么就认为这个是噪点,将其设为背景,也就是1。
当二值化的时候,不可避免的会将字符中一些小像素点过滤成了背景,此时就需要补偿这个字符,也是同样采用将周围四个字符进行统计,如果周围四个像素点有两个以上都是字符,也就是0,那么就认为这个像素点也是字符像素点,将其设为字符,也就是0。
// 降噪 补偿
private static function noiseReduce($img) {
$xCount = count($img[0]);
$yCount = count($img);
for ($i=1; $i < $yCount-1 ; $i++) {
for ($k=1; $k < $xCount-1; $k++) {
if($img[$i][$k] === 0){
$countOne = $img[$i][$k-1] + $img[$i][$k+1] + $img[$i+1][$k] + $img[$i-1][$k];
if($countOne > 2) $img[$i][$k] = 1;
}
if($img[$i][$k] === 1){
$countZero = $img[$i][$k-1] + $img[$i][$k+1] + $img[$i+1][$k] + $img[$i-1][$k];
if($countZero < 2) $img[$i][$k] = 0;
}
}
}
return $img;
}
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111100000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111110000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111110000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111111111111111111111111111111111111111111111111111111100111111111111111111111111111111111111111111111111000111111111111111111111111111111111111111111100000011111111111111111111111111111111111111
1111111111111111100000000000001111111111111111111111111111110000000111111111100000001111111111111111111111000000000000111111111111111111111111111111111111110000000000011111111111111111111111111111111111000000000000001111111111111111111111111111111111
1111111111111111100000000000001111111111111111111111111111110000000111111111000000001111111111111111111110000000000000001111111111111111111111111111111111100000000000000111111111111111111111111111111110000000000000000111111111111111111111111111111111
1111111111111111100000000000001111111111111111111111111111110000000111111111000000001111111111111111111100000000000000000111111111111111111111111111111110000000000000000011111111111111111111111111111100000000000000000001111111111111111111111111111111
1111111111111111100000000011111111111111111111111111111111110000000111111111000000011111111111111111111000000111110000000111111111111111111111111111111110000000000000000001111111111111111111111111111000000000000000000001111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000000111111111000000011111111111111111111000011111111100000111111111111111111111111111111100000000000000000000111111111111111111111111111000000000000000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000001111111111000000011111111111111111110000011111111110000011111111111111111111111111111000000001111110000000111111111111111111111111110000000111111110000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000001111111111000000011111111111111111110000011111111110000011111111111111111111111111111000000011111110000000011111111111111111111111110000000111111110000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000001111111110000000011111111111111111110000011111111111111111111111111111111111111111110000000011111111000000011111111111111111111111110000000111111111001111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000001111111110000000111111111111111111111000001111111111111111111111111111111111111111110000000111111111000000011111111111111111111111110000000000111111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111110000000111111111111111111111000000011111111111111111111111111111111111111110000000111111111100000001111111111111111111111111000000000001111111111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111110000000111111111111111111111000000000001111111111111111111111111111111111100000000000000111100000001111111111111111111111111000000000000000011111111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111100000000111111111111111111111100000000000001111111111111111111111111111111100000000000000000000000001111111111111111111111111000000000000000000011111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111100000001111111111111111111111110000000000000001111111111111111111111111111100000000000000000000010001111111111111111111111111100000000000000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000011111111100000001111111111111111111111111100000000000000011111111111111111111111111100000000000000000000000001111111111111111111111111110000000000000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000011111111100000001111111111111111111111111111100000000000011111111111111111111111111110000000000000000000000001111111111111111111111111111100000000000000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000111111111000000001111111111111111111111111111111110000000001111111111111111111111111110000000111111111111111111111111111111111111111111111111110000000000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000111111111000000001111111111111111111111111111111111110000001111111111111111111111111110000000111111111111111111111111111111111111111111111111111110000000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000001111111111000000001111111111111111111111111111111111111000001111111111111111111111111110000000111111111111111111111111111111111111111111111111111111111000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000001111111110000000011111111111111111111110000111111111111100001111111111111111111111111110000000011111111000000011111111111111111111111100000000111111111000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000001111111100000000011111111111111111111110000011111111111100001111111111111111111111111111000000011111110000000011111111111111111111111100000000111111111000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000000111111000000000011111111111111111111110000011111111111000001111111111111111111111111111000000001111110000000011111111111111111111111100000000011111111000000011111111111111111111111111111
1111111111111111111100000111111111111111111111111111111100000000000000000000000111111111111111111111111000001111111110000011111111111111111111111111111000000000000000000000111111111111111111111111110000000000000000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000000000000000000111111111111111111111111000000001111100000011111111111111111111111111111100000000000000000000111111111111111111111111111000000000000000000000111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111110000000000000010000000111111111111111111111111100000000000000000011111111111111111111111111111110000000000000000001111111111111111111111111111100000000000000000001111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111000000000000110000000111111111111111111111111110000000000000001111111111111111111111111111111111100000000000000011111111111111111111111111111110000000000000000011111111111111111111111111111111
1111111111111111111100000111111111111111111111111111111111100000000001110000000111111111111111111111111111000000000000011111111111111111111111111111111111110000000000001111111111111111111111111111111111000000000000001111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111000011111111111111111111111111111111111111111111100000111111111111111111111111111111111111111111111000011111111111111111111111111111111111111111110000111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
切割
由于此验证码并没有粘连,对于字符的切割相对而言比较简单,纵向统计出切割字符的起始与终止位置,切割后分别置入数组中,然后将横向的空白去除,同样也是统计字符有0值的起始行与终止行,再做切割,仅保留字符。
// 裁剪
private static function cutImg($img){
$xCount = count($img[0]);
$yCount = count($img);
$xFilter = [];
for($x = 0;$x < $xCount;$x++) {
$filter = true;
for($y = 0;$y < $yCount;$y++) $filter = $filter && ($img[$y][$x] === 1);
if($filter) $xFilter[] = $x;
}
$xImage = array_values(array_diff(range(0, $xCount-1), $xFilter));
$wordImage = [];
$preX = $xImage[0] - 1;
$wordCount = 0;
foreach($xImage as $xKey => $x) {
if($x != ($preX + 1)) $wordCount++;
$preX = $x;
for($y = 0;$y < $yCount;$y++) $wordImage[$wordCount][$y][] = $img[$y][$x];
}
$cutImg = [];
foreach($wordImage as $i => $image) {
$xCount = count($image[0]);
$yCount = count($image);
$start = 0;
for ($j=0; $j < $yCount; ++$j) {
$stopFlag = false;
for ($k=0; $k < $xCount; ++$k) {
if ($image[$j][$k] === 0) {
$start = $j;
$stopFlag = true;
break;
}
}
if($stopFlag) break;
}
$stop = $yCount-1;
for ($j=$yCount-1; $j >= 0; --$j) {
$stopFlag = false;
for ($k=0; $k < $xCount; ++$k) {
if ($image[$j][$k] === 0) {
$stop = $j;
$stopFlag = true;
break;
}
}
if($stopFlag) break;
}
for ($k=$start; $k <= $stop ; ++$k) {
$cutImg[$i][] = $image[$k];
}
// self::showImg($cutImg[$i]);
$cutImg[$i] = self::adjustImg($cutImg[$i]);
// self::showImg($cutImg[$i]);
}
return $cutImg;
}
1111111111111000001111111
1111111100000000000001111
1111111000000000000000011
1111110000000000000000011
1111100000000000000000001
1111000000001111000000001
1110000000011111100000000
1110000000111111110000000
1111111111111111110000000
1111111111111111110000000
1111111111111111100000001
1111111100000000000000001
1111100000000000000000001
1110000000000000000000001
1100000000000000000000001
1000000000000111100000011
1000000001111111000000011
1000000011111111000000011
0000000111111111000000011
0000000111111110000000111
0000000111111100000000111
0000000011111000000000111
1000000001100000000000111
1000000000000000000000111
1000000000000000000000111
1100000000000010000000111
1111000000001110000000111
1111100001111111111111111
倾斜矫正
对于倾斜矫正我尝试了两种方案,一个是使用线性回归,另一个是使用投影法。
线性回归
使用线性回归,取得每一行上字符像素点的中点的坐标,使用最小二乘法拟合曲线,得到一个斜率,也就相当于得到了这个字符的倾斜角度,然后根据斜率来矫正这个字符的倾斜度,这个方式对于n这样的字符效果比较不错,但是对于j这样的字符效果就比较差。
$img = [
[1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1],
[1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0],
[1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
[1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0],
[1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
[1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
[1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1],
[1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1],
[1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1],
[1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1],
[1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1],
[1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1],
[1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1],
[1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1],
[1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1],
[1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1],
];
ImgIdenfy::showImg($img);
$mixX = 0.0;
$mixY = 0.0;
$mixXX = 0.0;
$mixXY = 0.0;
$yCount = count($img);
$xCount = count($img[0]);
foreach($img as $i => $line) {
$x = 0;
$xValidCount = 0;
foreach($line as $k => $unit) {
if($unit === 0) {
$x += $k;
++$xValidCount;
}
}
if($xValidCount) {
$pointX = $x/$xValidCount;
$pointY = $yCount - $i;
$mixX += $pointX;
$mixY += $pointY;
$mixXX += ($pointX*$pointX);
$mixXY += ($pointX*$pointY);
}
}
$linearK = -($mixXY - $mixX*$mixY/$yCount) / ($mixXX - $mixX*$mixX/$yCount);
// if($linearK > -1 && $linearK < 1) return $img;
$whirlImg = [];
foreach($img as $i => $line) {
$pointY = $i;
if(!isset($whirlImg[$pointY])) $whirlImg[$pointY]=[];
foreach($line as $pointX => $unit) {
if(!isset($whirlImg[$pointY][$pointX])) $whirlImg[$pointY][$pointX]=1;
// $newY = (int)($pointY*sqrt(1+$linearK*$linearK)/$linearK);
$newY = (int)($pointY);
$newX = (int)($pointX-$pointY/$linearK);
if($newX >= 0 && $newX < $xCount && $newY >= 0 && $newY < $yCount) $whirlImg[$newY][$newX] = $unit;
}
}
$finishedImg = [];
for ($i=0; $i < $xCount; ++$i) {
for($k=0; $k < $yCount; ++$k) {
if($whirlImg[$k][$i] !== 1){
for($y = 0;$y < $yCount;++$y) $finishedImg[$y][] = $whirlImg[$y][$i];
break;
}
}
}
ImgIdenfy::showImg($finishedImg);
111110000111100000000011
111110000111000000000001
111100001110000000000000
111100000000000111100000
111100000000111111110000
111100000001111111110000
111100000011111111110000
111000000111111111110000
111000000111111111110000
111000001111111111110000
111000001111111111100000
111000011111111111100000
110000011111111111100001
110000011111111111000001
110000111111111111000001
110000111111111111000001
110000111111111111000001
100000111111111111000011
100000111111111111000011
100000111111111110000011
100001111111111110000011
100001111111111110000011
000011111111111110000111
000011111111111110000111
000011111111111100000111
000011111111111100000111
10000111100000000011
10000111000000000001
00001110000000000000
00000000000111100000
00000000111111110000
10000000111111111000
10000001111111111000
00000011111111111000
00000011111111111000
00000111111111111000
10000011111111111000
10000111111111111000
00000111111111111000
00000111111111110000
00001111111111110000
10000111111111111000
10000111111111111000
00000111111111111000
00000111111111111000
00000111111111110000
10000111111111111000
10000111111111111000
00001111111111111000
00001111111111111000
00001111111111110000
10000111111111111000
投影法
由于直接线性拟合的方式对于一些字符的效果比较差,于是采用投影法的方式,字符如果进行旋转,那么他的宽度势必会增加,于是可以在一定范围内尝试旋转字符,取得旋转过程中宽度最小时的字符,就是矫正后的字符。由于直接将竖直的字符根据斜率旋转的话,因为tan90°不存在,不好界定逆时针旋转的范围,于是首先将字符数组进行转置,然后就可以在斜率-0.5-0.5的范围内顺时针旋转,然后再将其转置回即可,我在实现的过程中有比较多的重复运算,这个主要是需要数学推算,而我是一步步实现的计算,还有就是旋转的过程中如果字符宽度由小到大变化的时候就可以逆向运算或者停止运算了,就像一个梯度下降的方式,此外我并没有使用矩阵方式的运算,如果使用矩阵的话实现会比较简单,PHP中有PHP-ML这样的机器学习库,其中就有矩阵运算方面的方法,当然也可以直接使用PHP-ML进行神经网络的训练。
// 旋转
private static function whirl($img, $yCount, $xCount, $linearK){
$whirlImg = [];
foreach($img as $i => $line) {
$pointY = $yCount - $i - 1;
if(!isset($whirlImg[$pointY])) $whirlImg[$pointY]=[];
foreach($line as $pointX => $unit) {
if(!isset($whirlImg[$pointY][$pointX])) $whirlImg[$pointY][$pointX]=1;
$newY = (int)($pointY - $pointX*$linearK);
$newX = (int)($pointX);
if($unit === 0 && ($newY < 0 || $newY >= $yCount)) return [$yCount+1, $img];
if($newX >= 0 && $newX < $xCount && $newY >= 0 && $newY < $yCount) $whirlImg[$newY][$newX] = $unit;
}
}
$cutImg = [];
$height = $yCount;
foreach ($whirlImg as $j => $line) {
foreach ($line as $k => $v) {
if($v !== 1) {
--$height;
break;
}
}
}
return [$yCount - $height, $whirlImg];
}
// 倾斜调整
private static function adjustImg($img){
$reverseImg = [];
$yCount = count($img);
$xCount = count($img[0]);
for ($i=0; $i < $yCount; ++$i) {
$pointY = $yCount - $i - 1;
for($k=0; $k < $xCount; ++$k) {
$reverseImg[$k][$i] = $img[$pointY][$k];
}
}
list($yCount,$xCount) = [$xCount,$yCount];
$min = $yCount;
$minImg = $reverseImg;
for ($k= -0.5 ; $k <= 0.5; $k = $k + 0.05) {
list($tempMin, $tempMinImg) = self::whirl($reverseImg, $yCount, $xCount, $k);
if($tempMin < $min) {
$min = $tempMin;
$minImg = $tempMinImg;
}
}
$removedImg = [];
foreach ($minImg as $j => $line) {
foreach ($line as $k => $v) {
if($v !== 1) {
$removedImg[] = $line;
break;
}
}
}
$reverseImg = [];
$xCount = count($removedImg[0]);
$yCount = count($removedImg);
$reverseImg = [];
for ($i=0; $i < $xCount; ++$i) {
for($k=0; $k < $yCount; ++$k) {
$pointX = $xCount - $i - 1;
$reverseImg[$i][$k] = $removedImg[$k][$pointX];
}
}
return $reverseImg;
}
1111111111111000001111111
1111111100000000000001111
1111111000000000000000011
1111110000000000000000011
1111100000000000000000001
1111000000001111000000001
1110000000011111100000000
1110000000111111110000000
1111111111111111110000000
1111111111111111110000000
1111111111111111100000001
1111111100000000000000001
1111100000000000000000001
1110000000000000000000001
1100000000000000000000001
1000000000000111100000011
1000000001111111000000011
1000000011111111000000011
0000000111111111000000011
0000000111111110000000111
0000000111111100000000111
0000000011111000000000111
1000000001100000000000111
1000000000000000000000111
1000000000000000000000111
1100000000000010000000111
1111000000001110000000111
1111100001111111111111111
111111111110000011111111
111111000000000000011111
111110000000000000000111
111100000000000000000111
111000000000000000000011
110000000011110000000011
100000000111111000000001
100000001111111100000001
111111111111111110000000
111111111111111110000000
111111111111111100000001
111111100000000000000001
111100000000000000000001
110000000000000000000001
100000000000000000000001
000000000000111100000011
000000001111111000000011
000000011111111000000011
000000011111111100000001
000000011111111000000011
000000011111110000000011
000000001111100000000011
100000000110000000000011
100000000000000000000011
100000000000000000000011
110000000000001000000011
111100000000111000000011
111110000111111111111111
建库
将验证码矫正过后,就需要建立特征匹配库了,这里我直接使用了将二值化的数组转化为字符串全部作为特征写入一个特征匹配数组,再手动打码,若是识别出的字符与我手动打码的字符不符,就将其加入特征匹配数组,然后将字符数组序列化存储到文件中,然后将这个序列化后的字符串进行压缩,存储到文件中,我提取的特征数组有150个字符特征码,占用约8KB,注意我这是将PHP作为脚本使用的,配置好环境变量写入空数据后再使用php Build.php即可开始提取特征码。
// 写入空序列化数组
// $info = serialize([]);
// $library = fopen("library", "w+");
// fwrite($library,gzcompress($info));
// fclose($library);
$library = fopen("library", "r+");
$info = fread($library,filesize("library"));
if(!$info) $charMap = [];
else $charMap = unserialize(gzuncompress($info));
while (1) {
$img = imagecreatefromjpeg("http://grdms.sdust.edu.cn:8081/security/jcaptcha.jpg"); //获取图片
imagejpeg($img,"v.jpg"); // 写入硬盘
list($result, $imgStringArr) = ImgIdenfy::build($img, $charMap, 250, 100);
echo($result."\n");
$input = fgets(STDIN);
if(isset($input[0]) && $input[0] === "$") break;
$n = strlen($input) - 2;
for ($i=0; $i < $n; $i++) {
if(!isset($result[$i]) || $input[$i] !== $result[$i]) $charMap[$input[$i].mt_rand(1, 10000)] = $imgStringArr[$i];
}
echo count($charMap)."\n";
ftruncate($library,0);
rewind($library);
fwrite($library,gzcompress(serialize($charMap)));
}
fclose($library);
匹配
由于是直接将全部的特征信息存入文件,直接使用循环对比字符串的值即可,为了提高准确率,我将两个对比字符串的第一个0进行对齐,然后再进行遍历,取得相同字符的数量,此外由于对比的字符串的长度不同,将字符串的长度信息乘以一定权值也作为一部分信息计入相似度中,当然PHP中提供了similar_text函数进行字符串相似度对比,使用此函数的话识别率会提升,但是由于字符串长度过长,对比匹配的时间比较慢,权衡时间消耗与正确率还是选择了自行匹配的方式。
// 对比
private static function comparedText($s1,$s2){
$s1N = strlen($s1);
$s2N = strlen($s2);
$i = -1;
$k = -1;
$percent = -abs($s1N - $s2N) * 0.1;
while(++$i<$s1N && $s1[$i]) {}
while(++$k<$s2N && $s2[$k]) {}
while ($i<$s1N && $k<$s2N) ($s1[$i++] === $s2[$k++]) ? $percent++ : "";
return $percent;
// $percent = 0;
// $N = $s1N < $s2N ? $s1N : $s2N;
// for ($i=0; $i < $N; ++$i) {
// ($s1[$i] === $s2[$i]) ? $percent++ : "";
// }
// return $percent;
}
// 匹配
private static function matchCode($imgGroup,$charMap){
$record = "";
$imgStringArr = [];
foreach ($imgGroup as $img) {
$maxMatch = 0;
$tempRecord = "";
$s = ImgIdenfy::getString($img);
foreach ($charMap as $key => $value) {
// similar_text(ImgIdenfy::getString($img),$value,$percent);
$percent = self::comparedText($s , $value);
if($percent > $maxMatch){
$maxMatch = $percent;
$tempRecord = $key[0];
}
}
$record = $record.$tempRecord;
$imgStringArr[] = $s;
}
return [$record, $imgStringArr];
}
实例代码
如果觉得不错,点个star吧
https://github.com/WindrunnerMax/Example
PHP验证码识别实例的更多相关文章
- Python验证码识别处理实例(转载)
版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka 一.准备工作与代码实例 1.PIL.pytesser.tesseract ...
- Python验证码识别处理实例(转)
一.准备工作与代码实例 1.PIL.pytesser.tesseract (1)安装PIL:下载地址:http://www.pythonware.com/products/pil/(CSDN下载) 下 ...
- Python3 简单验证码识别思路及实例
1.介绍 在爬虫中经常会遇到验证码识别的问题,现在的验证码大多分计算验证码.滑块验证码.识图验证码.语音验证码等四种.本文就是识图验证码,识别的是简单的验证码,要想让识别率更高, 识别的更加准确就需要 ...
- 【转】Python验证码识别处理实例
原文出处: 林炳文(@林炳文Evankaka) 一.准备工作与代码实例 1.PIL.pytesser.tesseract (1)安装PIL:下载地址:http://www.pythonware.com ...
- Python验证码识别处理实例
一.准备工作与代码实例 1.PIL.pytesser.tesseract (1)安装PIL:下载地址:http://www.pythonware.com/products/pil/(CSDN下载) 下 ...
- python验证码识别
关于利用python进行验证码识别的一些想法 用python加“验证码”为关键词在baidu里搜一下,可以找到很多关于验证码识别的文章.我大体看了一下,主要方法有几类:一类是通过对图片进行处 理,然后 ...
- 使用python及工具包进行简单的验证码识别
相信大家利用 Python 写的爬虫应该遇到过要输入验证码的尴尬局面,又或者写了个自动填充表单的小程序,结果就卡在了验证码上. 在ctf中有⼀一些题⽬目,本身有弱验证码识别绕过,那么我们怎么解决呢? ...
- 利用jTessBoxEditor工具进行Tesseract3.02.02样本训练,提高验证码识别率
1.背景 前文已经简要介绍tesseract ocr引擎的安装及基本使用,其中提到使用-l eng参数来限定语言库,可以提高识别准确率及识别效率. 本文将针对某个网站的验证码进行样本训练,形成自己的语 ...
- 关于利用python进行验证码识别的一些想法
转载:@小五义http://www.cnblogs.com/xiaowuyi 用python加“验证码”为关键词在baidu里搜一下,可以找到很多关于验证码识别的文章.我大体看了一下,主要方法有几类: ...
- 字符型图片验证码识别完整过程及Python实现
字符型图片验证码识别完整过程及Python实现 1 摘要 验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的 防火墙 功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越 ...
随机推荐
- ubuntu-软件管理工具-apt
- 一个轻量快速的C++日志库
limlog 作一篇文章记录实现,驱动优化迭代. 代码仓库 用法 实现 后端实现 前端实现 日期时间的处理 线程id的获取 日志行的其他项处理 优化 整形字符串格式化优化 测试 benchmark 性 ...
- [转帖]JVM参数配置及调优
https://cloud.tencent.com/developer/article/2235751 JVM参数分类 jvm 参数可分为三类: 标准参数:以 "-" 开头的参数 ...
- [转帖]Nginx 安全优化
目录 前言 1.使用 SSL/TLS 证书 2.使用安全密钥交换机制 3.禁用旧的 SSL/TLS 协议 4.禁用 SSL/TLS 弱密码套件 5.禁用不需要的 HTTP 方法 6.防止缓冲区溢出攻击 ...
- TiKV占用内存超过的解决过程
TiKV占用内存超过的解决过程 背景 为了后去TiDB的极限数据. 晚上在每台服务器上面增加了多个TiKV的节点. 主要方式为: 每个NVME的硬盘增加两个TiKV的进程. 这样每个服务器两个磁盘, ...
- [转帖]RocketMQ - nameSrv和Broker
RocketMQ RocketMQ是一个统一的消息传递引擎,轻量级的数据处理平台. Name Server Name Server充当路由消息的提供者,生产者(Producer)或消费者(Custom ...
- [转帖]linux系统下grub.cfg详解和实例操作
linux系统下grub.cfg详解和实例操作 简介 grub是引导操作系统的程序,它会根据自己的配置文件,去引导内核,当内核被加载到内存以后,内核会根据grub配置文件中的配置,找到根分区所使用的文 ...
- 【转帖】【ethtool】ethtool 网卡诊断、调整工具、网卡性能优化| 解决丢包严重
目录 即看即用 详细信息 软件简介 安装 ethtool的使用 输出详解 其他指令 将 ethtool 设置永久保存 如何使用 ethtool 优化 Linux 虚拟机网卡性能 ethtool 解决网 ...
- [转帖]在龙芯3A5000上测试SPEC CPU 2006
https://baijiahao.baidu.com/s?id=1707601012673143593&wfr=spider&for=pc 注:百家号中,一些文本.代码等的排版格式无 ...
- 【JS 逆向百例】网洛者反爬练习平台第二题:JJEncode 加密
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...