python如何生成验证码,captcha库的安装和使用,yeild和next关键字的使用 ,数据 generator

最近在研究 tensorflow框架下的深度学习,了解到深度学习对数据非常依赖,而标注好的数据集非常难得。今天发现 python 的 captcha 库,可以生成验证码,因此,完全可以利用captcha库生成一个验证码数据集,用于图片识别的实验。这其中会用到 yeild 和 next 关键字,生成数据 generator。

captcha 库的安装


captcha 库的安装非常简单,直接利用 pip 命令安装即可。

pip install captcha

看终端提示,它是先安装了 captcha 库,接着安装了 pillow 库。如果 pip 命令安装失败,可以自己下载安装包安装。

python实战,调用 captcha 生成简单图形验证码


安装好 captcha 库后,就可以使用 python 调用,生成验证码了。因为计划做图片识别,所以这里生成图形验证码。这里是一个例子。

#-*- coding:utf-8 -*-
from captcha.image import ImageCaptcha
import random
import string

image = ImageCaptcha(160,60)    # 图片宽 160 高 60
characters = string.digits + string.ascii_uppercase + string.ascii_lowercase        #验证码组成,数字+大写字母+小写字母
char_num = 4 #验证码字符个数

captcha_str = ''.join(random.sample(characters, char_num))
img = image.generate_image(captcha_str)
img.save(captcha_str + '.jpg')

上述代码生成了一个 160x60 的图形验证码,验证码由 4 位随机的数字、大小写字母组成,生成的验证码我们保存为 jpg 格式。

执行代码,得到如下图片:

因为验证码是由 10 个数字和 26 个字母组成,所以一共有 10 + 26x2(大小写) = 62 个类别,每次随机取 4 个字符组成验证码,如果标签用 one-hot 编码,那么标签的大小为 62x4 = 248。

python 的 yield 关键字


本节学习使用 python 的 captcha 库的目的就是为了做深度学习的数据集,深度学习网络需要很大的数据量,而存储和计算数据的内存是有限的,这两点其实是一对矛盾。我们需要大量数据,但是却没有无限大的内存存储它,有解决办法吗?当然是有的。

我们可以用多少,生成多少。比如训练深度学习网络时,需要一个 batch 的大小为 64 张验证码,那完全可以一次只生成 64 张图片。

似乎可以这样来:我们写一个函数,每次生成 64 张图片,需要数据时,调用一次该函数即可。这当然可行,只不过这样会有一个问题:每次生成图片都需要初始化程序,并且退出程序,而这样会导致产生数据的效率低下。为了解决这个问题,python有个叫数据生成器(generator)的功能,借助yieldnext关键字,可以再程序不重启的情况下,产生一个 batch 的图片。看下面这段代码:

def gen_captcha(self,batch_size = 50):
        ...
        while True:
            for i in range(batch_size):
                ...
                    Y[i,j,self.characters.find(ch)] = 1 
            Y = np.reshape(Y,(batch_size,self.char_num*self.classes))
            yield X,Y

咋一看它是一个死循环,不过 yield 关键字的使用,让它可以完成数据generator的功能。每次程序执行到yield时,它会将 X 和 Y 返回,但是这个函数不会退出,在遇到 next 关键字后,它会接着运行。例如我们在别处调用了

batch_x,batch_y = next(captcha.gen_captcha(64))

gen_captcha函数会从上次停下的地方接着运行,这就源源不断的产生 batch size 的验证码图片了。

将生成验证码的动作封装为库


这一部分,我们基于前面的内容,利用 python 的 captcha 库,封装一个可以每次产生验证码 batch 的类,用于后续的深度学习网络的训练。代码如下:

#-*- coding:utf-8 -*-
from captcha.image import ImageCaptcha
from PIL import Image
import numpy as np
import random
import string

class generateCaptcha():
    def __init__(self,
                 width = 160,#验证码图片的宽
                 height = 60,#验证码图片的高
                 char_num = 4,#验证码字符个数
                 characters = string.digits + string.ascii_uppercase + string.ascii_lowercase):#验证码组成,数字+大写字母+小写字母
        self.width = width
        self.height = height
        self.char_num = char_num
        self.characters = characters
        self.classes = len(characters)
        # print self.classes

    def gen_captcha(self,batch_size = 50):
        X = np.zeros([batch_size,self.height,self.width,1])
        img = np.zeros((self.height,self.width),dtype=np.uint8)
        Y = np.zeros([batch_size,self.char_num,self.classes])
        image = ImageCaptcha(width = self.width,height = self.height)

        while True:
            for i in range(batch_size):
                captcha_str = ''.join(random.sample(self.characters,self.char_num))
                img = image.generate_image(captcha_str).convert('L')
                img = np.array(img.getdata())
                X[i] = np.reshape(img,[self.height,self.width,1])/255.0
                for j,ch in enumerate(captcha_str):
                    Y[i,j,self.characters.find(ch)] = 1 
            Y = np.reshape(Y,(batch_size,self.char_num*self.classes))
            yield X,Y

    def decode_captcha(self,y):
        y = np.reshape(y,(len(y),self.char_num,self.classes))
        return ''.join(self.characters[x] for x in np.argmax(y,axis = 2)[0,:])

    def get_parameter(self):
        return self.width,self.height,self.char_num,self.characters,self.classes

这里,我们详细分析一下 gen_captcha 函数,它是用来产生验证码 batch 的。

  • X:一个 mini-batch 的训练数据,其 shape 为 [ batch_size, height, width, 1 ],batch_size 表示每批次多少个训练数据,height 表示验证码图片的高,width 表示验证码图片的宽,1 表示图片的通道。
  • Y:X 中每个训练数据属于哪一类验证码,其形状为 [ batch_size, class ] ,对验证码中每个字符进行 One-Hot 编码,所以 class 大小为 4*62。

在每一个 batch 中,程序先将 RGB 彩色图片转成灰度图片,然后将数据全部变换到 [0,1] 范围内,存在 X 的第 i 个 batch。

img = image.generate_image(captcha_str).convert('L')
img = np.array(img.getdata())
X[i] = np.reshape(img,[self.height,self.width,1])/255.0

标签值存在 Y 里,令 Y 中每个 batch 对应的字符的位置等于 1(即 one-hot 编码),最后将 Y 转成 [batch_size, 总类别] 的形状。

for j,ch in enumerate(captcha_str):
    Y[i,j,self.characters.find(ch)] = 1 
Y = np.reshape(Y,(batch_size,self.char_num*self.classes))

至此,利用 python 的 captcha 库生成验证码数据集的准备工作就做好了,今后研究深度学习图片识别时,这个可以作为一个不错的数据集。只需要将对象实例化,使用 next 关键字,就可以源源不断的获得训练的验证码 batch。

阅读更多:   Python
仅有 1 条评论
  1. […] 在python如何生成验证码小节,我们利用 captcha 库做了一个图形验证码产生器,可以产生带 one-hot 标签的图片数据集。本节将基于此数据集,建立一个卷积深度学习网络(CNN),并且训练之,希望可以识别破解此验证码数据集。 […]

添加新评论