pytesseract+tensorflow开发一个自己的验证码训练集

pytesseract模块结合tesseract-ocr软件能识别大部分的验证码,虽然用自己训练的数据跑tesseract识别验证码,具体参考博主:https://blog.csdn.net/Jayj1997/article/details/102882379
本人尝试了,很麻烦。
在这里插入图片描述
用pytesseract对以上这种验证码的识别率也只在75%左右,对于这个准确率实在事不满意。
例如验证码在这里插入图片描述
验证代码:

import pytesseract
from PIL import Image
img = Image.open('./3tst_15819267383940756.png', mode='r')
result = pytesseract.image_to_string(image=img, )
checkcode = result.replace(' ', '').lower()  ##把字符串的空格去掉,把大写转成小写
print(checkcode)

识别结果:

$

Process finished with exit code 0

连这么简单的验证码都识别错误,真是不堪重用。

直到某天逛github发现了https://github.com/nickliqian/cnn_captcha大神的宝藏,针对字符型图片验证码,使用tensorflow实现卷积神经网络,进行验证码识别。
git clone https://github.com/nickliqian/cnn_captcha
到本机,搞了好久终于测试通过。

但是这个训练数据是通过captcha模块生成,其验证码图片大小与形状和工作用到的大不一样。

在这里插入图片描述
如果要训练这种验证码的测试集,怎么处理?

最重要的是验证码的标签如何识别?训练图片至少好几千,总不能一个一个人工识别吧。不是还有pytesseract吗?虽然识别率有点差强人意。
缕下思路:
先从网站下载图片,图片命名格式:4位验证码标签_时间戳.png
4位验证码标签就通过pytesseract来识别,如果验证码长度不等于4或有非数字或字母的其它字符,就把图片方到另外一个路径。

import gevent
from gevent import monkey
monkey.patch_all(select=False)
import requests
import shutil
import time
import os
from PIL import Image
import pytesseract
import sys
import re

root_dir='./imgs'
error_dir='./imgs_error'
image_suffix='png'
imgurl = 'http://1.1.1.1:7001/cas/captcha.htm'  ##需要修改获取验证码的网址
headers = {
        'context-type': 'text/xml; charset=UTF-8',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3'service=http%3A%2F%2F10.128.85.13%3A7001%2Fworkshop%2Fbase%2Fjt%2Fjsp%2Findex_JT.jsp',
    }

if not os.path.exists(root_dir):
    os.makedirs(root_dir)
if not os.path.exists(root_dir):
    os.makedirs(error_dir) 
CNT=0

def get_img():
    global CNT
    checkcodecontent = requests.get(url=imgurl, headers=headers)
    timec = str(time.time()).replace(".", "")
    text='aaaa'
    filename = os.path.join(root_dir, "{}_{}.{}".format(text, timec, image_suffix))
    with open(filename, 'wb') as f:
        f.write(checkcodecontent.content)
        f.close() 
    img = Image.open(filename, mode='r')
    result = pytesseract.image_to_string(image=img, )
    checkcode = result.replace(' ', '').lower()  ##把字符串的空格去掉,把大写转成小写
    CNT = CNT + 1
    destname=os.path.join(error_dir, "{}_{}.{}".format(checkcode, timec, image_suffix))
    if len(checkcode) != 4:
        print('验证码{}长度不等于4,移动到错误目录'.format(checkcode))
        shutil.move(filename,destname)
        return
    if re.search('\W+', checkcode):
        print('文件名{}前缀包含特殊字符[包含非数字与字母的字符],移动到错误目录'.format(checkcode))
        shutil.move(filename,destname)
        return

    '''需要判断checkcode要a-z,1-9,A-Z的字符才可以'''
    filename_new=os.path.join(root_dir, "{}_{}.{}".format(checkcode, timec, image_suffix))
    os.rename(filename,filename_new)

    print('第{}张验证码图片下载完成'.format(CNT))


