PPv3-OCR自定义数据从训练到部署

PPv3-OCR自定义数据从训练到部署

最近一段时间使用PaddleOCR做了一个OCR相关的项目,本文记录一下项目的实现过程。由于数据集是公司的真是数据,不方便公开,我从网上搜集了一些数据集,给大家做演示。PaddleOCR用的最新的PaddleOCR-release-2.5,模型用的v3模型。

一、配置Paddle环境

创建虚拟环境

conda create --name pp python=3.7

PPv3-OCR自定义数据从训练到部署

创建完成后激活环境

conda activate pp

PPv3-OCR自定义数据从训练到部署

登录飞桨的官网下载最新的paddle,官网地址:飞桨PaddlePaddle-源于产业实践的开源深度学习平台

选择合适的CUDA版本,然后会在下面生成对应的命令。

PPv3-OCR自定义数据从训练到部署

然后,复制命令即可

conda install paddlepaddle-gpu==2.2.2 cudatoolkit=11.2 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ -c conda-forge

二、配置PaddleOCR

下载地址:(https://gitee.com/paddlepaddle/PaddleOCR

将其下载到本地,然后解压配置环境。

1、安装python

1、yaml

pip install pyyaml

2、imgaug

pip install imgaug

3、pyclipper

pip install pyclipper

4、lmdb

pip install lmdb

5、Levenshtein

pip install Levenshtein

6、tqdm

pip install tqdm

2、测试环境

模型简介模型名称推荐场景检测模型方向分类器识别模型中英文超轻量PP-OCRv3模型(16.2M)ch_PP-OCRv3_xx移动端&服务器端
推理模型 训练模型 推理模型 训练模型 推理模型 训练模型

英文超轻量PP-OCRv3模型(13.4M)en_PP-OCRv3_xx移动端&服务器端
推理模型 训练模型 推理模型 训练模型 推理模型 训练模型

中英文超轻量PP-OCRv2模型(13.0M)ch_PP-OCRv2_xx移动端&服务器端
推理模型 训练模型 推理模型 预训练模型 推理模型 训练模型

中英文超轻量PP-OCR mobile模型(9.4M)ch_ppocr_mobile_v2.0_xx移动端&服务器端
推理模型 预训练模型 推理模型 预训练模型 推理模型 预训练模型

中英文通用PP-OCR server模型(143.4M)ch_ppocr_server_v2.0_xx服务器端
推理模型 预训练模型 推理模型 预训练模型 推理模型 预训练模型

选择上面的一组模型放入到inference文件夹中,注意:是一组,包括:监测模型、方向分类器、识别模型。如下:

PaddleOCR-release-2.5
    └─inference
       ├─ch_PP-OCRv3_det_infer #检测模型
       │     ├─inference.pdiparams
       │     ├─inference.pdiparams.info
       │     └─inference.pdmodel
       ├─ch_PP-OCRv3_rec_infer #识别模型
       │     ├─inference.pdiparams
       │     ├─inference.pdiparams.info
       │     └─inference.pdmodel
       └─cls #方向分类器
             ├─inference.pdiparams
             ├─inference.pdiparams.info
             └─inference.pdmodel

PPv3-OCR自定义数据从训练到部署

将待检测的图片放在./doc/imgs/文件夹下面,然后执行命令:

python tools/infer/predict_system.py --image_dir="./doc/imgs/0.jpg" --det_model_dir="./inference/ch_PP-OCRv3_det_infer/" --cls_model_dir="./inference/cls/" --rec_model_dir="./inference/ch_PP-OCRv3_rec_infer/" --use_angle_cls=true

然后在inference_results文件夹中查看结果,例如:

PPv3-OCR自定义数据从训练到部署

如果能看到结果就说明环境是ok的。

更多的命令,如下:


python3 tools/infer/predict_system.py --image_dir="./doc/imgs/00018069.jpg" --det_model_dir="./ch_PP-OCRv3_det_infer/" --cls_model_dir="./cls/" --rec_model_dir="./ch_PP-OCRv3_rec_infer/" --use_angle_cls=true --rec_image_shape=3,48,320

python3 tools/infer/predict_system.py --image_dir="./doc/imgs/00018069.jpg" --det_model_dir="./ch_PP-OCRv3_det_infer/" --rec_model_dir="./ch_PP-OCRv3_rec_infer/" --use_angle_cls=false --rec_image_shape=3,48,320

python3 tools/infer/predict_system.py --image_dir="./doc/imgs/00018069.jpg" --det_model_dir="./ch_PP-OCRv3_det_infer/" --rec_model_dir="./ch_PP-OCRv3_rec_infer/" --use_angle_cls=false --use_mp=True --total_process_num=6 --rec_image_shape=3,48,320

也可以新建test.py脚本进行测试,系统会自动下载预训练模型,代码如下:

import cv2

from paddleocr import PaddleOCR, draw_ocr

ocr = PaddleOCR(use_angle_cls=True, lang="ch")
img_path = './doc/imgs_en/img_10.jpg'
result = ocr.ocr(img_path, cls=True)
for line in result:
    print(line)

from PIL import Image
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')

开始运行:

PPv3-OCR自定义数据从训练到部署
红框的位置显示了详细的配置信息。
查看结果:
PPv3-OCR自定义数据从训练到部署
ocr.ocr(img_path, cls=True)这个方法不仅支持传入图片的路径,还支持ndarray和list类型。比如传入ndarray
import cv2

from paddleocr import PaddleOCR, draw_ocr

ocr = PaddleOCR(use_angle_cls=True, lang="ch")
img_path = './doc/imgs_en/img_10.jpg'

from PIL import Image
import numpy as np
img = Image.open(img_path)
img = np.array(img)
result = ocr.ocr(img, cls=True)

img=cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
result = ocr.ocr(img, cls=True)

上面这两种方式都是可以的,大家自行尝试。

三 模型列表及其对应的配置文件

1. 文本检测模型

1.1 中文检测模型

模型名称模型简介配置文件推理模型大小下载地址ch_PP-OCRv3_det_slim【最新】slim量化+蒸馏版超轻量模型,支持中英文、多语种文本检测ch_PP-OCRv3_det_cml.yml1.1M
推理模型 训练模型 nb模型

ch_PP-OCRv3_det【最新】原始超轻量模型,支持中英文、多语种文本检测ch_PP-OCRv3_det_cml.yml3.8M
推理模型 训练模型

ch_PP-OCRv2_det_slimslim量化+蒸馏版超轻量模型,支持中英文、多语种文本检测ch_PP-OCRv2_det_cml.yml3M
推理模型

ch_PP-OCRv2_det原始超轻量模型,支持中英文、多语种文本检测ch_PP-OCRv2_det_cml.yml3M
推理模型 训练模型

ch_ppocr_mobile_slim_v2.0_detslim裁剪版超轻量模型,支持中英文、多语种文本检测ch_det_mv3_db_v2.0.yml2.6M
推理模型

ch_ppocr_mobile_v2.0_det原始超轻量模型,支持中英文、多语种文本检测ch_det_mv3_db_v2.0.yml3M
推理模型 训练模型

ch_ppocr_server_v2.0_det通用模型,支持中英文、多语种文本检测,比超轻量模型更大,但效果更好ch_det_res18_db_v2.0.yml47M
推理模型 训练模型

1.2 英文检测模型

模型名称模型简介配置文件推理模型大小下载地址en_PP-OCRv3_det_slim【最新】slim量化版超轻量模型,支持英文、数字检测ch_PP-OCRv3_det_cml.yml1.1M
推理模型 训练模型 nb模型

en_PP-OCRv3_det【最新】原始超轻量模型,支持英文、数字检测ch_PP-OCRv3_det_cml.yml3.8M
推理模型 训练模型

  • 注:英文检测模型的结构与中文检测模型完全相同,只是训练数据不同。这里只提供了相同的配置文件。
    [En]

    Note: the structure of the English detection model is exactly the same as that of the Chinese detection model, except that the training data are different. Only the same configuration file is provided here.*

1.3 多语言检测模型

模型名称模型简介配置文件推理模型大小下载地址ml_PP-OCRv3_det_slim【最新】slim量化版超轻量模型,支持多语言检测ch_PP-OCRv3_det_cml.yml1.1M
推理模型 训练模型 nb模型

ml_PP-OCRv3_det【最新】原始超轻量模型,支持多语言检测ch_PP-OCRv3_det_cml.yml3.8M
推理模型 训练模型

  • 注:除训练数据不同外,多语检测模型的结构与中文检测模型完全相同。这里只提供了相同的配置文件。
    [En]

    Note: the structure of the multilingual detection model is exactly the same as that of the Chinese detection model, except for the different training data. Only the same configuration file is provided here.*

2. 文本识别模型

2.1 中文识别模型

模型名称模型简介配置文件推理模型大小下载地址ch_PP-OCRv3_rec_slim【最新】slim量化版超轻量模型,支持中英文、数字识别ch_PP-OCRv3_rec_distillation.yml4.9M
推理模型 训练模型 nb模型

ch_PP-OCRv3_rec【最新】原始超轻量模型,支持中英文、数字识别ch_PP-OCRv3_rec_distillation.yml12.4M
推理模型 训练模型

ch_PP-OCRv2_rec_slimslim量化版超轻量模型,支持中英文、数字识别ch_PP-OCRv2_rec.yml9M
推理模型 训练模型

ch_PP-OCRv2_rec原始超轻量模型,支持中英文、数字识别ch_PP-OCRv2_rec_distillation.yml8.5M
推理模型 训练模型

ch_ppocr_mobile_slim_v2.0_recslim裁剪量化版超轻量模型,支持中英文、数字识别rec_chinese_lite_train_v2.0.yml6M
推理模型 训练模型

ch_ppocr_mobile_v2.0_rec原始超轻量模型,支持中英文、数字识别rec_chinese_lite_train_v2.0.yml5.2M
推理模型 训练模型 预训练模型

ch_ppocr_server_v2.0_rec通用模型,支持中英文、数字识别rec_chinese_common_train_v2.0.yml94.8M
推理模型 训练模型 预训练模型

说明: 训练模型是基于预训练模型在真实数据与竖排合成文本数据上finetune得到的模型,在真实应用场景中有着更好的表现, 预训练模型则是直接基于全量真实数据与合成数据训练得到,更适合用于在自己的数据集上finetune。

2.2 英文识别模型

模型名称模型简介配置文件推理模型大小下载地址en_PP-OCRv3_rec_slim【最新】slim量化版超轻量模型,支持英文、数字识别en_PP-OCRv3_rec.yml3.2M
推理模型 训练模型 nb模型

en_PP-OCRv3_rec【最新】原始超轻量模型,支持英文、数字识别en_PP-OCRv3_rec.yml9.6M
推理模型 训练模型

en_number_mobile_slim_v2.0_recslim裁剪量化版超轻量模型,支持英文、数字识别rec_en_number_lite_train.yml2.7M
推理模型 训练模型

en_number_mobile_v2.0_rec原始超轻量模型,支持英文、数字识别rec_en_number_lite_train.yml2.6M
推理模型 训练模型

2.3 多语言识别模型(更多语言持续更新中…)

模型名称字典文件模型简介配置文件推理模型大小下载地址korean_PP-OCRv3_recppocr/utils/dict/korean_dict.txt韩文识别korean_PP-OCRv3_rec.yml11M
推理模型 训练模型

japan_PP-OCRv3_recppocr/utils/dict/japan_dict.txt日文识别japan_PP-OCRv3_rec.yml11M
推理模型 训练模型

chinese_cht_PP-OCRv3_recppocr/utils/dict/chinese_cht_dict.txt中文繁体识别chinese_cht_PP-OCRv3_rec.yml12M
推理模型 训练模型

te_PP-OCRv3_recppocr/utils/dict/te_dict.txt泰卢固文识别te_PP-OCRv3_rec.yml9.6M
推理模型 训练模型

ka_PP-OCRv3_recppocr/utils/dict/ka_dict.txt卡纳达文识别ka_PP-OCRv3_rec.yml9.9M
推理模型 训练模型

ta_PP-OCRv3_recppocr/utils/dict/ta_dict.txt泰米尔文识别ta_PP-OCRv3_rec.yml9.6M
推理模型 训练模型

latin_PP-OCRv3_recppocr/utils/dict/latin_dict.txt拉丁文识别latin_PP-OCRv3_rec.yml9.7M
推理模型 训练模型

arabic_PP-OCRv3_recppocr/utils/dict/arabic_dict.txt阿拉伯字母arabic_PP-OCRv3_rec.yml9.6M
推理模型 训练模型

cyrillic_PP-OCRv3_recppocr/utils/dict/cyrillic_dict.txt斯拉夫字母cyrillic_PP-OCRv3_rec.yml9.6M
推理模型 训练模型

devanagari_PP-OCRv3_recppocr/utils/dict/devanagari_dict.txt梵文字母devanagari_PP-OCRv3_rec.yml9.9M
推理模型 训练模型

查看完整语种列表与使用教程请参考: 多语言模型

3. 文本方向分类模型

模型名称模型简介配置文件推理模型大小下载地址ch_ppocr_mobile_slim_v2.0_clsslim量化版模型,对检测到的文本行文字角度分类cls_mv3.yml2.1M
推理模型 训练模型 nb模型

ch_ppocr_mobile_v2.0_cls原始分类器模型,对检测到的文本行文字角度分类

四、标注工具PPOCRLabel

PPOCRLabel是一款适用于OCR领域的半自动化图形标注工具,内置PP-OCR模型对数据自动标注和重新识别。使用Python3和PyQT5编写,支持矩形框标注和四点标注模式,导出格式可直接用于PaddleOCR检测和识别模型的训练。

由于PaddleOCR已经包含PPOCRLabel,可以直接运行,命令如下:

cd ./PPOCRLabel  # 切换到PPOCRLabel目录
python PPOCRLabel.py --lang ch

PPv3-OCR自定义数据从训练到部署

点击自动批注后,您可以看到自动批注的结果。用户可以根据自己的需求进行微调和修改,非常简单。

[En]

After clicking on the automatic annotation, you can see the result of the automatic annotation. Users can fine-tune and modify it according to their own needs, which is very simple.

如果标注的结果与您预期的大不相同,您可以使用标记后的数据集来训练模型,然后标记一定量的数据集来替换官方模型。模型位置:

[En]

If the result of the annotation is quite different from what you expected, you can use the labeled data set to train a model after tagging a certain amount of data set to replace the official model. Model location:

PPv3-OCR自定义数据从训练到部署
上图是我的模型的位置,大家可以试着找找自己模型的位置。
更多的方式和注意事项,详见下面

1. 安装与运行

1.1 安装PaddlePaddle

pip3 install --upgrade pip

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

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

更多的版本需求,请参照安装文档中的说明进行操作。

1.2 安装与运行PPOCRLabel

PPOCRLabel可通过whl包与Python脚本两种方式启动,whl包形式启动更加方便,python脚本启动便于二次开发

1.2.1 通过whl包安装与运行

Windows
pip install PPOCRLabel
PPOCRLabel --lang ch

注意:通过whl包安装PPOCRLabel会自动下载 paddleocr whl包,其中shapely依赖可能会出现 [winRrror 126] 找不到指定模块的问题。 的错误,建议从这里下载并安装

Ubuntu Linux
pip3 install PPOCRLabel
pip3 install trash-cli
PPOCRLabel --lang ch
MacOS
pip3 install PPOCRLabel
pip3 install opencv-contrib-python-headless==4.2.0.32
PPOCRLabel --lang ch

如果上述安装出现问题,可以参考3.6节 错误提示

1.2.2 本地构建whl包并安装

cd PaddleOCR/PPOCRLabel
python3 setup.py bdist_wheel
pip3 install dist/PPOCRLabel-1.0.2-py2.py3-none-any.whl -i https://mirror.baidu.com/pypi/simple

1.2.3 通过Python脚本运行PPOCRLabel

如果您对PPOCRLabel文件有所更改,通过Python脚本运行会更加方面的看到更改的结果

cd ./PPOCRLabel
python PPOCRLabel.py --lang ch

2. 使用

2.1 操作步骤

  1. 安装与运行:使用上述命令安装与运行程序。
  2. 打开文件夹:在菜单栏点击 “文件” – “打开目录” 选择待标记图片的文件夹[1].

  3. 自动标注:点击 “自动标注”,使用PPOCR超轻量模型对图片文件名前图片状态[2]为 “X” 的图片进行自动标注。

  4. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”),用户可对当前图片中模型未检出的部分进行手动绘制标记框。点击键盘Q,则使用四点标注模式(或点击”编辑” – “四点标注”),用户依次点击4个点后,双击左键表示标注完成。
  5. 标记框绘制完成后,用户点击 “确认”,检测框会先被预分配一个 “待识别” 标签。
  6. 重新识别:将图片中的所有检测画绘制/调整完成后,点击 “重新识别”,PPOCR模型会对当前图片中的 所有检测框重新识别[3]。
  7. 内容更改:双击识别结果,对不准确的识别结果进行手动更改。
  8. 确认标记:点击 “确认”,图片状态切换为 “√”,跳转至下一张。
  9. 删除:点击 “删除图像”,图片将会被删除至回收站。
  10. 导出结果:用户可以通过菜单中”文件-导出标记结果”手动导出,同时也可以点击”文件 – 自动导出标记结果”开启自动导出。手动确认过的标记将会被存放在所打开图片文件夹下的 _Label.txt_中。在菜单栏点击 “文件” – “导出识别结果”后,会将此类图片的识别训练数据保存在 _crop_img_文件夹下,识别标签保存在 _rec_gt.txt_中[4]。

