【人工智能学习之PaddleOCR快速上手】

PaddleOCR 下载与安装

1 创建环境

conda create -n paddleOCR python=3.7
conda activate paddleOCR

2 安装PaddlePaddle
可以先升级一下pip,防止后面出现一些错误

pip3 install --upgrade pip

如果机器是CUDA9或者CUDA10,可以运行这个命令

pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple

如果机器是CPU,可以运行这个命令安装

pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple

如果是网络问题可以切换其它的镜像源比如阿里,如下:

pip install paddlepaddle -i https://mirrors.aliyun.com/pypi/simple/

3 安装PaddleOCR whl包

pip install paddleocr

4 克隆

git clone https://github.com/PaddlePaddle/PaddleOCR

5 安装PaddleOCR 第三方依赖包

命令行进入 PaddleOCR 文件夹下

cd PaddleOCR

安装第三方依赖项

pip3 install -r requirements.txt

下载的太慢可以使用一些镜像源

pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/

命令行便捷使用

1 命令行使用
PaddleOCR提供了一系列测试图片,点击这里下载并解压ppocr_img.zip,然后在终端中切换到相应目录。
在这里插入图片描述
然后我们可以使用以下命令测试一下。

paddleocr --image_dir ./imgs/11.jpg --use_angle_cls true --use_gpu false

检测+方向分类器+识别全流程:–use_angle_cls true设置使用方向分类器识别180度旋转文字,–use_gpu false设置不使用GPU

这个命令会直接帮助我们下载权重文件。
并且我们可以看到它的输出效果。结果是一个list,每个item包含了文本框,文字和识别置信度。
在这里插入图片描述
此外,paddleocr也支持输入pdf文件,并且可以通过指定参数page_num来控制推理前面几页,默认为0,表示推理所有页。

paddleocr --image_dir ./xxx.pdf --use_angle_cls true --use_gpu false --page_num 2

单独使用检测:设置–rec为false

paddleocr --image_dir ./imgs/11.jpg --rec false

结果是一个list,每个item只包含文本框
在这里插入图片描述
单独使用识别:设置–det为false

paddleocr --image_dir ./imgs_words/ch/word_1.jpg --det false

结果是一个list,每个item只包含识别结果和识别置信度
在这里插入图片描述
PaddleOCR目前支持80个语种,可以通过修改–lang参数进行切换,对于英文模型,指定–lang=en。
同样,使用这个命令会下载相应所需要的权重文件

paddleocr --image_dir ./imgs_en/254.jpg --lang=en

在这里插入图片描述
在这里插入图片描述
常用的多语言简写包括

语种缩写
中文ch
法文fr
日文japan
英文en
德文german
韩文korean
繁体中文chinese_cht
意大利文it
俄罗斯文ru

Python脚本使用

通过Python脚本使用PaddleOCR whl包,whl包会自动下载ppocr轻量级模型作为默认模型。

检测+方向分类器+识别全流程:

from paddleocr import PaddleOCR, draw_ocr

# Paddleocr目前支持的多语言语种可以通过修改lang参数进行切换
# 例如`ch`, `en`, `fr`, `german`, `korean`, `japan`
ocr = PaddleOCR(use_angle_cls=True, lang="ch")  # need to run only once to download and load model into memory
img_path = './imgs/11.jpg'
result = ocr.ocr(img_path, cls=True)
for idx in range(len(result)):
    res = result[idx]
    for line in res:
        print(line)

# 显示结果
from PIL import Image
result = result[0]
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]
im_show = draw_ocr(image, boxes, txts, scores, font_path='./fonts/simfang.ttf')
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')

在这里插入图片描述
随手拍一张试试效果:
在这里插入图片描述

在这里插入图片描述
不难发现效果是非常好的,即便字体有一些形变也能正确识别。

如果输入是PDF文件,那么可以参考下面代码进行可视化:

from paddleocr import PaddleOCR, draw_ocr

# Paddleocr目前支持的多语言语种可以通过修改lang参数进行切换
# 例如`ch`, `en`, `fr`, `german`, `korean`, `japan`
PAGE_NUM = 10 # 将识别页码前置作为全局,防止后续打开pdf的参数和前文识别参数不一致 / Set the recognition page number
pdf_path = 'default.pdf'
ocr = PaddleOCR(use_angle_cls=True, lang="ch", page_num=PAGE_NUM)  # need to run only once to download and load model into memory
# ocr = PaddleOCR(use_angle_cls=True, lang="ch", page_num=PAGE_NUM,use_gpu=0) # 如果需要使用GPU,请取消此行的注释 并注释上一行 / To Use GPU,uncomment this line and comment the above one.
result = ocr.ocr(pdf_path, cls=True)
for idx in range(len(result)):
    res = result[idx]
    if res == None: # 识别到空页就跳过,防止程序报错 / Skip when empty result detected to avoid TypeError:NoneType
        print(f"[DEBUG] Empty page {idx+1} detected, skip it.")
        continue
    for line in res:
        print(line)
