中文点选验证码自动识别
2018-8-16 21:27:36 Author: fuping.site(查看原文) 阅读量:2 收藏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php


function createImage($word,$imagePath,$type,$imageName){

$fontPath = 'msyh.ttc';
$fontSize = 20 * 0.75;
foreach ($word as $v ) {
$fontarea = imagettfbbox($fontSize, 0, $fontPath, $v);
$textWidth = $fontarea[2] - $fontarea[0];
$textHeight = $fontarea[1] - $fontarea[7];
$tmp['text'] = $v;
$tmp['size'] = $fontSize;
$tmp['width'] = $textWidth;
$tmp['height'] = $textHeight;
$textArr[] = $tmp;
}
list($imageWidth, $imageHeight, $imageType) = getimagesize($imagePath);

for($i=0;$i<count($textArr);$i++){
list($x, $y) = randPosition($textArr, $imageWidth, $imageHeight, $textArr[$i]['width'], $textArr[$i]['height'],$i,$type);
$textArr[$i]['x'] = $x;
$textArr[$i]['y'] = $y;
}
unset($v);


$image = imagecreatefromstring(file_get_contents($imagePath));

$color = imagecolorallocate($image, 0, 0, 0);

foreach($textArr as $v){
imagefttext($image, $v['size'], 0, $v['x'], $v['y'], $color, $fontPath, $v['text']);
}

if(imagepng($image,$imageName)){
echo $imageName."\n";
}

}

function randPosition($textArr, $imgW, $imgH, $fontW, $fontH,$i,$type){
switch ($type) {
case 0:
$x = rand($i*60, ($i+1)*60-$fontW-3);
$y = rand(40,80);
break;
case 1:
$x = ($i)*25+5;
$y = 25;
default:
break;
}
$return = array($x, $y);
return $return;
}

$ap_imagePath = 'ap_bg.png';
$mp_imagePath = 'mp_bg.png';
$ap_imageName = "ap_".time().".png";
$mp_imageName = "mp_".time().".png";
$ap_word = array('请','依','次','点','击','图','中','的','猎', '户','室') ;
$mp_word = array('猎', '户', '实','验','室');
createImage($ap_word,$ap_imagePath,1,$ap_imageName);
createImage($mp_word,$mp_imagePath,0,$mp_imageName);
?>

对于这种简单的点选验证码,可以有两种很容易的识别方式(机器学习算麻烦的,这里就不列出了。嗯,对,我也不会)。一种是opencv的图像模板匹配,另外一种是OCR识别。

第一种方式,使用opencv的图像模板匹配。模板匹配是一种在较大图像中搜索和查找模板图像位置的方法,opencv2和opencv3中提供了一个专门用于模板匹配的函数matchTemplate()。它是在输入图像上滑动模板图像(如在2D卷积中),并比较模板图像下的输入图像的模板和补丁。在OpenCV中实现了六种比较方法(这里用到的是cv2.TM_CCOEFF_NORMED),它返回一个灰度图像,其中每个像素表示该像素的邻域与模板匹配的程度。

我们进行使用模板匹配来识别这种验证码时,首先先将“模板”找出来,这里我们需要匹配的是“猎”、“户”、“室”这三个字。将这三个字所在的图片进行截取,然后使用matchTemplate()函数在mp中进行匹配。

本文用了两种方法来自动识别汉字点选验证码,第一种采用的是opencv的模板匹配,这种方法虽然也可以匹配到,但这种方法缺点就是对于字体形状差异较大的验证码识别率较低。而第二种方法就比较快捷方便了,而且识别度高,比较推荐第二种方法。

当然这两种方法对于简单、“正规”的验证码可以,遇到复杂的、“扭曲的”验证码就不行了。这时候就要用到机器学习了,而本文只是简单的“识别”,将机器学习用到这里,就有些大材小用了。


文章来源: https://fuping.site/2018/08/16/Automatically-Identify-Chinese-Point-Selection/
如有侵权请联系:admin#unsafe.sh