2.2 注意

[1] PPOCRLabel以文件夹为基本标记单位,打开待标记的图片文件夹后,不会在窗口栏中显示图片,而是在点击 “选择文件夹” 之后直接将文件夹下的图片导入到程序中。

[2] 图片状态表示本张图片用户是否手动保存过,未手动保存过即为 “X”,手动保存过为 “√”。点击 “自动标注”按钮后,PPOCRLabel不会对状态为 “√” 的图片重新标注。

[3] 点击”重新识别”后,模型会对图片中的识别结果进行覆盖。因此如果在此之前手动更改过识别结果,有可能在重新识别后产生变动。

[4] PPOCRLabel产生的文件放置于标记图片文件夹下,包括一下几种,请勿手动更改其中内容,否则会引起程序出现异常。

文件名说明Label.txt检测标签,可直接用于PPOCR检测模型训练。用户每确认5张检测结果后,程序会进行自动写入。当用户关闭应用程序或切换文件路径后同样会进行写入。fileState.txt图片状态标记文件,保存当前文件夹下已经被用户手动确认过的图片名称。Cache.cach缓存文件,保存模型自动识别的结果。rec_gt.txt识别标签。可直接用于PPOCR识别模型训练。需用户手动点击菜单栏”文件” – “导出识别结果”后产生。crop_img识别数据。按照检测框切割后的图片。与rec_gt.txt同时产生。

