python使用tensorflow深度学习识别验证码


Posted in Python onApril 03, 2018

本文介绍了python使用tensorflow深度学习识别验证码 ,分享给大家,具体如下:

除了传统的PIL包处理图片,然后用pytessert+OCR识别意外,还可以使用tessorflow训练来识别验证码。

此篇代码大部分是转载的,只改了很少地方。

代码是运行在linux环境,tessorflow没有支持windows的python 2.7。

gen_captcha.py代码。

#coding=utf-8
from captcha.image import ImageCaptcha # pip install captcha
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import random

# 验证码中的字符, 就不用汉字了

number = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
      'v', 'w', 'x', 'y', 'z']

ALPHABET = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
      'V', 'W', 'X', 'Y', 'Z']
'''
number=['0','1','2','3','4','5','6','7','8','9']
alphabet =[]
ALPHABET =[]
'''

# 验证码一般都无视大小写;验证码长度4个字符
def random_captcha_text(char_set=number + alphabet + ALPHABET, captcha_size=4):
  captcha_text = []
  for i in range(captcha_size):
    c = random.choice(char_set)
    captcha_text.append(c)
  return captcha_text


# 生成字符对应的验证码
def gen_captcha_text_and_image():
  while(1):
    image = ImageCaptcha()

    captcha_text = random_captcha_text()
    captcha_text = ''.join(captcha_text)

    captcha = image.generate(captcha_text)
    #image.write(captcha_text, captcha_text + '.jpg') # 写到文件

    captcha_image = Image.open(captcha)
    #captcha_image.show()
    captcha_image = np.array(captcha_image)
    if captcha_image.shape==(60,160,3):
      break

  return captcha_text, captcha_image






if __name__ == '__main__':
  # 测试
  text, image = gen_captcha_text_and_image()
  print image
  gray = np.mean(image, -1)
  print gray

  print image.shape
  print gray.shape
  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()

train.py代码。

#coding=utf-8
from gen_captcha import gen_captcha_text_and_image
from gen_captcha import number
from gen_captcha import alphabet
from gen_captcha import ALPHABET

import numpy as np
import tensorflow as tf

"""
text, image = gen_captcha_text_and_image()
print "验证码图像channel:", image.shape # (60, 160, 3)
# 图像大小
IMAGE_HEIGHT = 60
IMAGE_WIDTH = 160
MAX_CAPTCHA = len(text)
print  "验证码文本最长字符数", MAX_CAPTCHA # 验证码最长4字符; 我全部固定为4,可以不固定. 如果验证码长度小于4,用'_'补齐
"""
IMAGE_HEIGHT = 60
IMAGE_WIDTH = 160
MAX_CAPTCHA = 4

# 把彩色图像转为灰度图像(色彩对识别验证码没有什么用)
def convert2gray(img):
  if len(img.shape) > 2:
    gray = np.mean(img, -1)
    # 上面的转法较快,正规转法如下
    # r, g, b = img[:,:,0], img[:,:,1], img[:,:,2]
    # gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
    return gray
  else:
    return img


"""
cnn在图像大小是2的倍数时性能最高, 如果你用的图像大小不是2的倍数,可以在图像边缘补无用像素。
np.pad(image,((2,3),(2,2)), 'constant', constant_values=(255,)) # 在图像上补2行,下补3行,左补2行,右补2行
"""

# 文本转向量
char_set = number + alphabet + ALPHABET + ['_'] # 如果验证码长度小于4, '_'用来补齐
CHAR_SET_LEN = len(char_set)


def text2vec(text):
  text_len = len(text)
  if text_len > MAX_CAPTCHA:
    raise ValueError('验证码最长4个字符')

  vector = np.zeros(MAX_CAPTCHA * CHAR_SET_LEN)

  def char2pos(c):
    if c == '_':
      k = 62
      return k
    k = ord(c) - 48
    if k > 9:
      k = ord(c) - 55
      if k > 35:
        k = ord(c) - 61
        if k > 61:
          raise ValueError('No Map')
    return k

  for i, c in enumerate(text):
    #print text
    idx = i * CHAR_SET_LEN + char2pos(c)
    #print i,CHAR_SET_LEN,char2pos(c),idx
    vector[idx] = 1
  return vector

#print text2vec('1aZ_')

# 向量转回文本
def vec2text(vec):
  char_pos = vec.nonzero()[0]
  text = []
  for i, c in enumerate(char_pos):
    char_at_pos = i # c/63
    char_idx = c % CHAR_SET_LEN
    if char_idx < 10:
      char_code = char_idx + ord('0')
    elif char_idx < 36:
      char_code = char_idx - 10 + ord('A')
    elif char_idx < 62:
      char_code = char_idx - 36 + ord('a')
    elif char_idx == 62:
      char_code = ord('_')
    else:
      raise ValueError('error')
    text.append(chr(char_code))
  return "".join(text)