# 显示结果
import fitz
from PIL import Image
import cv2
import numpy as np
imgs = []
with fitz.open(pdf_path) as pdf:
    for pg in range(0, PAGE_NUM):
        page = pdf[pg]
        mat = fitz.Matrix(2, 2)
        pm = page.get_pixmap(matrix=mat, alpha=False)
        # if width or height > 2000 pixels, don't enlarge the image
        if pm.width > 2000 or pm.height > 2000:
            pm = page.get_pixmap(matrix=fitz.Matrix(1, 1), alpha=False)
        img = Image.frombytes("RGB", [pm.width, pm.height], pm.samples)
        img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
        imgs.append(img)
for idx in range(len(result)):
    res = result[idx]
    if res == None:
        continue
    image = imgs[idx]
    boxes = [line[0] for line in res]
    txts = [line[1][0] for line in res]
    scores = [line[1][1] for line in res]
    im_show = draw_ocr(image, boxes, txts, scores, font_path='doc/fonts/simfang.ttf')
    im_show = Image.fromarray(im_show)
    im_show.save('result_page_{}.jpg'.format(idx))

要使用滑动窗口进行光学字符识别(OCR),可以使用以下代码片段:

from paddleocr import PaddleOCR
from PIL import Image, ImageDraw, ImageFont

# 初始化OCR引擎
ocr = PaddleOCR(use_angle_cls=True, lang="en")

img_path = "./very_large_image.jpg"
slice = {'horizontal_stride': 300, 'vertical_stride': 500, 'merge_x_thres': 50, 'merge_y_thres': 35}
results = ocr.ocr(img_path, cls=True, slice=slice)

# 加载图像
image = Image.open(img_path).convert("RGB")
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("./doc/fonts/simfang.ttf", size=20)  # 根据需要调整大小

# 处理并绘制结果
for res in results:
    for line in res:
        box = [tuple(point) for point in line[0]]
        # 找出边界框
        box = [(min(point[0] for point in box), min(point[1] for point in box)),
               (max(point[0] for point in box), max(point[1] for point in box))]
        txt = line[1][0]
        draw.rectangle(box, outline="red", width=2)  # 绘制矩形
        draw.text((box[0][0], box[0][1] - 25), txt, fill="blue", font=font)  # 在矩形上方绘制文本

# 保存结果
image.save("result.jpg")

此示例初始化了启用角度分类的PaddleOCR实例,并将语言设置为英语。然后调用ocr方法,并使用多个参数来自定义检测和识别过程,包括处理图像切片的slice参数。

模型训练方法

(以下文字转载官方文档training)

PP-OCR模型训练

本文将介绍模型训练时需掌握的基本概念,和训练时的调优方法。

同时会简单介绍PaddleOCR模型训练数据的组成部分,以及如何在垂类场景中准备数据finetune模型。

1. 配置文件说明

PaddleOCR模型使用配置文件管理网络训练、评估的参数。在配置文件中,可以设置组建模型、优化器、损失函数、模型前后处理的参数,PaddleOCR从配置文件中读取到这些参数,进而组建出完整的训练流程,完成模型训练,在需要对模型进行优化的时,可以通过修改配置文件中的参数完成配置,使用简单且方便修改。

完整的配置文件说明可以参考配置文件

2. 基本概念

模型训练过程中需要手动调整一些超参数,帮助模型以最小的代价获得最优指标。不同的数据量可能需要不同的超参,当您希望在自己的数据上finetune或对模型效果调优时,有以下几个参数调整策略可供参考:

2.1 学习率

学习率是训练神经网络的重要超参数之一,它代表在每一次迭代中梯度向损失函数最优解移动的步长。
在PaddleOCR中提供了多种学习率更新策略,可以通过配置文件修改,例如:

Optimizer:
  ...
  lr:
    name: Piecewise
    decay_epochs : [700, 800]
    values : [0.001, 0.0001]
    warmup_epoch: 5

Piecewise 代表分段常数衰减,在不同的学习阶段指定不同的学习率,在每段内学习率相同。
warmup_epoch 代表在前5个epoch中,学习率将逐渐从0增加到base_lr。全部策略可以参考代码learning_rate.py

2.2 正则化