3. 说明

3.1 快捷键

快捷键说明Ctrl + shift + R对当前图片的所有标记重新识别W新建矩形框Q新建四点框Ctrl + E编辑所选框标签Ctrl + R重新识别所选标记Ctrl + C复制并粘贴选中的标记框Ctrl + 鼠标左键多选标记框Backspace删除所选框Ctrl + V确认本张图片标记Ctrl + Shift + d删除本张图片D下一张图片A上一张图片Ctrl++缩小Ctrl–放大↑→↓←移动标记框

3.2 内置模型

  • 默认模型:PPOCRLabel默认使用PaddleOCR中的中英文超轻量OCR模型,支持中英文与数字识别,多种语言检测。
  • 模型语言切换:用户可通过菜单栏中 “PaddleOCR” – “选择模型” 切换内置模型语言,目前支持的语言包括法文、德文、韩文、日文。具体模型下载链接可参考PaddleOCR模型列表.

  • 自定义模型:如果用户想将内置模型更换为自己的推理模型,可根据自定义模型代码使用,通过修改PPOCRLabel.py中针对PaddleOCR类的实例化,通过修改PPOCRLabel.py中针对PaddleOCR类的实例化) 实现,例如指定检测模型: self.ocr = PaddleOCR(det=True, cls=True, use_gpu=gpu, lang=lang),在 det_model_dir 中传入 自己的模型即可。