"""
#向量(大小MAX_CAPTCHA*CHAR_SET_LEN)用0,1编码 每63个编码一个字符,这样顺利有,字符也有
vec = text2vec("F5Sd")
text = vec2text(vec)
print(text) # F5Sd
vec = text2vec("SFd5")
text = vec2text(vec)
print(text) # SFd5
"""


# 生成一个训练batch
def get_next_batch(batch_size=128):
  batch_x = np.zeros([batch_size, IMAGE_HEIGHT * IMAGE_WIDTH])
  batch_y = np.zeros([batch_size, MAX_CAPTCHA * CHAR_SET_LEN])

  # 有时生成图像大小不是(60, 160, 3)
  def wrap_gen_captcha_text_and_image():
    while True:
      text, image = gen_captcha_text_and_image()
      if image.shape == (60, 160, 3):
        return text, image

  for i in range(batch_size):
    text, image = wrap_gen_captcha_text_and_image()
    image = convert2gray(image)

    batch_x[i, :] = image.flatten() / 255 # (image.flatten()-128)/128 mean为0
    batch_y[i, :] = text2vec(text)

  return batch_x, batch_y


####################################################################

X = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT * IMAGE_WIDTH])
Y = tf.placeholder(tf.float32, [None, MAX_CAPTCHA * CHAR_SET_LEN])
keep_prob = tf.placeholder(tf.float32) # dropout


# 定义CNN
def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1):
  x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])

  # w_c1_alpha = np.sqrt(2.0/(IMAGE_HEIGHT*IMAGE_WIDTH)) #
  # w_c2_alpha = np.sqrt(2.0/(3*3*32))
  # w_c3_alpha = np.sqrt(2.0/(3*3*64))
  # w_d1_alpha = np.sqrt(2.0/(8*32*64))
  # out_alpha = np.sqrt(2.0/1024)

  # 3 conv layer
  w_c1 = tf.Variable(w_alpha * tf.random_normal([3, 3, 1, 32]))
  b_c1 = tf.Variable(b_alpha * tf.random_normal([32]))
  conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding='SAME'), b_c1))
  conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
  conv1 = tf.nn.dropout(conv1, keep_prob)

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

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

  # Fully connected layer
  w_d = tf.Variable(w_alpha * tf.random_normal([8 * 32 * 40, 1024]))
  b_d = tf.Variable(b_alpha * tf.random_normal([1024]))
  dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]])
  dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d))
  dense = tf.nn.dropout(dense, keep_prob)

  w_out = tf.Variable(w_alpha * tf.random_normal([1024, MAX_CAPTCHA * CHAR_SET_LEN]))
  b_out = tf.Variable(b_alpha * tf.random_normal([MAX_CAPTCHA * CHAR_SET_LEN]))
  out = tf.add(tf.matmul(dense, w_out), b_out)
  # out = tf.nn.softmax(out)
  return out


# 训练
def train_crack_captcha_cnn():
  import time
  start_time=time.time()
  output = crack_captcha_cnn()
  # loss
  #loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output, Y))
  loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output, labels=Y))
  # 最后一层用来分类的softmax和sigmoid有什么不同?
  # optimizer 为了加快训练 learning_rate应该开始大,然后慢慢衰
  optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)

  predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN])
  max_idx_p = tf.argmax(predict, 2)
  max_idx_l = tf.argmax(tf.reshape(Y, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)
  correct_pred = tf.equal(max_idx_p, max_idx_l)
  accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

  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)
      _, loss_ = sess.run([optimizer, loss], feed_dict={X: batch_x, Y: batch_y, keep_prob: 0.75})
      print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())),step, loss_

      # 每100 step计算一次准确率
      if step % 100 == 0:
        batch_x_test, batch_y_test = get_next_batch(100)
        acc = sess.run(accuracy, feed_dict={X: batch_x_test, Y: batch_y_test, keep_prob: 1.})
        print u'***************************************************************第%s次的准确率为%s'%(step, acc)
        # 如果准确率大于50%,保存模型,完成训练
        if acc > 0.9:         ##我这里设了0.9,设得越大训练要花的时间越长,如果设得过于接近1,很难达到。如果使用cpu,花的时间很长,cpu占用很高电脑发烫。
          saver.save(sess, "crack_capcha.model", global_step=step)
          print time.time()-start_time
          break

      step += 1


train_crack_captcha_cnn()

测试代码:

output = crack_captcha_cnn()
saver = tf.train.Saver()
sess = tf.Session()
saver.restore(sess, tf.train.latest_checkpoint('.'))

