8

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

 3 years ago
source link: https://blog.popkx.com/python-how-to-generate-captcha-use-of-captcha-library-and-keyword-of-yeild-and-next/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

最近在研究 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。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK