前言
由于业务需要识别银行卡卡号,为了降低成本,网上找了各种开源框架,最后决定使用PaddleOCR+Flask+Layui搭建一个提供webapi接口的OCR平台,本文尽量从小白基础讲解整个搭建过程,如有不足之处尽情见谅。文末附源代码,本地或者直接部署到Linux就可以使用,内含训练好的模型。
一、环境准备
-
下载源码
下载paddleOCR的2.8分支,下载地址:
https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.8 -
运行环境准备
使用的 Anaconda创建Python环境(本文用的是Python 3.8.5),详细请看源码说明:
https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.8/doc/doc_ch/environment.md -
安装requirements
在项目根目录,执行安装requirements.txt,下载慢的话换国内镜像源试试。
pip install -r requirements.txt
为了精准的识别出银行卡号,大致分为两个步骤,检测文本的位置,然后对检测出的位置进行文字识别,如果图片方向不正的话,还要进行方向检测,本文仅对文本检测和文本识别进行训练、推理,具体可以看官方说明:
https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.8/doc/doc_ch/training.md
二、文本检测
- 训练数据
训练数据来源有两种,一种是自己用PPOCRLabel标注数据,一种用别人训练好的数据。
PPOCRLabel安装和使用教程:
https://www.jianshu.com/p/4133fbf91981
3000多张银行卡号已标注文本检测数据集:
https://download.youkuaiyun.com/download/YY007H/85374437 - 训练模型
开始训练前,可以看下官网文档,有详细训练和微调说明:
文本检测:
https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.8/doc/doc_ch/detection.md
模型微调:
https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.8/doc/doc_ch/finetune.md
本文选择PP-OCRv3模型(配置文件:ch_PP-OCRv3_det_student.yml,预训练模型:ch_PP-OCRv3_det_distill_train.tar)进行微调。
ch_PP-OCRv3_det_distill_train.tar 下载地址:
https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_distill_train.tar
ch_PP-OCRv3_det_student.yml 配置文件如下:
Global:
debug: false
use_gpu: true
epoch_num: 1200 #最大训练epoch数
log_smooth_window: 20 #log队列长度,每次打印输出队列里的中间值
print_batch_step: 2 #设置打印log间隔
save_model_dir: ./output/ch_PP-OCRv3_det_student/ #设置输出模型路径
save_epoch_step: 1200 #设置模型保存间隔
eval_batch_step: 1500 #设置模型评估间隔
cal_metric_during_train: false
pretrained_model: ./pretrain_models/ch_PP-OCRv3_det_distill_train/student.pdparams #预训练模型路径
checkpoints: null
save_inference_dir: null
use_visualdl: True
infer_img: doc/imgs_en/img_10.jpg
save_res_path: ./output/ch_PP-OCRv3_det_student/predicts_db.txt
distributed: true
Architecture:
model_type: det
algorithm: DB
Transform:
Backbone:
name: MobileNetV3
scale: 0.5
model_name: large
disable_se: True
Neck:
name: RSEFPN
out_channels: 96
shortcut: True
Head:
name: DBHead
k: 50
Loss:
name: DBLoss
balance_loss: true
main_loss_type: DiceLoss
alpha: 5
beta: 10
ohem_ratio: 3
Optimizer:
name: Adam
beta1: 0.9
beta2: 0.999
lr:
name: Cosine
learning_rate: 0.001
warmup_epoch: 2
regularizer:
name: L2
factor: 0
PostProcess:
name: DBPostProcess
thresh: 0.3
box_thresh: 0.6
max_candidates: 1000
unclip_ratio: 1.5
Metric:
name: DetMetric
main_indicator: hmean
Train:
dataset:
name: SimpleDataSet
data_dir: ./pretrain_models/train_data/ #标注数据集路径
label_file_list:
- "./pretrain_models/train_data/bank/bank1/real_det_train.txt"
- "./pretrain_models/train_data/bank/bank2/real_det_train.txt"
- "./pretrain_models/train_data/bank/bank3/real_det_train.txt"
ratio_list: [ 1.0, 1.0 , 1.0 ]
transforms:
- DecodeImage:
img_mode: BGR
channel_first: false
- DetLabelEncode: null
- IaaAugment:
augmenter_args:
- type: Fliplr
args:
p: 0.5
- type: Affine
args:
rotate:
- -10
- 10
- type: Resize
args:
size:
- 0.5
- 3
- EastRandomCropData:
size:
- 960
- 960
max_tries: 50
keep_ratio: true
- MakeBorderMap:
shrink_ratio: 0.4
thresh_min: 0.3
thresh_max: 0.7
- MakeShrinkMap:
shrink_ratio: 0.4
min_text_size: 8
- NormalizeImage:
scale: 1./255.
mean:
- 0.485
- 0.456
- 0.406
std:
- 0.229
- 0.224
- 0.225
order: hwc
- ToCHWImage