while(1):
  

  text, image = gen_captcha_text_and_image()
  image = convert2gray(image)
  image = image.flatten() / 255

  predict = tf.argmax(tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)
  text_list = sess.run(predict, feed_dict={X: [image], keep_prob: 1})
  predict_text = text_list[0].tolist()

  vector = np.zeros(MAX_CAPTCHA * CHAR_SET_LEN)
  i = 0
  for t in predict_text:
    vector[i * 63 + t] = 1
    i += 1
    # break



  print("正确: {} 预测: {}".format(text, vec2text(vector)))

如果想要快点测试代码效果,验证码的字符不要设置太多,例如0123这几个数字就可以了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详细介绍Python的鸭子类型
Sep 12 Python
python学习基础之循环import及import过程
Apr 22 Python
pygame实现俄罗斯方块游戏
Jun 26 Python
对numpy中的数组条件筛选功能详解
Jul 02 Python
python sort、sort_index方法代码实例
Mar 28 Python
Python识别快递条形码及Tesseract-OCR使用详解
Jul 15 Python
Python 读取用户指令和格式化打印实现解析
Sep 02 Python
django创建简单的页面响应实例教程
Sep 06 Python
python实现按关键字筛选日志文件
Dec 24 Python
解决pyinstaller打包运行程序时出现缺少plotly库问题
Jun 02 Python
Python如何发送与接收大型数组
Aug 07 Python
利用Python的folium包绘制城市道路图的实现示例
Aug 24 Python
使用python获取csv文本的某行或某列数据的实例
Apr 03 #Python
python中实现数组和列表读取一列的方法
Apr 03 #Python
numpy.delete删除一列或多列的方法
Apr 03 #Python
取numpy数组的某几行某几列方法
Apr 03 #Python
Python numpy 提取矩阵的某一行或某一列的实例
Apr 03 #Python
python3安装pip3(install pip3 for python 3.x)
Apr 03 #Python
Win7 64位下python3.6.5安装配置图文教程
Oct 27 #Python
You might like
php Http_Template_IT类库进行模板替换
2009/03/19 PHP
提示Trying to clone an uncloneable object of class Imagic的解决
2011/10/27 PHP
PHP pthreads v3下worker和pool的使用方法示例
2020/02/21 PHP
JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享
2013/07/02 Javascript
jquery基础教程之deferred对象使用方法
2014/01/22 Javascript
JavaScript实现单击下拉框选择直接跳转页面的方法
2015/07/02 Javascript
每天一篇javascript学习小结(基础知识)
2015/11/10 Javascript
使用jQuery Mobile框架开发移动端Web App的入门教程
2016/05/17 Javascript
浅析jQuery操作select控件的取值和设值
2016/12/07 Javascript
微信小程序scroll-view实现横向滚动和上拉加载示例
2017/03/06 Javascript
关于HTTP传输中gzip压缩的秘密探索分析
2018/01/12 Javascript
JavaScript监听一个DOM元素大小变化
2020/04/26 Javascript
在Vue中使用CSS3实现内容无缝滚动的示例代码
2020/11/27 Vue.js
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
python实现基本进制转换的方法
2015/07/11 Python
Python实现代码统计工具(终极篇)
2016/07/04 Python
再谈Python中的字符串与字符编码(推荐)
2016/12/14 Python
python中numpy包使用教程之数组和相关操作详解
2017/07/30 Python
Python django使用多进程连接mysql错误的解决方法
2018/10/08 Python
Python XlsxWriter模块Chart类用法实例分析
2019/03/11 Python
python中seaborn包常用图形使用详解
2019/11/25 Python
python读取图片的几种方式及图像宽和高的存储顺序
2020/02/11 Python
关于Python Tkinter Button控件command传参问题的解决方式
2020/03/04 Python
Windows 下更改 jupyterlab 默认启动位置的教程详解
2020/05/18 Python
详解pandas中利用DataFrame对象的.loc[]、.iloc[]方法抽取数据
2020/12/13 Python
斯德哥尔摩通票:Stockholm Pass
2018/01/09 全球购物
卡骆驰英国官网:Crocs英国
2019/08/22 全球购物
优秀学生干部个人的自我评价
2013/10/04 职场文书
中专生的个人自我评价
2013/12/11 职场文书
婚前协议书
2014/04/15 职场文书
教师对学生的评语
2014/04/28 职场文书
优秀党员学习焦裕禄精神思想汇报范文
2014/09/10 职场文书
群众路线查摆问题整改措施
2014/10/10 职场文书
导师对论文的学术评语
2015/01/04 职场文书
《鲁滨逊漂流记》之六读后感(4篇)
2019/09/29 职场文书
python实战之用emoji表情生成文字
2021/05/08 Python