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