数字验证码识别
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))