3.3 导出标记结果

PPOCRLabel支持三种导出方式:

  • 自动导出:点击”文件 – 自动导出标记结果”后,用户每确认过一张图片,程序自动将标记结果写入Label.txt中。若未开启此选项,则检测到用户手动确认过5张图片后进行自动导出。

    默认情况下自动导出功能为关闭状态

  • 手动导出:点击”文件 – 导出标记结果”手动导出标记。
  • 关闭应用程序导出

3.4 导出部分识别结果

针对部分难以识别的数据,通过在识别结果的复选框中 取消勾选相应的标记,其识别结果不会被导出。被取消勾选的识别结果在标记文件 label.txt 中的 difficult 变量保存为 True

注意:识别结果中的复选框状态仍需用户手动点击确认后才能保留

3.5 数据集划分

在终端中输入以下命令执行数据集划分脚本:

cd ./PPOCRLabel # 将目录切换到PPOCRLabel文件夹下
python gen_ocr_train_val_test.py --trainValTestRatio 6:2:2 --datasetRootPath ../train_data

参数说明:

  • trainValTestRatio 是训练集、验证集、测试集的图像数量划分比例,根据实际情况设定,默认是 6:2:2
  • datasetRootPath 是PPOCRLabel标注的完整数据集存放路径。默认路径是 PaddleOCR/train_data 分割数据集前应有如下结构:
|-train_data
  |-crop_img
    |- word_001_crop_0.png
    |- word_002_crop_0.jpg
    |- word_003_crop_0.jpg
    | ...

  | Label.txt
  | rec_gt.txt
  |- word_001.png
  |- word_002.jpg
  |- word_003.jpg
  | ...

3.6 错误提示

  • 如果同时使用whl包安装了paddleocr,其优先级大于通过paddleocr.py调用PaddleOCR类,whl包未更新时会导致程序异常。
  • PPOCRLabel 不支持对中文文件名的图片进行自动标注。
  • 针对Linux用户:如果您在打开软件过程中出现objc[XXXXX]开头的错误,证明您的opencv版本太高,建议安装4.2版本:
pip install opencv-python==4.2.0.32
  • 如果出现 Missing string id 开头的错误,需要重新编译资源:
pyrcc5 -o libs/resources.py resources.qrc
  • 如果出现 module 'cv2' has no attribute 'INTER_NEAREST'错误,需要首先删除所有opencv相关包,然后重新安装4.2.0.32版本的headless opencv
pip install opencv-contrib-python-headless==4.2.0.32

五、训练检测器

1、制作数据集

完成数据的标注就可以看是训练检测器了。找到Lable.txt,将其中一部分放到train_label.txt ,将一部分放到test_label.txt,将图片放到ppocr( 这个文件夹的名字和标注时的图片文件夹的名字一致),如下:

PPv3-OCR自定义数据从训练到部署
PaddleOCR-release-2.5/train_data/icdar2015/text_localization/
  └─ ppocr/         图片存放的位置
  └─ train_label.txt    icdar数据集的训练标注
  └─ test_label.txt     icdar数据集的测试标注

PPv3-OCR自定义数据从训练到部署

自定义分片数据集代码。我在这里不使用官方的切分方法,它是一种定制的切分方法。

[En]

Custom sharding dataset code. I do not use the official segmentation method here, it is a custom segmentation method.

import os
import shutil
from sklearn.model_selection import train_test_split

label_txt='./ppocr/Label.txt'
if not os.path.exists('tmp'):
    os.makedirs('tmp')
with open(label_txt, 'r') as f:
   txt_List=f.readlines()
   trainval_files, val_files = train_test_split(txt_List, test_size=0.1, random_state=42)
   print(trainval_files)
   f = open("train_label.txt", "w")
   f.writelines(trainval_files)
   f.close()
   f = open("test_label.txt", "w")
   f.writelines(val_files)
   f.close()
   for txt in txt_List:
       image_name=txt.split('\t')[0]
       new_path="./tmp/"+image_name.split('/')[1]
       shutil.move(image_name, new_path)
       print(image_name)

如果路径不存在,请手动创建。执行完成后将tmp文件夹里面的图片放到PaddleOCR-release-2.5/train_data/icdar2015/text_localization/ppocr/文件夹下面。如果不存在则自己创建。

2、下载预训练模型

然后下载预训练模型,将其放到pretrain_models文件夹中,命令如下:

