正方系统验证码 识别模型训练

验证码识别最主要难点在于图像的处理,模型的训练网上有太多例子,所以只要能将图片处理成可训练的数据集,便没什么难度了。

图片处理 (生成data.dat 训练数据)

验证码获取: http://222.24.62.120/CheckCode.aspx
训练图片生成器

from PIL import Image

def denoise_img(img):
    '''图片降噪处理'''
    img2 = Image.new("L", img.size, 255)
    for x in range(img.size[1]):
        for y in range(img.size[0]):
            pix = img.getpixel((y, x))
            if pix == 17:
                img2.putpixel((y, x), 0)
    return img2

img1 = Image.open("CheckCode.gif")
# 将图片转化为 灰度图
img2 = img1.convert("L")
img3 = denoise_img(img2)
图片处理

图片切分与转化成训练数据: 0代表存在像素点,1则表示没有像素点
数据张量:

  • 输入: 336 = 16*21
  • 输出: 36
def photo_to_text(img):
    x_size, y_size = img.size
    y_size -= 5
    piece = (x_size - 22) // 8
    centers = [4 + piece * (2 * i + 1) for i in range(4)]
    photo_data = []
    data_str = ''
    for i, center in enumerate(centers):
        single_img = img.crop((center - (piece + 2), 1, center + (piece + 2), y_size))
        # single_img.save("%s.png" % i)
        width, height = single_img.size
        photo_data_x = []
        for h_index in range(0, height):
            for w_index in range(0, width):
                pixel = single_img.getpixel((w_index, h_index))
                data_str += '1 ' if pixel == 255 else '0 '
        data_str += '\n\n' 
    return data_str

分割图片

图片分割

将图片转成可训练集 (336 = 16*21)


图片文本

将图片转化01字符串,存储到训练数据data.dat
完整的图片处理代码

模型训练 (生成theta.dat特征文本)

import numpy as np
from scipy.optimize import fmin_bfgs


def sigmoid(z):
    g = 1.0/(1.0+np.exp(-z))
    return g


def lrGD(theta, *args):
    theta = np.matrix(theta).transpose()
    X, y, the_lambda = args
    m = y.shape[0]
    grad = np.zeros(theta.shape)

    htheta = sigmoid(X * theta)
    grad[0] = 1.0/m * np.sum(np.array((htheta-y))*np.array(X[:, 0:1]))
    for i in range(1, theta.shape[0]):
        grad[i] = 1.0/m * np.sum(np.array((htheta-y)) *
                                 np.array(X[:, i:i+1])) + the_lambda/m*theta[i]
    return grad.flatten()


def lrCostFunction(theta, *args):
    theta = np.matrix(theta).transpose()
    X, y, the_lambda = args
    m = y.shape[0]
    htheta = sigmoid(X*theta)
    J = -np.sum(np.array(y)*np.array(np.log(htheta)) + np.array((1-y))
                * np.array(np.log(1-htheta)))/m + the_lambda*np.sum(
        np.array(theta[1:]) * np.array(theta[1:]))/(2*m)
    return J


def oneVsAll(X, y, num_labels, the_lambda):
    m, n = np.shape(X)
    all_theta = np.matrix(np.zeros((num_labels, n+1)))
    X = np.hstack((np.ones((m, 1)), X))
    initial_theta = np.zeros((n+1, 1))
    for c in range(num_labels):
        print ('Training for %d/%d' % (c+1, num_labels))
        args = (X, (y == c), the_lambda)
        theta = fmin_bfgs(lrCostFunction, initial_theta,
                          fprime=lrGD, args=args, maxiter=50)
        all_theta[c, :] = theta.transpose()

    return all_theta


def train():
    '''开始训练'''
    num_labels = 36 # 输出量
    num_y = 336     # 输入量 16*21
    the_lambda = 0.1
    data = np.matrix(np.loadtxt('data.dat'))  # 载入训练数据
    y = data[:, num_y]
    X = data[:, :num_y]
    all_theta = oneVsAll(X, y, num_labels, the_lambda)
    ''' 生成训练后的特征文本 '''
    np.savetxt('theta.dat', all_theta)

if __name__ == '__main__':
    train()

使用模型识别

精简版教程查看

github:https://github.com/dairoot/zfxfzb-code

你可能感兴趣的:(正方系统验证码 识别模型训练)