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
00001111111111110000011110000111100000000011
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
1111100001111111111111111111111111110000011111111
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吧 												

PHP验证码识别实例相关推荐

  1. 韩服 永恒之塔 验证码识别实例测试[非商业用途]

    韩服 永恒之塔 验证码识别实例 韩服 永恒之塔外挂 过验证码必备工具 外挂必用 永恒之塔 验证码识别率90%以上

  2. 验证码识别的原理python_Python验证码识别处理实例

    一.准备工作与代码实例 1.PIL.pytesser.tesseract (1)安装PIL:下载地址:http://www.pythonware.com/products/pil/(CSDN下载) 下 ...

  3. 提交调用验证_干货丨RPA验证码识别技巧

    验证码是RPA流程自动化中经常碰到的问题.比如进行网页或者客户端登录的时候,或者提交数据查验都有可能碰到验证码. 验证码的类型也各式各样:纯数字.英文数字.英数汉等,且一般验证码上面都有干扰因素存在( ...

  4. 关于利用python进行验证码识别的一些想法

    关于利用python进行验证码识别的一些想法 - 小五义 - 博客园 关于利用python进行验证码识别的一些想法 转载请注明:@小五义http://www.cnblogs.com/xiaowuyi ...

  5. 用爬虫实现验证码识别并模拟登陆和cookie操作、代理操作、线程池

    一.模拟登陆 1.为什么要进行模拟登陆 有时,我们需要爬取一些基于个人用户的用户信息(需要登陆后才可以查看) 2.为什么要需要识别验证码 因为验证码往往是作为登陆请求中的请求参数被使用 3.验证码识别 ...

  6. 【Python5】图像操作,数字验证码识别,图像拼接/保存器

    文章目录 1.安装 2.画图 3.几何变换 3.1 位计算 3.2 遮挡 3.3 通道切分合并 3.4 金字塔 3.5 缩放 3.6 平移 3.7 旋转 3.8 仿射变换 3.9 透视变换 4.形态学 ...

  7. python验证码 识别代码不准_谈谈Python进行验证码识别的一些想法

    用python加"验证码"为关键词在baidu里搜一下,可以找到很多关于验证码识别的文章.我大体看了一下,主要方法有几类:一类是通过对图片进行处理,然后利用字库特征匹配的方法,一类 ...

  8. code block怎样实现图形界面_Python 代码实现验证码识别,很稳

    作者:叶庭云 源自:快学python 昨天十行代码实现文字识别,感觉怎样,是不是很爽 今天咋们继续利用pillow和pytesseract来实现验证码的识别 一.环境配置 需要 pillow 和 py ...

  9. 基于CRNN的文本字符交易验证码识别--Paddle实战

    基于CRNN的文本字符验证码识别 本项目链接,欢迎大家Fork:https://aistudio.baidu.com/aistudio/projectdetail/3501451 Paddle学习资料 ...

最新文章

  1. 图形交互界面_人机交互界面UI简介
  2. symantec、officescan控制台忘记密码如何处理
  3. New Linux2.6 I2C Driver Model Example
  4. PyTorch深度学习实践05
  5. 应付账款账龄分析模板_超全的财务会计表单模板分享
  6. python 复制文件_python 复制文件
  7. python 面部识别_一文教你在Python中打造你自己专属的面部识别系统
  8. 【java】理解和运用Java中的Lambda
  9. 手把手分析 mfc 程序创建 代码执行流程
  10. 黄健计算机科学与技术学院,计算机科学与技术学院研究生学业奖学金初评结果汇总表...
  11. 竞赛经验|2019年电赛B题四旋翼无人机组巡线机器人
  12. 干货十足:一大波好用的Windows软件帮你开路!
  13. Python实战题 · 计算圆面积
  14. mbs单位是什么意思计算机,Mbps是什么意思 1Mbps是多少兆网速?
  15. 小米手环4怎么使用_小米运动手环4使用说明
  16. 简单批处理内部命令简介
  17. 在线直播源码,VUE 获奖名单滚动显示的两种方式
  18. JavaScript-牛客网-剑指offer(1-10)题解
  19. EAS(能量感知调度)绿色节能调度器
  20. CCE to REG bundle

热门文章

  1. Linux 64位进程地址空间分布概况
  2. Spring Bean的一生
  3. redis数据类型set总结
  4. docker开启mysql的binlog日志
  5. 前端http请求跨域问题解决
  6. Docker 的两类存储资源 - 每天5分钟玩转 Docker 容器技术(38)
  7. 奇怪的微信内置浏览器IOS版和Anroid 版
  8. redis超时原因排查
  9. 黑客入侵交警计算机系统删交通违法记录牟利
  10. JDK源码(20)-Thread