# 根据backbone的不同选择下载对应的预训练模型
# 下载MobileNetV3的预训练模型
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/MobileNetV3_large_x0_5_pretrained.pdparams
# 或,下载ResNet18_vd的预训练模型
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/ResNet18_vd_pretrained.pdparams
# 或,下载ResNet50_vd的预训练模型
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/ResNet50_vd_ssld_pretrained.pdparams

不同的预训练模型对应不同的配置文件,详见第3节。
这次我选用如下图的配置:

PPv3-OCR自定义数据从训练到部署

3、修改配置文件

然后修改该config文件,路径: configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml.yml,打开文件对里面的参数进行修改该。

PPv3-OCR自定义数据从训练到部署

按照自己定义的路径,修改训练集的路径。

PPv3-OCR自定义数据从训练到部署

按照自己定义的路径,修改验证集的路径。

PPv3-OCR自定义数据从训练到部署
对BatchSize的修改。
如果训练出来的检测框偏小,可以修改参数unclip_ratio,将其调大即可。
PPv3-OCR自定义数据从训练到部署

; 4、开启训练

完成上面的工作就可以启动训练了,在pycharm的Terminal中输入命令:

注意:在PaddleOCR的根目录执行命令。

# 单机单卡训练
python tools/train.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml.yml  -o Global.pretrained_model=./pretrain_models/

PPv3-OCR自定义数据从训练到部署

更多的训练方式如下:


python3 tools/train.py -c configs/det/det_mv3_db.yml \
     -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \
     -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \
     -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

4.1、 断点训练

如果训练程序中断,如果希望加载训练中断的模型从而恢复训练,可以通过指定Global.checkpoints指定要加载的模型路径:

python3 tools/train.py -c configs/det/det_mv3_db.yml -o Global.checkpoints=./your/trained/model

注意Global.checkpoints的优先级高于 Global.pretrained_model的优先级,即同时指定两个参数时,优先加载 Global.checkpoints指定的模型,如果 Global.checkpoints指定的模型路径有误,会加载 Global.pretrained_model指定的模型。

4.2 混合精度训练

如果您想进一步加快训练速度,可以使用自动混合精度训练, 以单机单卡为例,命令如下:

python3 tools/train.py -c configs/det/det_mv3_db.yml -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained Global.use_amp=True Global.scale_loss=1024.0 Global.use_dynamic_loss_scaling=True

4.3 分布式训练

多机多卡训练时,通过 --ips 参数设置使用的机器IP地址,通过 --gpus 参数设置使用的GPU ID:

python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

注意: 采用多机多卡训练时,需要替换上面命令中的ips值为您机器的地址,机器之间需要能够相互ping通。另外,训练时需要在多个机器上分别启动命令。查看机器ip地址的命令为 ifconfig
分布式训练,我没有试过,主要是没有钞能力。

5、 模型评估与预测

5.1 指标评估

PaddleOCR计算三个OCR检测相关的指标,分别是:Precision、Recall、Hmean(F-Score)。

训练中模型参数默认保存在 Global.save_model_dir目录下。在评估指标时,需要设置 Global.checkpoints指向保存的参数文件。

python tools/eval.py -c configs/det/det_mv3_db.yml  -o Global.checkpoints="{path/to/weights}/best_accuracy"

5.2 测试检测效果

测试单张图像的检测效果:

python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/img_10.jpg" Global.pretrained_model="./output/det_db/best_accuracy"

测试DB模型时,调整后处理阈值:

python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/img_10.jpg" Global.pretrained_model="./output/det_db/best_accuracy"  PostProcess.box_thresh=0.6 PostProcess.unclip_ratio=2.0
  • 注: box_threshunclip_ratio是DB后处理参数,其他检测模型不支持。

测试文件夹下所有图像的检测效果:

python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/" Global.pretrained_model="./output/det_db/best_accuracy"

6. 模型导出与预测

inference 模型( paddle.jit.save保存的模型) 一般是模型训练,把模型结构和模型参数保存在文件中的固化模型,多用于预测部署场景。 训练过程中保存的模型是checkpoints模型,保存的只有模型的参数,多用于恢复训练等。 与checkpoints模型相比,inference 模型会额外保存模型的结构信息,在预测部署、加速推理上性能优越,灵活方便,适合于实际系统集成。

检测模型转inference 模型方式:
官方的例子:


python3 tools/export_model.py -c configs/det/det_mv3_db.yml -o Global.pretrained_model="./output/det_db/best_accuracy" Global.save_inference_dir="./output/det_db_inference/"

自己用的命令:

python tools/export_model.py -c output/db_mv3/config.yml -o Global.pretrained_model="./output/db_mv3/best_accuracy" Global.save_inference_dir="./output/det_db_inference/"

DB检测模型inference 模型预测:

python3 tools/infer/predict_det.py --det_algorithm="DB" --det_model_dir="./output/det_db_inference/" --image_dir="./doc/imgs/" --use_gpu=True

五、训练识别器

1、图片裁剪与数据集生成

在训练识别器之间,我们还有一步要做,那就是剔除已标记的数据。裁剪代码如下:

[En]

Between the training recognizers, we have one more step to do, which is to cut out the labeled data. The tailoring code is as follows:

import json
import os
import numpy as np
import cv2

def get_rotate_crop_image(img, points):
    '''
    img_height, img_width = img.shape[0:2]
    left = int(np.min(points[:, 0]))
    right = int(np.max(points[:, 0]))
    top = int(np.min(points[:, 1]))
    bottom = int(np.max(points[:, 1]))
    img_crop = img[top:bottom, left:right, :].copy()
    points[:, 0] = points[:, 0] - left
    points[:, 1] = points[:, 1] - top
    '''
    assert len(points) == 4, "shape of points must be 4*2"

    img_crop_width = int(
        max(
            np.linalg.norm(points[0] - points[1]),
            np.linalg.norm(points[2] - points[3])))

    img_crop_height = int(
        max(
            np.linalg.norm(points[0] - points[3]),
            np.linalg.norm(points[1] - points[2])))
    pts_std = np.float32([[0, 0], [img_crop_width, 0],
                          [img_crop_width, img_crop_height],
                          [0, img_crop_height]])

    M = cv2.getPerspectiveTransform(points, pts_std)

    dst_img = cv2.warpPerspective(
        img,
        M, (img_crop_width, img_crop_height),
        borderMode=cv2.BORDER_REPLICATE,
        flags=cv2.INTER_CUBIC)
    dst_img_height, dst_img_width = dst_img.shape[0:2]
    if dst_img_height * 1.0 / dst_img_width >= 1.5:
        dst_img = np.rot90(dst_img)
    return dst_img
