生成常用验证码识别,基于PaddleOCR训练识别

★★★ 本文源自AlStudio社区精品项目,【点击此处】查看更多精品内容 >>>


生成常用验证码识别,基于PaddleOCR训练识别

零.背景

在一些传统网站或者App中登录需要验证码,验证码的形态各异,有数字,英文,中文,图形,问答。本项目通过PaddleOCR实现验证码的生成,数据预处理,训练,评估和模型导出

PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库,助力开发者训练出更好的模型,并应用落地。

一.环境安装

# 安装 PaddleOCR
%cd /home/aistudio/work
!git clone https://gitee.com/paddlepaddle/PaddleOCR.git
!pip install -r PaddleOCR/requirements.txt --user

%cd PaddleOCR/
# 下载英文PP-OCRv3的预训练模型
!wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/PP-OCRv3/english/en_PP-OCRv3_rec_train.tar
# 解压模型参数
%cd pretrain_models
!tar -xf en_PP-OCRv3_rec_train.tar && rm -rf en_PP-OCRv3_rec_train.tar

二.生成数据集

分别生成训练集,验证码集和测试集,放在 /work/datas/目录下

txt文件中默认请将图片路径和图片标签用 \t 分割,如用其他方式分割将造成训练报错。

图像文件名                 图像标注信息 

train_data/rec/train/word_001.jpg   简单可依赖
train_data/rec/train/word_002.jpg   用科技让复杂的世界更简单
...
import random
from PIL import Image, ImageDraw, ImageFont

class Datas(object):

    def __init__(self):
        self.dataPath = '/home/aistudio/work/datas/'

    def run(self):
        trainNums = 800
        vaildNums = 200
        testNums = 100
        self.trains(trainNums)
        self.vailds(vaildNums)
        self.tests(testNums)


    def trains(self, nums):
        filename = self.dataPath+'/train.txt'
        f = open(filename, 'w')
        for i in range(nums):
            text = self.text(4)
            self.create(text, 'train')
            f.write(self.dataPath+"train/"+text+".png\t"+text)
            f.write("\n")


    def vailds(self, nums):
        filename = self.dataPath+'/vaild.txt'
        f = open(filename, 'w')
        for i in range(nums):
            text = self.text(4)
            self.create(text, 'vaild')
            f.write(self.dataPath+"vaild/"+text+".png\t"+text)
            f.write("\n")

    def tests(self, nums):
        filename = self.dataPath+'/test.txt'
        f = open(filename, 'w')
        for i in range(nums):
            text = self.text(4)
            self.create(text, 'test')
            f.write(self.dataPath+"test/"+text+".png\t"+text)
            f.write("\n")


    def text(self, length):
        strs = 'abcdefghijklmnopqrstuvwxyz0123456789'
        res = ""
        for i in range(length):
            w = strs[random.randint(0, len(strs)-1)]
            w = w.upper() if random.randint(0,1) == 0 else w
            res += str(w)
        return res
        
    def create(self, text, mode):
        bg_color = (random.randrange(20, 120), random.randrange(20, 120), random.randrange(150, 255))
        width = 400
        height = 100

        im = Image.new('RGB',(width,height),bg_color)
        # 创建画笔对象
        draw = ImageDraw.Draw(im)

        # 构造字体对象
        font = ImageFont.truetype('font.ttf', 80)
        #font = ImageFont.load_default().font
        # 构造字体颜色
        fontcolor = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
        # 绘制4个字
        draw.text((random.randint(10, 30), (random.randint(0, 10))), text[0], font=font, fill=fontcolor)
        draw.text((random.randint(90, 130), (random.randint(0, 10))), text[1], font=font, fill=fontcolor)
        draw.text((random.randint(180, 230), (random.randint(0, 10))), text[2], font=font, fill=fontcolor)
        draw.text((random.randint(270, 330), (random.randint(0, 10))), text[3], font=font, fill=fontcolor)

        #调用画笔的point()函数绘制噪点
        for i in range(0, 10000):
            xy = (random.randrange(0, width), random.randrange(0, height))
            fill = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
            draw.point(xy, fill=fill)

        #释放画笔
        del draw
        # im.show()
        im.save(f'./datas/{mode}/{text}.png','png')
# 创建验证码图片
%cd /home/aistudio/work
!python datas.py

三.训练

这里使用英文PP-OCRv3模型进行训练,其配置文件在 PaddleOCR/configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml

# 替换当前配置文件
%cd /home/aistudio/work
!cp -r en_PP-OCRv3_rec.yml PaddleOCR/configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml
/home/aistudio/work

需要设置训练接和验证集的路径:data_dir字段和label_file_list字段

如需要可视化,可以设置use_visualdl 为true

设置预训练模型路径字段 pretrained_model

Global:
  debug: false
  use_gpu: true
  epoch_num: 500
  log_smooth_window: 20
  print_batch_step: 10
  save_model_dir: ./output/v3_en_mobile  # 设置模型保存路径
  save_epoch_step: 3
  eval_batch_step: [0, 2000]
  cal_metric_during_train: true
  pretrained_model: /home/aistudio/work/PaddleOCR/pretrain_models/en_PP-OCRv3_rec_train/best_accuracy  # 设置预训练模型路径
  checkpoints: 
  save_inference_dir: ./output/inference
  use_visualdl: true  # 设置可视化
  infer_img: doc/imgs_words/ch/word_1.jpg
  character_dict_path: ppocr/utils/en_dict.txt
  max_text_length: &max_text_length 25
  infer_mode: false
  use_space_char: true
  distributed: true
  save_res_path: ./output/rec/predicts_ppocrv3_en.txt


