数字验证码识别

数字验证码识别
1,导入工具包`

import numpy as np
from captcha.image import ImageCaptcha
import matplotlib.pyplot as plt
from PIL import Image
import tensorflow as tf
import random

这次我们主要使用CNN 来做验证码识别 框架使用TensorFlow
2,构建验证码文本

number = ['0','1','2','3','4','5','6','7','8','9']
def huoquyanzhengmawenben(char_set = number,char_size = 4):
    text = []
    for i in range(char_size):
        c = random.choice(char_set)
        text.append(c)
    return text

3,生成验证码文本与图像(使用captcha.image)

def shengchengtuxiang():
    image = ImageCaptcha()
    text = huoquyanzhengmawenben()
    text = ''.join(text)
    img = image.generate(text)
    img = Image.open(img)
    img = np.array(img)

    return text,img

4,图片灰度化

def convert2gray(img):
    if len(img.shape)>2:
        gray = np.mean(img,-1)
        return gray
    else:
        return img

5,文本转向量

def text2vec(text):
    if len(text)>4:
        raise ValueError
    vec = np.zeros(40)
    for i,c in enumerate(text):
        idx = i*10+int(c)
        vec[idx] = 1
    return vec

6,batch函数

def get_next_batch(batchsize):
    batch_x = np.zeros([batchsize,60*160])
    batch_y = np.zeros([batchsize,4*10])
    def warp_get_img():
        while True:
            text,image = shengchengtuxiang()
            if image.shape==(60,160,3):
                return text,image
    for i in range(batchsize):
        text,image = warp_get_img()
        img = convert2gray(image)
        batch_x[i,:] = img.flatten()/255
        batch_y[i,:] = text2vec(text)
    return batch_x,batch_y

7, 卷积神经网络架构

def cnn_jiagou():
    x = tf.reshape(X,[-1,60,160,1])
    w_c1 = tf.Variable(tf.random_normal([3,3,1,32]))
    b_c1 = tf.Variable(tf.random_normal([32]))
    conv1 = tf.nn.conv2d(x,w_c1,strides=[1,1,1,1],padding='SAME')
    conv1 = tf.nn.relu(tf.nn.bias_add(conv1,b_c1))
    conv1 = tf.nn.max_pool(conv1,strides=[1,2,2,1],ksize=[1,2,2,1],padding='SAME')
    conv1 = tf.nn.dropout(conv1,keepratio)

    w_c2 = tf.Variable(tf.random_normal([3,3,32,64]))
    b_c2 = tf.Variable(tf.random_normal([64]))
    conv2 = tf.nn.conv2d(conv1,w_c2,strides=[1,1,1,1],padding='SAME')
    conv2 = tf.nn.relu(tf.nn.bias_add(conv2,b_c2))
    conv2 = tf.nn.max_pool(conv2,strides=[1,2,2,1],ksize=[1,2,2,1],padding='SAME')
    conv2 = tf.nn.dropout(conv2,keepratio)

    w_c3 = tf.Variable(tf.random_normal([3,3,64,64]))
    b_c3 = tf.Variable(tf.random_normal([64]))
    conv3 = tf.nn.conv2d(conv2,w_c3,strides=[1,1,1,1],padding='SAME')
    conv3 = tf.nn.relu(tf.nn.bias_add(conv3,b_c3))
    conv3 = tf.nn.max_pool(conv3,strides=[1,2,2,1],ksize=[1,2,2,1],padding='SAME')
    conv3 = tf.nn.dropout(conv3,keepratio)

    w_d1 = tf.Variable(tf.random_normal([8*20*64,1024]))
    b_d1 = tf.Variable(tf.random_normal([1024]))
    de_1 = tf.reshape(conv3,[-1,8*20*64])
    de_1 = tf.nn.relu(tf.add(tf.matmul(de_1,w_d1),b_d1))

    w_d2 = tf.Variable(tf.random_normal([1024,40]))
    b_d2 = tf.Variable(tf.random_normal([40]))
    out = tf.add(tf.matmul(de_1,w_d2),b_d2)
    return out

8,运行训练模块函数

def yunxing_cnn():
    output = cnn_jiagou()
    loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output, labels=Y))
    op = tf.train.AdadeltaOptimizer(1e-6).minimize(loss)
    max_p = tf.argmax(tf.reshape(output,[-1,4,10]),2)
    max_i = tf.argmax(tf.reshape(Y,[-1,4,10]),2)
    correct_pred = tf.cast(tf.equal(max_p,max_i),tf.float32)
    acc = tf.reduce_mean(correct_pred)

    saver = tf.train.Saver()
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        step = 0
        while True:
            batch_x,batch_y = get_next_batch(64)
            f_train = {X:batch_x,Y:batch_y,keepratio:0.75}
            loss_ = sess.run([op,loss],feed_dict=f_train)
            train_acc = sess.run(acc,feed_dict=f_train)

            batch_x_test,batch_y_test = get_next_batch(100)
            test = {X:batch_x_test,Y:batch_y_test,keepratio:0.75}
            accr = sess.run(acc,feed_dict=test)
            print('训练准确率',train_acc,'测试准确率',accr)
            if accr>0.50:
                saver.save(sess,'./model/yunxingcnn.model',step)
                break
            step+=1

9,测试模块函数

def ceshi_cnn(img):
    output = yunxing_cnn()
    saver = tf.train.saver()
    with tf.Session() as sess:
        saver.restore('./model/crack_capcha.model-810')
        predict = tf.argmax(tf.reshape(output,[-1,4,10]),2)
        text_list = sess.run(predict,feed_dict={X:[img],keepratio:1})
        text = text_list[0].to_list()
    return text

10,主程序部分

if __name__ == '__main__':
    train = 0
    if train == 0:
        number = ['0','1','2','3','4','5','6','7','8','9']
        text,image = gen_captcha_text_and_image()
        print(image.shape)
        hight = 60
        width = 160
        X = tf.placeholder(tf.float32, [None, 60*160])  
        Y = tf.placeholder(tf.float32, [None, 4*10])  
        keepratio = tf.placeholder(tf.float32)

        yunxing_cnn()
    if train == 1:
        text, image = gen_captcha_text_and_image()  


        f = plt.figure()  
        ax = f.add_subplot(111)  
        ax.text(0.1, 0.9,text, ha='center', va='center', transform=ax.transAxes)  
        plt.imshow(image)  

        plt.show()  

        image = convert2gray(image)
        image = image.flatten()/255

        X = tf.placeholder(tf.float32,[None,60*160])
        Y = tf.placeholder(tf.float32,[None,4*10])
        keepratio = tf.placeholder(tf.float32)

        pre = ceshi_cnn(image)
        print('正确%d 预测%d'%(text,pre))
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值