def write_txt_img(src_path,label_txt):
    with open(src_path, 'r', encoding='utf-8') as f:
        for line in f.readlines():
            print(line)
            content = line.split('\t')
            print(content[0])
            imag_name = content[0].split('/')[1]
            image_path = './train_data/icdar2015/text_localization/' + content[0]
            img = cv2.imread(image_path)
            list_dict = json.loads(content[1])
            nsize = len(list_dict)
            print(nsize)
            num = 0
            for i in range(nsize):
                print(list_dict[i])
                lin = list_dict[i]
                info = lin['transcription']
                info=info.replace(" ","")
                points = lin['points']
                points = [list(x) for x in points]
                points = np.float32([list(map(float, item)) for item in points])
                imag_name=str(num)+"_"+imag_name
                save_path = './train_data/rec/train/' + imag_name
                dst_img = get_rotate_crop_image(img, points)
                cv2.imwrite(save_path, dst_img)
                label_txt.write('train/'+imag_name+'\t'+info+'\n')
                num=num+1
if not os.path.exists('train_data/rec/train/'):
    os.makedirs('train_data/rec/train/')
src_path = r"./train_data/icdar2015/text_localization/train_icdar2015_label.txt"
label_txt=r"./train_data/rec/rec_gt_train.txt"
src_test_path = r"./train_data/icdar2015/text_localization/test_icdar2015_label.txt"
label_test_txt=r"./train_data/rec/rec_gt_test.txt"
with open(label_txt, 'w') as w_label:
    write_txt_img(src_path,w_label)
with open(label_test_txt, 'w') as w_label:
    write_txt_img(src_test_path, w_label)

获取标注区域的图像主要用到了getPerspectiveTransform计算转换的矩阵和warpPerspective函数透视转换的组合。

获取到图像和标注的内容,生成文字识别通用数据集(SimpleDataSet)。

数据集的格式:

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

" 图像文件名                 图像标注信息 "

train/word_001.jpg   简单可依赖
train/word_002.jpg   用科技让复杂的世界更简单

生成数据集的路径如下:

PPv3-OCR自定义数据从训练到部署

2、修改配置文件

修改配置文件,在configs/rec/中,用rec_icdar15_train.yml 举例:

PPv3-OCR自定义数据从训练到部署

设置训练集的路径。

PPv3-OCR自定义数据从训练到部署

设置验证集的路径。

PPv3-OCR自定义数据从训练到部署

调整训练集和验证集的图片尺寸

PPv3-OCR自定义数据从训练到部署

设置训练和验证的batchsize。

PPv3-OCR自定义数据从训练到部署

设置字典,根据任务不同设置的字典也不同。
内置字典如下:

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个字符的英文字典

; 3、开启训练

完成上面的参数的设置,然后开始训练,命令如下:

python tools/train.py -c configs/rec/rec_icdar15_train.yml

PPv3-OCR自定义数据从训练到部署
更多的训练方式:

python3 tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy

python3 -m paddle.distributed.launch --gpus '0,1,2,3'  tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy

3.1、 断点训练

如果训练程序中断,如果希望加载训练中断的模型从而恢复训练,可以通过指定Global.checkpoints指定要加载的模型路径:

python tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.checkpoints=./your/trained/model

例如:

python tools/train.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_common_train_v2.0.yml -o Global.checkpoints=./output/rec_chinese_common_v2.0/best_accuracy

best_accuracy指的是红框中的三个模型。

PPv3-OCR自定义数据从训练到部署

注意Global.checkpoints的优先级高于 Global.pretrained_model的优先级,即同时指定两个参数时,优先加载 Global.checkpoints指定的模型,如果 Global.checkpoints指定的模型路径有误,会加载 Global.pretrained_model指定的模型。

3.2、 混合精度训练

如果您想进一步加快训练速度,可以使用自动混合精度训练, 以单机单卡为例,命令如下:

python3 tools/train.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.use_amp=True Global.scale_loss=1024.0 Global.use_dynamic_loss_scaling=True

3.3、 分布式训练

多机多卡训练时,通过 --ips 参数设置使用的机器IP地址,通过 --gpus 参数设置使用的GPU ID:

python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml \
     -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy

注意: 采用多机多卡训练时,需要替换上面命令中的ips值为您机器的地址,机器之间需要能够相互ping通。另外,训练时需要在多个机器上分别启动命令。查看机器ip地址的命令为 ifconfig

4 模型评估与预测

4.1、指标评估

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

# GPU 评估, Global.checkpoints 为待测权重
python -m paddle.distributed.launch --gpus '0' tools/eval.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.checkpoints={path/to/weights}/best_accuracy

4.2、测试识别效果

使用 PaddleOCR 训练好的模型,可以通过以下脚本进行快速预测。

默认预测图片存储在 infer_img 里,通过 -o Global.checkpoints 加载训练好的参数文件:

根据配置文件中设置的 save_model_dirsave_epoch_step 字段,会有以下几种参数被保存下来:

output/rec/
├── best_accuracy.pdopt
├── best_accuracy.pdparams
├── best_accuracy.states
├── config.yml
├── iter_epoch_3.pdopt
├── iter_epoch_3.pdparams
├── iter_epoch_3.states
├── latest.pdopt
├── latest.pdparams
├── latest.states
└── train.log

其中 best_accuracy. 是评估集上的最优模型;iter_epoch_3. 是以 save_epoch_step 为间隔保存下来的模型;latest.* 是最后一个epoch的模型。


python tools/infer_rec.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model={path/to/weights}/best_accuracy  Global.infer_img=doc/imgs_words/en/word_1.png

预测使用的配置文件必须与训练一致,如您通过 python tools/train.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml 完成了中文模型的训练, 您可以使用如下命令进行中文模型预测。

# 预测中文结果
python tools/infer_rec.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml -o Global.pretrained_model={path/to/weights}/best_accuracy Global.infer_img=doc/imgs_words/ch/word_1.jpg

4. 模型导出与预测