正则化可以有效的避免算法过拟合,PaddleOCR中提供了L1、L2正则方法,L1 和 L2 正则化是最常用的正则化方法。L1 正则化向目标函数添加正则化项,以减少参数的绝对值总和;而 L2 正则化中,添加正则化项的目的在于减少参数平方的总和。配置方法如下:

Optimizer:
  ...
  regularizer:
    name: L2
    factor: 2.0e-05

2.3 评估指标

(1)检测阶段:先按照检测框和标注框的IOU评估,IOU大于某个阈值判断为检测准确。这里检测框和标注框不同于一般的通用目标检测框,是采用多边形进行表示。检测准确率:正确的检测框个数在全部检测框的占比,主要是判断检测指标。检测召回率:正确的检测框个数在全部标注框的占比,主要是判断漏检的指标。

(2)识别阶段: 字符识别准确率,即正确识别的文本行占标注的文本行数量的比例,只有整行文本识别对才算正确识别。

(3)端到端统计: 端对端召回率:准确检测并正确识别文本行在全部标注文本行的占比; 端到端准确率:准确检测并正确识别文本行在 检测到的文本行数量 的占比; 准确检测的标准是检测框与标注框的IOU大于某个阈值,正确识别的检测框中的文本与标注的文本相同。

3. 数据与垂类场景

3.1 训练数据

目前开源的模型,数据集和量级如下:

- 检测:
    - 英文数据集,ICDAR2015
    - 中文数据集,LSVT街景数据集训练数据3w张图片

- 识别:
    - 英文数据集,MJSynth和SynthText合成数据,数据量上千万。
    - 中文数据集,LSVT街景数据集根据真值将图crop出来,并进行位置校准,总共30w张图像。此外基于LSVT的语料,合成数据500w。
    - 小语种数据集,使用不同语料和字体,分别生成了100w合成数据集,并使用ICDAR-MLT作为验证集。

其中,公开数据集都是开源的,用户可自行搜索下载,也可参考中文数据集,合成数据暂不开源,用户可使用开源合成工具自行合成,可参考的合成工具包括text_rendererSynthTextTextRecognitionDataGenerator 等。

3.2 垂类场景

PaddleOCR主要聚焦通用OCR,如果有垂类需求,您可以用PaddleOCR+垂类数据自己训练;
如果缺少带标注的数据,或者不想投入研发成本,建议直接调用开放的API,开放的API覆盖了目前比较常见的一些垂类。

3.3 自己构建数据集

在构建数据集时有几个经验可供参考:

(1) 训练集的数据量:

a. 检测需要的数据相对较少,在PaddleOCR模型的基础上进行Fine-tune,一般需要500张可达到不错的效果。
b. 识别分英文和中文,一般英文场景需要几十万数据可达到不错的效果,中文则需要几百万甚至更多。

(2)当训练数据量少时,可以尝试以下三种方式获取更多的数据:

a. 人工采集更多的训练数据,最直接也是最有效的方式。
b. 基于PIL和opencv基本图像处理或者变换。例如PIL中ImageFont, Image, ImageDraw三个模块将文字写到背景中,opencv的旋转仿射变换,高斯滤波等。
c. 利用数据生成算法合成数据,例如pix2pix或[StyleText](https://github.com/PFCCLab/StyleText)等算法。

4. 常见问题

Q:训练CRNN识别时,如何选择合适的网络输入shape?

A:一般高度采用32,最长宽度的选择,有两种方法:

(1)统计训练样本图像的宽高比分布。最大宽高比的选取考虑满足80%的训练样本。

(2)统计训练样本文字数目。最长字符数目的选取考虑满足80%的训练样本。然后中文字符长宽比近似认为是1,英文认为3:1,预估一个最长宽度。

Q:识别训练时,训练集精度已经到达90了,但验证集精度一直在70,涨不上去怎么办?

A:训练集精度90,测试集70多的话,应该是过拟合了,有两个可尝试的方法:

(1)加入更多的增广方式或者调大增广prob的[概率](https://github.com/PaddlePaddle/PaddleOCR/blob/dygraph/ppocr/data/imaug/rec_img_aug.py#L341),默认为0.4。

(2)调大系统的[l2 dcay值](https://github.com/PaddlePaddle/PaddleOCR/blob/a501603d54ff5513fc4fc760319472e59da25424/configs/rec/ch_ppocr_v1.1/rec_chinese_lite_train_v1.1.yml#L47)

Q: 识别模型训练时,loss能正常下降,但acc一直为0

A:识别模型训练初期acc为0是正常的,多训一段时间指标就上来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值