def modefy_name():
    filenames=os.listdir(root_dir)
    for filename in filenames:
        prefix=re.split('_', filename)[0]
        if len(prefix) != 4:
            print('文件名{}前缀长度不等于4,直接删除'.format(filename))
            os.remove(os.path.join(root_dir, filename))
        elif re.search('\W+',prefix):
            print('文件名{}前缀包含特殊字符[包含非数字与字母的字符],直接删除'.format(filename))
            os.remove(os.path.join(root_dir, filename))


if __name__ == '__main__':

    g_list = list()
    start = time.time()
    for j in range(200):
        for i in range(30):
            g = gevent.spawn(get_img)
            g_list.append(g)

        gevent.joinall(g_list)
        print('总耗时:%.5f秒' % float(time.time() - start))

        modefy_name()
        time.sleep(50)

把验证码图片下载到目录imgs,至少要5000张,拷贝到cnn_captcha\sample\origin,
执行python verify_and_split_data.py
执行结果:

>>> 开始校验目录:[sample/origin/]
开始校验原始图片集
原始集共有图片: 7375
====以下0张图片有异常====
未发现异常(共 7375 张图片)
========end
开始分离原始图片集为:测试集(5%)和训练集(95%
共分配7375张图片到训练集和测试集,其中0张为异常留在原始目录
测试集数量为:368
训练集数量为:7007
>>> 开始校验目录:[sample/new_train/]
开始校验原始图片集
原始集共有图片: 0
====以下0张图片有异常====
未发现异常(共 0 张图片)
========end
开始分离原始图片集为:测试集(5%)和训练集(95%
共分配0张图片到训练集和测试集,其中0张为异常留在原始目录
测试集数量为:0
训练集数量为:0

开始训练:
python train_model.py
训练大概要几个小时:
训练结果:

[训练集] 字符准确率为 1.00000 图片准确率为 1.00000 >>> loss 0.0029035145
[验证集] 字符准确率为 0.94750 图片准确率为 0.83000 >>> loss 0.0029035145
6970次训练 >>>
[训练集] 字符准确率为 0.99414 图片准确率为 0.99219 >>> loss 0.0040454771
[验证集] 字符准确率为 0.95500 图片准确率为 0.89000 >>> loss 0.0040454771
6980次训练 >>>
[训练集] 字符准确率为 0.99805 图片准确率为 0.99219 >>> loss 0.0039159926
[验证集] 字符准确率为 0.95500 图片准确率为 0.87000 >>> loss 0.0039159926
6990次训练 >>>
[训练集] 字符准确率为 1.00000 图片准确率为 1.00000 >>> loss 0.0033209689
[验证集] 字符准确率为 0.96500 图片准确率为 0.88000 >>> loss 0.0033209689
7000次训练 >>>
[训练集] 字符准确率为 0.99219 图片准确率为 0.99219 >>> loss 0.0044688974
[验证集] 字符准确率为 0.96500 图片准确率为 0.89000 >>> loss 0.0044688974

开启api功能:
python webserver_recognize_api.py

测试验证码是否能准确识别:
测试图片:
在这里插入图片描述
python recognize_local.py

接口响应: {
     
  "speed_time(ms)": 76, 
  "time": "1584877709842", 
  "value": "3tst"
}

2020-02-17 18:31:27 耗时:124ms 预测结果:3tst
============== end ==============

完美!perfect!

附,tensorflow注意事项:
1)先https://github.com/nickliqian/cnn_captcha 把代码clone到本机
在此,非常感谢大神Nick Li提供的代码
2)新建目录model,logs,sample/origin , sample/train, sample/test,
sample/api , sample/local, sample/new_train , sample/online
3) 把要训练的验证码按照,4位验证码标签_时间戳.png
的格式放进目录 sample/origin,至少要5000张以上,执行pythonverify_and_split_data.py
4)开始训练python train_model.py
如果报错断点是在代码:
saver.restore(sess, self.model_save_dir)
那么可以先把这段代码屏蔽,等训练集没有问题后可以再打开
5)训练完成后,需要先打开api才能验证

你可能感兴趣的:(pytesseract+tensorflow开发一个自己的验证码训练集)