inference 模型( paddle.jit.save保存的模型) 一般是模型训练,把模型结构和模型参数保存在文件中的固化模型,多用于预测部署场景。 训练过程中保存的模型是checkpoints模型,保存的只有模型的参数,多用于恢复训练等。 与checkpoints模型相比,inference 模型会额外保存模型的结构信息,在预测部署、加速推理上性能优越,灵活方便,适合于实际系统集成。

识别模型转inference模型与检测的方式相同,如下:
官方的例子:

# -c 后面设置训练算法的yml配置文件
# -o 配置可选参数
# Global.pretrained_model 参数设置待转换的训练模型地址,不用添加文件后缀 .pdmodel,.pdopt或.pdparams。
# Global.save_inference_dir参数设置转换的模型将保存的地址。

python 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/

注意:如果您是在自己的数据集上训练的模型,并且调整了中文字符的字典文件,请注意修改配置文件中的 character_dict_path为自定义字典文件。
自己执行的命令:

python tools/export_model.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=./output/v3_en_mobile/best_accuracy  Global.save_inference_dir=./inference/en_PP-OCRv3_rec/

转换成功后,在目录下有三个文件:

inference/en_PP-OCRv3_rec/
    ├── inference.pdiparams         # 识别inference模型的参数文件
    ├── inference.pdiparams.info    # 识别inference模型的参数信息,可忽略
    └── inference.pdmodel           # 识别inference模型的program文件
  • 自定义模型推理 如果训练时修改了文本的字典,在使用inference模型预测时,需要通过 --rec_char_dict_path指定使用的字典路径
python3 tools/infer/predict_rec.py --image_dir="./doc/imgs_words_en/word_336.png" --rec_model_dir="./your inference model" --rec_image_shape="3, 48, 320" --rec_char_dict_path="your text dict path"

六、hubserving部署

hubserving服务部署目录下包括文本检测、文本方向分类,文本识别、文本检测+文本方向分类+文本识别3阶段串联,表格识别和PP-Structure六种服务包,请根据需求选择相应的服务包进行安装和启动。目录结构如下:

deploy/hubserving/
  └─  ocr_cls     文本方向分类模块服务包
  └─  ocr_det     文本检测模块服务包
  └─  ocr_rec     文本识别模块服务包
  └─  ocr_system  文本检测+文本方向分类+文本识别串联服务包
  └─  structure_table  表格识别服务包
  └─  structure_system  PP-Structure服务包

每个服务包下包含3个文件。以2阶段串联服务包为例,目录如下:

deploy/hubserving/ocr_system/
  └─  __init__.py    空文件,必选
  └─  config.json    配置文件,可选,使用配置启动服务时作为参数传入
  └─  module.py      主模块,必选,包含服务的完整逻辑
  └─  params.py      参数文件,必选,包含模型路径、前后处理参数等参数

1、准备环境


pip install paddlehub==2.1.0 --upgrade -i https://mirror.baidu.com/pypi/simple

2、安装服务模块

PaddleOCR提供5种服务模块,根据需要安装所需模块。

  • 在Linux环境下,安装示例如下:

hub install deploy/hubserving/ocr_det/

hub install deploy/hubserving/ocr_cls/

hub install deploy/hubserving/ocr_rec/

hub install deploy/hubserving/ocr_system/

hub install deploy/hubserving/structure_table/

hub install deploy/hubserving/structure_system/
  • 在Windows环境下(文件夹的分隔符为),安装示例如下:

hub install deploy\hubserving\ocr_det\

hub install deploy\hubserving\ocr_cls\

hub install deploy\hubserving\ocr_rec\

hub install deploy\hubserving\ocr_system\

hub install deploy\hubserving\structure_table\

hub install deploy\hubserving\structure_system\

我使用了检测+方向+识别,所以只需要安装

hub install deploy/hubserving/ocr_system/

注意:在PaddleOCR-release-2.5目录下执行

3、启动服务

3.1. 命令行命令启动(仅支持CPU,不推荐)

启动命令:

$ hub serving start --modules [Module1==Version1, Module2==Version2, ...] \
                    --port XXXX \
                    --use_multiprocess \
                    --workers \

参数:

参数用途–modules/-mPaddleHub Serving预安装模型,以多个Module==Version键值对的形式列出
_ 当不指定Version时,默认选择最新版本_

–port/-p服务端口,默认为8866–use_multiprocess是否启用并发方式,默认为单进程方式,推荐多核CPU机器使用此方式
_ Windows操作系统只支持单进程方式_

–workers在并发方式下指定的并发任务数,默认为 2*cpu_count-1

,其中 cpu_count

为CPU核数

如启动串联服务: hub serving start -m ocr_system

这样就完成了一个服务化API的部署,使用默认端口号8866。

3.2、 配置文件启动(支持CPU、GPU)

启动命令:
hub serving start -c config.json

其中, config.json格式如下:

{
    "modules_info": {
        "ocr_system": {
            "init_args": {
                "version": "1.0.0",
                "use_gpu": true
            },
            "predict_args": {
            }
        }
    },
    "port": 8868,
    "use_multiprocess": false,
    "workers": 2
}
  • init_args中的可配参数与 module.py中的 _initialize函数接口一致。其中, use_gputrue 时,表示使用GPU启动服务
  • predict_args中的可配参数与 module.py中的 predict函数接口一致。

注意:

  • 使用配置文件启动服务时,其他参数会被忽略。
  • 如果使用GPU预测(即, use_gpu置为 true),则需要在启动服务之前,设置CUDA_VISIBLE_DEVICES环境变量,如: export CUDA_VISIBLE_DEVICES=0,否则不用设置。
  • use_gpu 不可与 use_multiprocess 同时为 true

如,使用GPU 3号卡启动串联服务:

export CUDA_VISIBLE_DEVICES=3
hub serving start -c deploy/hubserving/ocr_system/config.json

4、 发送预测请求

配置好服务端,可使用以下命令发送预测请求,获取预测结果:

python tools/test_hubserving.py server_url image_path

test_hubserving.py代码:


import os
import sys
__dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(__dir__)
sys.path.append(os.path.abspath(os.path.join(__dir__, '..')))

from ppocr.utils.logging import get_logger
logger = get_logger()

import cv2
import numpy as np
import time
from PIL import Image
from ppocr.utils.utility import get_image_file_list
from tools.infer.utility import draw_ocr, draw_boxes, str2bool
from ppstructure.utility import draw_structure_result
from ppstructure.predict_system import to_excel

