1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
""" |
3
|
|
|
school_api.check_code.predict |
4
|
|
|
~~~~~~~~~~~~~~~~ |
5
|
|
|
This module provides functions for Identification verification code |
6
|
|
|
|
7
|
|
|
:copyright: (c) 2018 by dairoot. |
8
|
|
|
:license: MIT, see LICENSE for more details. |
9
|
|
|
""" |
10
|
|
|
import os |
11
|
|
|
from io import BytesIO |
12
|
|
|
|
13
|
|
|
import numpy as np |
14
|
|
|
from PIL import Image |
15
|
|
|
|
16
|
|
|
|
17
|
|
|
class CheckCode(object): |
18
|
|
|
""" 正方系统验证码识别 """ |
19
|
|
|
data_file = os.path.dirname(os.path.realpath(__file__)) + '/theta.dat' |
20
|
|
|
real_all_theta = np.matrix(np.loadtxt(data_file)).transpose() |
21
|
|
|
|
22
|
|
|
def __init__(self): |
23
|
|
|
self.img = None |
24
|
|
|
|
25
|
|
|
def photo_to_text(self): |
26
|
|
|
''' |
27
|
|
|
图片转数据 |
28
|
|
|
''' |
29
|
|
|
x_size, y_size = self.img.size |
30
|
|
|
y_size -= 5 |
31
|
|
|
piece = (x_size - 22) // 8 |
32
|
|
|
centers = [4 + piece * (2 * i + 1) for i in range(4)] |
33
|
|
|
photo_data = [] |
34
|
|
|
for center in centers: |
35
|
|
|
single_img = self.img.crop((center - (piece + 2), 1, center + (piece + 2), y_size)) |
36
|
|
|
width, height = single_img.size |
37
|
|
|
photo_data_x = [] |
38
|
|
|
for h_index in range(0, height): |
39
|
|
|
for w_index in range(0, width): |
40
|
|
|
pixel = single_img.getpixel((w_index, h_index)) |
41
|
|
|
photo_data_x.append(int(pixel == 255)) |
42
|
|
|
photo_data.append(photo_data_x) |
43
|
|
|
return photo_data |
44
|
|
|
|
45
|
|
|
def verify(self, img_stream): |
46
|
|
|
''' |
47
|
|
|
将图片转成numpy数组数据 与 训练好的模型 进行匹配 |
48
|
|
|
''' |
49
|
|
|
obj = BytesIO(img_stream) |
50
|
|
|
img = Image.open(obj).convert("L") |
51
|
|
|
self.img = self.denoise_img(img) |
52
|
|
|
data = np.matrix(self.photo_to_text()) |
53
|
|
|
data = np.hstack((np.ones((data.shape[0], 1)), data)) |
54
|
|
|
all_predict = 1.0 / (1.0 + np.exp(-(np.dot(data, self.real_all_theta)))) |
55
|
|
|
pred = np.argmax(all_predict, axis=1).reshape(-1).tolist()[0] |
56
|
|
|
answers = map(chr, map(lambda x: x + 48 if x <= 9 else x + 87, pred)) |
57
|
|
|
return ''.join(answers) |
58
|
|
|
|
59
|
|
|
@staticmethod |
60
|
|
|
def denoise_img(img): |
61
|
|
|
'''图片降噪处理''' |
62
|
|
|
img2 = Image.new("L", img.size, 255) |
63
|
|
|
for x in range(img.size[1]): |
64
|
|
|
for y in range(img.size[0]): |
65
|
|
|
pix = img.getpixel((y, x)) |
66
|
|
|
if pix == 17: # these are the numbers to get |
67
|
|
|
img2.putpixel((y, x), 0) |
68
|
|
|
return img2 |
69
|
|
|
|