Optimizer:
  name: Adam
  beta1: 0.9
  beta2: 0.999
  lr:
    name: Cosine
    learning_rate: 0.001
    warmup_epoch: 5
  regularizer:
    name: L2
    factor: 3.0e-05


Architecture:
  model_type: rec
  algorithm: SVTR
  Transform:
  Backbone:
    name: MobileNetV1Enhance
    scale: 0.5
    last_conv_stride: [1, 2]
    last_pool_type: avg
  Head:
    name: MultiHead
    head_list:
      - CTCHead:
          Neck:
            name: svtr
            dims: 64
            depth: 2
            hidden_dims: 120
            use_guide: True
          Head:
            fc_decay: 0.00001
      - SARHead:
          enc_dim: 512
          max_text_length: *max_text_length

Loss:
  name: MultiLoss
  loss_config_list:
    - CTCLoss:
    - SARLoss:

PostProcess:  
  name: CTCLabelDecode

Metric:
  name: RecMetric
  main_indicator: acc
  ignore_space: False

Train:
  dataset:
    name: SimpleDataSet
    data_dir: /home/aistudio/work/datas/train  # 设置数据集路径
    ext_op_transform_idx: 1
    label_file_list:
    - /home/aistudio/work/datas/train.txt  # 设置标签路径
    transforms:
    - DecodeImage:
        img_mode: BGR
        channel_first: false
    - RecConAug:
        prob: 0.5
        ext_data_num: 2
        image_shape: [48, 320, 3]
        max_text_length: *max_text_length
    - RecAug:
    - MultiLabelEncode:
    - RecResizeImg:
        image_shape: [3, 48, 320]
    - KeepKeys:
        keep_keys:
        - image
        - label_ctc
        - label_sar
        - length
        - valid_ratio
  loader:
    shuffle: true
    batch_size_per_card: 128
    drop_last: true
    num_workers: 4
Eval:
  dataset:
    name: SimpleDataSet
    data_dir: /home/aistudio/work/datas/vaild # 设置数据集路径
    label_file_list:
    - /home/aistudio/work/datas/vaild.txt # 设置标签路径
    transforms:
    - DecodeImage:
        img_mode: BGR
        channel_first: false
    - MultiLabelEncode:
    - RecResizeImg:
        image_shape: [3, 48, 320]
    - KeepKeys:
        keep_keys:
        - image
        - label_ctc
        - label_sar
        - length
        - valid_ratio
  loader:
    shuffle: false
    drop_last: false
    batch_size_per_card: 128
    num_workers: 4
# 开始训练
%cd /home/aistudio/work/PaddleOCR/
!python3 tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml
# 断点训练
%cd /home/aistudio/work/PaddleOCR/
!python3 tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.checkpoints=./output/v3_en_mobile/iter_epoch_100

数据模型可视化结果

四.评估

训练中模型参数默认保存在Global.save_model_dir目录下。在评估指标时,需要设置Global.checkpoints指向保存的参数文件。评估数据集可以通过 configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml 修改Eval中的 data_dir 和 label_file_list 设置

# GPU 评估, Global.checkpoints 为待测权重
%cd /home/aistudio/work/PaddleOCR/
!python3 -m paddle.distributed.launch --gpus '0' tools/eval.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.checkpoints=./output/v3_en_mobile/best_accuracy

五.预测

Global.pretrained_model:使用的权重

Global.infer_img:待预测的图片路径

# 预测图片
%cd /home/aistudio/work/PaddleOCR/
!python3 tools/infer_rec.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=output/v3_en_mobile/best_accuracy  Global.infer_img=/home/aistudio/work/datas/test/3zE8.png

六. 模型导出+预测

# 模型导出
# -c 后面设置训练算法的yml配置文件
# -o 配置可选参数
# Global.pretrained_model 参数设置待转换的训练模型地址,不用添加文件后缀 .pdmodel,.pdopt或.pdparams。
# Global.save_inference_dir参数设置转换的模型将保存的地址。
%cd /home/aistudio/work/PaddleOCR/
!python3 tools/export_model.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy  Global.save_inference_dir=./inference/en_PP-OCRv3_rec/
# 使用导出模型进行预测
# image_dir 图片路径
# rec_model_dir 导出模型路径
# rec_char_dict_path 字段路径,当前项目选用的是  
# rec_image_shape 图片信息shape 同配置文件 image_shape 保持一致
# rec_char_dict_path 字段路径,当前使用英文字典,根据实际情况选择
!python3 tools/infer/predict_rec.py --image_dir="/home/aistudio/work/datas/test/3zE8.png" --rec_model_dir="./inference/en_PP-OCRv3_rec/" --rec_image_shape="3, 48, 320" --rec_char_dict_path="./ppocr/utils/en_dict.txt"

PaddleOCR内置了一部分字典,可以按需使用。

ppocr/utils/ppocr_keys_v1.txt 是一个包含6623个字符的中文字典

ppocr/utils/ic15_dict.txt 是一个包含36个字符的英文字典

ppocr/utils/dict/french_dict.txt 是一个包含118个字符的法文字典

ppocr/utils/dict/japan_dict.txt 是一个包含4399个字符的日文字典

ppocr/utils/dict/korean_dict.txt 是一个包含3636个字符的韩文字典

ppocr/utils/dict/german_dict.txt 是一个包含131个字符的德文字典

ppocr/utils/en_dict.txt 是一个包含96个字符的英文字典

七. 总结

通过PaddleOCR 可以快速搭建训练,评估,导出,预测模型,完成验证码的识别工程。通过更换不同的预训练模型,可以二次训练出不同的验证码识别模型,支持中英文和其他多语种。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值