import requests
import json
import base64

def cv2_to_base64(image):
    return base64.b64encode(image).decode('utf8')

def draw_server_result(image_file, res):
    img = cv2.imread(image_file)
    image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    if len(res) == 0:
        return np.array(image)
    keys = res[0].keys()
    if 'text_region' not in keys:
        logger.info("draw function is invalid for ocr_rec!")
        return None
    elif 'text' not in keys:
        logger.info("draw text boxes only!")
        boxes = []
        for dno in range(len(res)):
            boxes.append(res[dno]['text_region'])
        boxes = np.array(boxes)
        draw_img = draw_boxes(image, boxes)
        return draw_img
    else:
        logger.info("draw boxes and texts!")
        boxes = []
        texts = []
        scores = []
        for dno in range(len(res)):
            boxes.append(res[dno]['text_region'])
            texts.append(res[dno]['text'])
            scores.append(res[dno]['confidence'])
        boxes = np.array(boxes)
        scores = np.array(scores)
        draw_img = draw_ocr(
            image, boxes, texts, scores, draw_txt=True, drop_score=0.5)
        return draw_img

def save_structure_res(res, save_folder, image_file):
    img = cv2.imread(image_file)
    excel_save_folder = os.path.join(save_folder, os.path.basename(image_file))
    os.makedirs(excel_save_folder, exist_ok=True)

    with open(
            os.path.join(excel_save_folder, 'res.txt'), 'w',
            encoding='utf8') as f:
        for region in res:
            if region['type'] == 'Table':
                excel_path = os.path.join(excel_save_folder,
                                          '{}.xlsx'.format(region['bbox']))
                to_excel(region['res'], excel_path)
            elif region['type'] == 'Figure':
                x1, y1, x2, y2 = region['bbox']
                print(region['bbox'])
                roi_img = img[y1:y2, x1:x2, :]
                img_path = os.path.join(excel_save_folder,
                                        '{}.jpg'.format(region['bbox']))
                cv2.imwrite(img_path, roi_img)
            else:
                for text_result in region['res']:
                    f.write('{}\n'.format(json.dumps(text_result)))

def main(args):
    image_file_list = get_image_file_list(args.image_dir)
    is_visualize = False
    headers = {"Content-type": "application/json"}
    cnt = 0
    total_time = 0
    for image_file in image_file_list:
        img = open(image_file, 'rb').read()
        if img is None:
            logger.info("error in loading image:{}".format(image_file))
            continue
        img_name = os.path.basename(image_file)

        starttime = time.time()
        data = {'images': [cv2_to_base64(img)]}
        r = requests.post(
            url=args.server_url, headers=headers, data=json.dumps(data))
        elapse = time.time() - starttime
        total_time += elapse
        logger.info("Predict time of %s: %.3fs" % (image_file, elapse))
        res = r.json()["results"][0]
        logger.info(res)

        if args.visualize:
            draw_img = None
            if 'structure_table' in args.server_url:
                to_excel(res['html'], './{}.xlsx'.format(img_name))
            elif 'structure_system' in args.server_url:
                save_structure_res(res['regions'], args.output, image_file)
            else:
                draw_img = draw_server_result(image_file, res)
            if draw_img is not None:
                if not os.path.exists(args.output):
                    os.makedirs(args.output)
                cv2.imwrite(
                    os.path.join(args.output, os.path.basename(image_file)),
                    draw_img[:, :, ::-1])
                logger.info("The visualized image saved in {}".format(
                    os.path.join(args.output, os.path.basename(image_file))))
        cnt += 1
        if cnt % 100 == 0:
            logger.info("{} processed".format(cnt))
    logger.info("avg time cost: {}".format(float(total_time) / cnt))

def parse_args():
    import argparse
    parser = argparse.ArgumentParser(description="args for hub serving")
    parser.add_argument("--server_url", type=str, required=True)
    parser.add_argument("--image_dir", type=str, required=True)
    parser.add_argument("--visualize", type=str2bool, default=False)
    parser.add_argument("--output", type=str, default='./hubserving_result')
    args = parser.parse_args()
    return args

if __name__ == '__main__':
    args = parse_args()
    main(args)

需要给脚本传递2个参数:

  • server_url:服务地址,格式为
    http://[ip_address]:[port]/predict/[module_name]
    例如,如果使用配置文件启动分类,检测、识别,检测+分类+识别3阶段,表格识别和PP-Structure服务,那么发送请求的url将分别是:
    http://127.0.0.1:8865/predict/ocr_det
    http://127.0.0.1:8866/predict/ocr_cls
    http://127.0.0.1:8867/predict/ocr_rec
    http://127.0.0.1:8868/predict/ocr_system
    http://127.0.0.1:8869/predict/structure_table
    http://127.0.0.1:8870/predict/structure_system
  • image_dir:测试图像路径,可以是单张图片路径,也可以是图像集合目录路径
  • visualize:是否可视化结果,默认为False
  • output:可视化结果保存路径,默认为 ./hubserving_result

访问示例:
python tools/test_hubserving.py --server_url=http://127.0.0.1:8868/predict/ocr_system --image_dir=./doc/imgs/ --visualize=false

运行结果:

PPv3-OCR自定义数据从训练到部署

5、 返回结果格式说明

返回结果为列表(list),列表中的每一项为词典(dict),词典一共可能包含3种字段,信息如下:

字段名称数据类型意义anglestr文本角度textstr文本内容confidencefloat文本识别置信度或文本角度分类置信度text_regionlist文本位置坐标htmlstr表格的html字符串regionslist版面分析+表格识别+OCR的结果,每一项为一个list,包含表示区域坐标的 bbox

,区域类型的 type

和区域结果的 res

三个字段

不同模块返回的字段不同,如,文本识别服务模块返回结果不含 text_region字段,具体信息如下:

字段名/模块名ocr_detocr_clsocr_recocr_systemstructure_tablestructure_systemangle✔✔text✔✔✔confidence✔✔✔text_region✔✔✔html✔✔regions✔✔

说明: 如果需要增加、删除、修改返回字段,可在相应模块的 module.py文件中进行修改,完整流程参考下一节自定义修改服务模块。

Original: https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/125087878
Author: AI浩
Title: PPv3-OCR自定义数据从训练到部署

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/31429/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

发表回复

登录后才能评论
免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部