跳转至

通用 OCR 产线 C++ 部署 - Linux

本章节介绍通用 OCR 产线 C++ 部署方法。通用 OCR 产线由以下5个模块组成:

  1. 文档图像方向分类模块(可选)
  2. 文本图像矫正模块 (可选)
  3. 文本行方向分类模块(可选)
  4. 文本检测模块
  5. 文本识别模块

下面将介绍如何在 Linux (CPU/GPU) 环境下配置 C++ 环境并完成通用 OCR 产线部署。

  • 备注
    • Windows 环境具体编译方法请参考 Windows 编译教程,在编译完成后,后续运行 demo 的指令与 Linux 一致。

1. 环境准备

  • 本章节编译运行时用到的源代码位于 PaddleOCR/deploy/cpp_infer 目录下。

  • Linux 环境。

    • gcc 8.2(编译使用 Paddle Inference GPU 版本时,gcc>=11.2)
    • cmake 3.18

1.1 编译 OpenCV 库

目前仅支持 OpenCV 4.x 版本。下面以 OpenCV 4.7.0 为例。

  1. 执行如下命令下载 OpenCV 源码:
cd deploy/cpp_infer
wget https://paddle-model-ecology.bj.bcebos.com/paddlex/cpp/libs/opencv-4.7.0.tgz
tar -xf opencv-4.7.0.tgz
  1. 配置并编译 OpenCV 库:
  2. a. 在 tools/build_opencv.sh 脚本中,将 root_path 设置为 opencv-4.7.0 源码的绝对路径。
  3. b. 设置 install_path,如默认的 ${root_path}/opencv4install_path 在后续编译预测 demo 时,将作为 OpenCV 库的路径使用。
  4. c. 配置完成后,运行以下命令进行 OpenCV 的编译:

    sh tools/build_opencv.sh
    

1.2 编译 Paddle Inference

可以选择直接下载预编译包或者手动编译源码。

1.2.1 直接下载预编译包(推荐)

Paddle Inference 官网 上提供了 Linux 预测库,可以在官网查看并选择合适的预编译包。

下载之后解压:

tar -xvf paddle_inference.tgz

最终会在当前的文件夹中生成 paddle_inference/ 的子文件夹。

1.2.2 源码编译预测库

可以选择通过源码自行编译预测库,源码编译可灵活配置各类功能和依赖,以适应不同的硬件和软件环境。详细步骤请参考 Linux 下源码编译

2. 开始运行

2.1 编译预测 demo

在编译预测demo前,请确保您已经按照 1.1 和 1.2 节编译好 OpenCV 库和 Paddle Inference 预测库。

修改 tools/build.sh 中的配置后,执行以下命令进行编译:

sh tools/build.sh

相关配置参数详细介绍如下:

参数 说明 默认值
OPENCV_DIR OpenCV编译安装的路径(如上述编译 OpenCV 时的 install_path ,必填。
LIB_DIR 下载的 Paddle Inference 的预编译包或手动编译生成的Paddle Inference库路径(如 build/paddle_inference_install_dir 文件夹),必填。
CUDA_LIB_DIR CUDA库文件路径,通常为/usr/local/cuda/lib64。当Paddle Inference库为GPU版本且设置 -DWITH_GPU=ON 时需要设置该参数。
CUDNN_LIB_DIR cuDNN 库文件路径,通常为 /usr/lib/x86_64-linux-gnu/ 。当 Paddle Inference 库为 GPU 版本且设置 -DWITH_GPU=ON 时需要设置该参数。
WITH_GPU 当设置为 ON 时可以进行 GPU 版本 demo 的编译,要求 Paddle Inference 库为 GPU 版本。 OFF

注意:以上路径需要填绝对路径。

2.2 准备模型

可以直接下载 PaddleOCR 提供的推理模型:

文档图像方向分类模块(可选):
模型模型下载链接 Top-1 Acc(%) 模型存储大小(MB) 介绍
PP-LCNet_x1_0_doc_ori 推理模型 99.06 7 基于 PP-LCNet_x1_0 的文档图像分类模型,含有四个类别,即0度,90度,180度,270度
文本图像矫正模块(可选):
模型模型下载链接 CER 模型存储大小(MB) 介绍
UVDoc 推理模型 0.179 30.3 高精度文本图像矫正模型
文本行方向分类模块(可选):
模型 模型下载链接 Top-1 Acc(%) 模型存储大小(MB) 介绍
PP-LCNet_x1_0_textline_ori (默认) 推理模型 99.42 6.5 基于 PP-LCNet_x1_0 的文本行分类模型,含有两个类别,即0度,180度
PP-LCNet_x0_25_textline_ori 推理模型 98.85 0.96 基于 PP-LCNet_x0_25 的文本行分类模型,含有两个类别,即0度,180度
文本检测模块:
模型模型下载链接 检测Hmean(%) 模型存储大小(MB) 介绍
PP-OCRv5_server_det (默认) 推理模型 83.8 84.3 PP-OCRv5 的服务端文本检测模型,精度更高,适合在性能较好的服务器上部署
PP-OCRv5_mobile_det 推理模型 79.0 4.7 PP-OCRv5 的移动端文本检测模型,效率更高,适合在端侧设备部署
PP-OCRv4_server_det 推理模型 69.2 109 PP-OCRv4 的服务端文本检测模型,精度更高,适合在性能较好的服务器上部署
PP-OCRv4_mobile_det 推理模型 63.8 4.7 PP-OCRv4 的移动端文本检测模型,效率更高,适合在端侧设备部署
文本识别模块:
模型模型下载链接 识别 Avg Accuracy(%) 模型存储大小(MB) 介绍
PP-OCRv5_server_rec (默认) 推理模型 86.38 81 PP-OCRv5_rec 是新一代文本识别模型。该模型致力于以单一模型高效、精准地支持简体中文、繁体中文、英文、日文四种主要语言,以及手写、竖版、拼音、生僻字等复杂文本场景的识别。在保持识别效果的同时,兼顾推理速度和模型鲁棒性,为各种场景下的文档理解提供高效、精准的技术支撑。
PP-OCRv5_mobile_rec 推理模型 81.29 16
PP-OCRv4_server_rec_doc 推理模型 86.58 182 PP-OCRv4_server_rec_doc 是在 PP-OCRv4_server_rec 的基础上,在更多中文文档数据和PP-OCR训练数据的混合数据训练而成,增加了部分繁体字、日文、特殊字符的识别能力,可支持识别的字符为1.5万+,除文档相关的文字识别能力提升外,也同时提升了通用文字的识别能力
PP-OCRv4_mobile_rec 推理模型 78.74 10.5 PP-OCRv4 的轻量级识别模型,推理效率高,可以部署在包含端侧设备的多种硬件设备中
PP-OCRv4_server_rec 推理模型 85.19 173 PP-OCRv4 的服务器端模型,推理精度高,可以部署在多种不同的服务器上

也可以参考各模块的模型导出章节,如文本检测模块-模型导出,将训练好的模型导出为推理模型。

模型的目录结构一般如下所示:

PP-OCRv5_mobile_det
|--inference.pdiparams
|--inference.json
|--inference.yml

2.3 运行预测 demo

在本地使用通用 OCR 产线 C++前,请先成功编译预测 demo。编译后,可通过命令行体验或调用 api 进行二次开发并重新编译生成应用程序。

请注意,如果在执行过程中遇到程序失去响应、程序异常退出、内存资源耗尽、推理速度极慢等问题,请尝试参考文档调整配置,例如关闭不需要使用的功能或使用更轻量的模型。

本 demo 支持系统串联调用,也支持单个模块的调用,运行以下代码前,请您下载示例图片到本地:

运行方式:

./build/ppocr <pipeline_or_module> [--param1] [--param2] [...]

常用参数如下:

  • 输入输出相关
参数 参数说明 参数类型 默认值
input 本地待预测图片,必填。仅支持jpgpng, jpeg,bmp格式的图像。 str
save_path 指定推理结果文件保存的路径,该路径下会保存推理结果的 json 文件和预测结果图片。 str ./output
点击展开查看更多参数的详细说明 - 通用参数
参数 参数说明 参数类型 默认值
device 用于推理的设备。支持指定具体卡号:
  • CPU:如 cpu 表示使用 CPU 进行推理;
  • GPU:如 gpu:0 表示使用第 1 块 GPU 进行推理;
如果不设置,将默认使用产线初始化的该参数值,初始化时,如果编译时添加-DWITH_GPU=ON,则会优先使用本地的 GPU 0号设备,否则,将使用 CPU 设备。
str
precision 计算精度,如 fp32fp16 str fp32
enable_mkldnn 是否启用 MKL-DNN 加速推理。如果 MKL-DNN 不可用或模型不支持通过 MKL-DNN 加速,即使设置了此标志,也不会使用加速。 bool true
mkldnn_cache_capacity MKL-DNN 缓存容量。 int 10
cpu_threads PaddleInference CPU 加速库线程数量 int 8
paddlex_config PaddleX产线配置文件路径。 str
- 模块开关
参数 参数说明 参数类型 默认值
use_doc_orientation_classify 是否加载并使用文档方向分类模块。如果不设置,将使用产线初始化的该参数值,默认初始化为true bool true
use_doc_unwarping 是否加载并使用文本图像矫正模块。如果不设置,将使用产线初始化的该参数值,默认初始化为true bool true
use_textline_orientation 是否加载并使用文本行方向模块。如果不设置,将使用产线初始化的该参数值,默认初始化为true bool true
- 检测模型相关
参数 参数说明 参数类型 默认值
text_detection_model_name 文本检测模型的名称。如果不设置,将会使用产线默认模型。当传入文本检测模型路径的模型名称与产线默认文本识别模型名称配置不一致时,需指定传入模型的名称。 str PP-OCRv5_server_det
text_detection_model_dir 文本检测模型的目录路径,必填。 str
text_det_limit_side_len 文本检测的图像边长限制。 大于 0 的任意整数。如果不设置,将使用产线初始化的该参数值,默认初始化为 64 int 64
text_det_limit_type 文本检测的边长度限制类型。支持 minmaxmin 表示保证图像最短边不小于 det_limit_side_lenmax 表示保证图像最长边不大于 limit_side_len。如果不设置,将使用产线初始化的该参数值,默认初始化为 min str min
text_det_thresh 文本检测像素阈值,输出的概率图中,得分大于该阈值的像素点才会被认为是文字像素点。 大于0的任意浮点数。如果不设置,将使用产线初始化的该参数值。 float 0.3
text_det_box_thresh 文本检测框阈值,检测结果边框内,所有像素点的平均得分大于该阈值时,该结果会被认为是文字区域。 大于 0 的任意浮点数。如果不设置,将使用产线初始化的该参数值(默认为 0.6)。 float 0.6
text_det_unclip_ratio 文本检测扩张系数,使用该方法对文字区域进行扩张,该值越大,扩张的面积越大。大于 0 的任意浮点数。如果不设置,将使用产线初始化的该参数值。 float 1.5
text_det_input_shape 文本检测的输入形状,您可以设置3个值代表C,H,W。 std::vector
- 方向分类器相关
参数 参数说明 参数类型 默认值
doc_orientation_classify_model_name 文档方向分类模型的名称。如果不设置,将会使用产线默认模型。当传入文档方向分类模型与产线默认模型不一致时,需指定传入模型的名称。 str PP-LCNet_x1_0_doc_ori
doc_orientation_classify_model_dir 文档方向分类模型的目录路径。当设置use_doc_orientation_classify = false时,可不添加。 str
textline_orientation_model_name 文本行方向分类模型的名称。如果不设置,将会使用产线默认模型。当传入文本行方向分类模型与产线默认模型不一致时,需指定传入模型的名称。 str PP-LCNet_x1_0_textline_ori
textline_orientation_model_dir 文本行方向分类模型的目录路径。当设置use_textline_orientation = false时,可不添加。 str
textline_orientation_batch_size 文本行方向模型的batch size。如果不设置,将会使用产线默认模型。 int 6
- 文字识别模型相关
参数 参数说明 参数类型 默认值
text_recognition_model_name 文本识别模型的名称。如果不设置,将会使用产线默认模型。当传入文本识别模型路径的模型名称与产线默认文本识别模型名称配置不一致时,需指定传入模型的名称。 str PP-OCRv5_server_rec
text_recognition_model_dir 文本识别模型的目录路径,必填。 str
text_recognition_batch_size 文本识别模型的batch size。如果不设置,将会使用产线默认值。 int 6
text_rec_score_thresh 文本识别阈值,得分大于该阈值的文本结果会被保留。大于0的任意浮点数。 float 0.0
text_rec_input_shape 文本识别的输入形状,您可以设置3个值代表C,H,W。 std::vector

2.3.1 调用示例-系统串联调用

本节提供了系统串联调用的调用示例,请参考 2.1 节准备好模型,假设模型的目录结构如下所示:

models
|--PP-LCNet_x1_0_doc_ori_infer
|--UVDoc_infer
|--PP-LCNet_x1_0_textline_ori_infer
|--PP-OCRv5_server_det_infer
|--PP-OCRv5_server_rec_infer
./build/ppocr ocr --input ./general_ocr_002.png --save_path ./output/  \
--doc_orientation_classify_model_dir models/PP-LCNet_x1_0_doc_ori_infer \
--doc_unwarping_model_dir models/UVDoc_infer \
--textline_orientation_model_dir models/PP-LCNet_x1_0_textline_ori_infer \
--text_detection_model_dir models/PP-OCRv5_server_det_infer \
--text_recognition_model_dir models/PP-OCRv5_server_rec_infer \
--device cpu

输出示例(若指定了 save_path,则会在该路径下生成标准的 json 预测结果文件和预测结果图片):

{
   "input_path": "./general_ocr_002.png",
   "doc_preprocessor_res": {
       "model_settings": {"use_doc_unwarping": true, "use_doc_orientation_classify": true},
       "angle": 0
    },
   ...,
   "dt_polys": [[[132, 6], [355, 6], [355, 64], [132, 64]],
    [[424, 9], [689, 9], [689, 59], [424, 59]],
     ...,
    [[664, 8], [867, 4], [868, 55], [665, 60]],
    [[31, 99], [173, 99], [173, 126], [31, 126]]],
     ...,
   "rec_texts": ["登机牌", "BOARDING", "GPASS", ..., ],
   ...,
}        
./build/ppocr ocr --input ./general_ocr_002.png --save_path ./output/  \
--doc_orientation_classify_model_dir models/PP-LCNet_x1_0_doc_ori_infer \
--doc_unwarping_model_dir models/UVDoc_infer \
--textline_orientation_model_dir models/PP-LCNet_x1_0_textline_ori_infer \
--text_detection_model_dir models/PP-OCRv5_server_det_infer \
--text_recognition_model_dir models/PP-OCRv5_server_rec_infer \
--use_doc_orientation_classify False \
--use_doc_unwarping False \
--device cpu

输出示例(若指定了 save_path,则会在该路径下生成标准的 json 预测结果文件和预测结果图片):

{
   "input_path": "./general_ocr_002.png",
   ...,
    "dt_polys": [[[0, 1], [334, 1], [334, 34], [0, 34]],
    [[151, 21], [357, 16], [358, 72], [152, 76]],
     ...,
    [[675, 97], [740, 97], [740, 121], [675, 121]],
    [[751, 97], [836, 94], [837, 115], [752, 119]],
     ...,
   "rec_texts": ["净小8866-", "登机牌", "BOARDING", "GPASS", ..., ],
   ...,
}    
./build/ppocr ocr --input ./general_ocr_002.png --save_path ./output/  \
--doc_orientation_classify_model_dir models/PP-LCNet_x1_0_doc_ori_infer \
--doc_unwarping_model_dir models/UVDoc_infer \
--textline_orientation_model_dir models/PP-LCNet_x1_0_textline_ori_infer \
--text_detection_model_dir models/PP-OCRv5_server_det_infer \
--text_recognition_model_dir models/PP-OCRv5_server_rec_infer \
--use_doc_orientation_classify False \
--use_doc_unwarping False \
--use_textline_orientation False \
--device cpu

输出示例(若指定了 save_path,则会在该路径下生成标准的 json 预测结果文件和预测结果图片):

{
   "input_path": "./general_ocr_002.png",
   ...,
   "dt_polys": [[[0, 1], [334, 1], [334, 34], [0, 34]],
    [[151, 21], [357, 16], [358, 72], [152, 76]],
     ...,
    [[61, 109], [194, 106], [194, 132], [61, 135]],
    [[80, 138], [219, 136], [219, 162], [80, 164]],
     ...,
   "rec_texts": ["www.997788.com中国收藏热线","登机牌", "BOARDING", "GPASS", ..., ],
   ...,
}    

以上示例代码会生成如下文本检测结果图:

若需要查看文本识别结果图,请参考后文 可视化文本识别结果 小节。

2.3.2 调用示例-单模块调用

./build/ppocr doc_img_orientation_classification --input ./general_ocr_002.png --save_path ./output/  \
--doc_orientation_classify_model_dir models/PP-LCNet_x1_0_doc_ori_infer \
--device cpu 

输出示例(若指定了 save_path,则会在该路径下生成标准的 json 预测结果文件和预测结果图片):

{
"res": {
    "input_path": {./general_ocr_002.png},
    "class_ids": {0},
    "scores": {0.926328},
    "label_names": {0},
}
./build/ppocr text_image_unwarping --input ./general_ocr_002.png --save_path ./output/  \
--doc_unwarping_model_dir models/UVDoc_infer \
--device cpu 

输出示例(若指定了 save_path,则会在该路径下生成标准的 json 预测结果文件和预测结果图片):

{
"res": {
    "input_path": {./general_ocr_002.png},
    "doctr_img": {...}
}    
./build/ppocr textline_orientation_classification --input ./general_ocr_002.png --save_path ./output/  \
--textline_orientation_model_dir models/PP-LCNet_x1_0_textline_ori_infer \
--device cpu 

输出示例(若指定了 save_path,则会在该路径下生成标准的 json 预测结果文件和预测结果图片):

{
"res": {
    "input_path": {./general_ocr_002.png},
    "class_ids": {0},
    "scores": {0.719926},
    "label_names": {0_degree},
}
./build/ppocr text_detection --input ./general_ocr_002.png --save_path ./output/  \
--text_detection_model_dir models/PP-OCRv5_server_det_infer \
--device cpu 

输出示例(若指定了 save_path,则会在该路径下生成标准的 json 预测结果文件和预测结果图片):

{
"res": {
    "input_path": {./general_ocr_002.png    },
    "dt_polys": [
        [[98, 456], [834, 441], [834, 466], [98, 480]],
        [[344, 347], [662, 343], [662, 366], [344, 371]],
        [[66, 341], [165, 337], [167, 363], [67, 367]],
        ...,
        [[0, 1], [331, 0], [332, 32], [0, 34]],
    ]},
    "dt_scores": [
        0.812284, 0.8082, 0.848293, ..., 
    ]
  }
}
./build/ppocr text_recognition --input ./general_ocr_rec_001.png --save_path ./output/  \
--text_recognition_model_dir models/PP-OCRv5_server_rec_infer \ 
--device cpu 

输出示例(若指定了 save_path,则会在该路径下生成标准的 json 预测结果文件和预测结果图片):

{
"res": {
    "input_path": {./general_ocr_rec_001.png },
    "rec_text": {绿洲仕格维花园公寓 }
    "rec_score": {0.982409 }
}

2.4 C++ API 集成

命令行方式是为了快速体验查看效果,一般来说,在项目中,往往需要通过代码集成,您可以通过几行代码即可完成产线的快速推理,推理代码如下:

由于通用 OCR 产线配置参数较多,故采用结构体传参进行实例化,结构体命名规则为 pipeline_class_name + Params,如通用 OCR 产线对应的类名为 PaddleOCR ,结构体为 PaddleOCRParams

#include "src/api/pipelines/ocr.h"


int main(){
    PaddleOCRParams params;
    params.doc_orientation_classify_model_dir = "models/PP-LCNet_x1_0_doc_ori_infer"; // 文档方向分类模型路径。
    params.doc_unwarping_model_dir = "models/UVDoc_infer"; // 文本图像矫正模型路径。
    params.textline_orientation_model_dir = "models/PP-LCNet_x1_0_textline_ori_infer"; // 文本行方向分类模型路径。
    params.text_detection_model_dir = "models/PP-OCRv5_server_det_infer"; // 文本检测模型路径
    params.text_recognition_model_dir = "models/PP-OCRv5_server_rec_infer"; // 文本识别模型路径

    // params.device = "gpu"; // 推理时使用GPU。请确保编译时添加 -DWITH_GPU=ON 选项,否则使用CPU。
    // params.use_doc_orientation_classify = false;  // 不使用文档方向分类模型。
    // params.use_doc_unwarping = false; // 不使用文本图像矫正模型。
    // params.use_textline_orientation = false; // 不使用文本行方向分类模型。
    // params.params.text_recognition_model_name = "PP-OCRv5_server_rec" // 使用 PP-OCRv5_server_rec 模型进行识别。
    // params.vis_font_dir = "your_vis_font_dir"; // 当编译时添加 -DUSE_FREETYPE=ON 选项,必须提供相应 ttf 字体文件路径。

    auto infer = PaddleOCR(params);
    auto outputs = infer.Predict("./general_ocr_002.png");
    for (auto& output : outputs) {
      output->Print();
      output->SaveToImg("./output/");
      output->SaveToJson("./output/");
    }
}

3. 额外功能

3.1 可视化文本识别结果

我们需要 FreeType 去完成字体的渲染,所以需要自己编译包含 FreeType 的 OpenCV,注意仅支持 OpenCV 4.x 版本。 FreeType 属于 opencv_contrib 模块,需要下载 OpenvCV 和 opencv_contrib 源码,注意版本一致。以下以 opencv4.7.0 为例,源码下载命令如下:

wget https://paddle-model-ecology.bj.bcebos.com/paddlex/cpp/libs/opencv-4.7.0.tgz
wget https://paddle-model-ecology.bj.bcebos.com/paddlex/cpp/libs/opencv_contrib-4.7.0.tgz
tar -xf opencv-4.7.0.tgz
tar -xf opencv_contrib-4.7.0.tgz

安装FreeType依赖库

sudo apt-get update
sudo apt-get install libfreetype6-dev libharfbuzz-dev

编译包含 FreeType 模块的 OpenCV 的步骤如下:

  • a. 在 tools/build_opencv.sh 脚本中增加如下三个选项:
    • -DOPENCV_EXTRA_MODULES_PATH=your_opencv_contrib-4.7.0/modules/
    • -DBUILD_opencv_freetype=ON
    • -DWITH_FREETYPE=ON
  • b. 在 tools/build_opencv.sh 脚本中,将 root_path 设置为 opencv-4.7.0 源码的绝对路径。
  • c. 在 tools/build_opencv.sh 脚本中,设置 install_path,如默认的 ${root_path}/opencv4install_path 在后续编译预测 demo 时,将作为 OpenCV 库的路径使用。
  • d. 配置完成后,运行以下命令进行 OpenCV 的编译:

    sh tools/build_opencv.sh
    
  • e. 在 tools/build.sh 设置 -DUSE_FREETYPE=ON 开启文字渲染功能,设置 --vis_font_dir your_ttf_path 提供相应 ttf 字体文件路径。运行以下命令进行预测 demo 的编译:

    sh tools/build.sh
    

编译并运行预测 demo 可以得到如下可视化文本识别结果:

4. FAQ

  1. 如果遇到 Model name mismatch, please input the correct model dir. model dir is xxx, but model name is xxx 的报错,说明指定的模型名称和传入模型不匹配。比如文本识别模型指定名称是 PP-OCRv5_server_rec,但传入模型是 PP-OCRv5_mobile_rec。 解决:需要调整模型名称或传入的模型。例如上述例子,可以使用 --text_recognition_model_name PP-OCRv5_mobile_rec 指定和传入模型匹配的模型名称。

  2. 在 Windows 的控制台中输出出现乱码,原因可能是 Windows 控制台的字符编码是 GBK,请设置为 UTF-8 编码。