# 通用 OCR 产线 C++ 部署 - Linux - [1. 环境准备](#1) - [1.1 编译 OpenCV 库](#11-编译-opencv-库) - [1.2 编译 Paddle Inference](#12-编译-paddle-inference) - [2. 开始运行](#2-开始运行) - [2.1 编译预测 demo](#21-编译预测-demo) - [2.2 准备模型](#22-准备模型) - [2.3 运行预测 demo](#23-运行预测-demo) - [2.4 C++ API 集成](#24-c-api-集成) - [3. 额外功能](#3-额外功能) - [3.1 可视化文本识别结果](#31-可视化文本识别结果) - [4. FAQ](#4-faq) 本章节介绍通用 OCR 产线 C++ 部署方法。通用 OCR 产线由以下5个模块组成: 1. 文档图像方向分类模块(可选) 2. 文本图像矫正模块 (可选) 3. 文本行方向分类模块(可选) 4. 文本检测模块 5. 文本识别模块 下面将介绍如何在 Linux (CPU/GPU) 环境下配置 C++ 环境并完成通用 OCR 产线部署。 - 备注 - Windows 环境具体编译方法请参考 [Windows 编译教程](./OCR_windows.md),在编译完成后,后续运行 demo 的指令与 Linux 一致。 ## 1. 环境准备 - 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 源码: ```bash 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 ``` 2. 配置并编译 OpenCV 库: - a. 在 `tools/build_opencv.sh` 脚本中,将 `root_path` 设置为 opencv-4.7.0 源码的绝对路径。 - b. 设置 `install_path`,如默认的 `${root_path}/opencv4`。`install_path` 在后续编译预测 demo 时,将作为 OpenCV 库的路径使用。 - c. 配置完成后,运行以下命令进行 OpenCV 的编译: ```bash sh tools/build_opencv.sh ``` ### 1.2 编译 Paddle Inference 可以选择直接下载预编译包或者手动编译源码。 #### 1.2.1 直接下载预编译包(推荐) [Paddle Inference 官网](https://www.paddlepaddle.org.cn/inference/v3.0/guides/install/download_lib.html) 上提供了 Linux 预测库,可以在官网查看并选择合适的预编译包。 下载之后解压: ```shell tar -xvf paddle_inference.tgz ``` 最终会在当前的文件夹中生成 `paddle_inference/` 的子文件夹。 #### 1.2.2 源码编译预测库 可以选择通过源码自行编译预测库,源码编译可灵活配置各类功能和依赖,以适应不同的硬件和软件环境。详细步骤请参考 [Linux 下源码编译](https://www.paddlepaddle.org.cn/inference/v3.0/guides/install/compile/source_compile_under_Linux.html)。 ## 2. 开始运行 ### 2.1 编译预测 demo 在编译预测demo前,请确保您已经按照 1.1 和 1.2 节编译好 OpenCV 库和 Paddle Inference 预测库。 修改 tools/build.sh 中的配置后,执行以下命令进行编译: ```shell 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 |
| 模型 | 模型下载链接 | 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 的服务器端模型,推理精度高,可以部署在多种不同的服务器上 |
| 参数 | 参数说明 | 参数类型 | 默认值 |
|---|---|---|---|
input |
本地待预测图片,必填。仅支持jpg,png, jpeg,bmp格式的图像。
|
str |
|
save_path |
指定推理结果文件保存的路径,该路径下会保存推理结果的 json 文件和预测结果图片。 | str |
./output |
| 参数 | 参数说明 | 参数类型 | 默认值 |
|---|---|---|---|
device |
用于推理的设备。支持指定具体卡号:
-DWITH_GPU=ON,则会优先使用本地的 GPU 0号设备,否则,将使用 CPU 设备。
|
str |
|
precision |
计算精度,如 fp32、fp16。 |
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 |
文本检测的边长度限制类型。支持 min 和 max,min 表示保证图像最短边不小于 det_limit_side_len,max 表示保证图像最长边不大于 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.2 调用示例-单模块调用
=== "文档图像方向分类"
```bash
./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 预测结果文件和预测结果图片):
```bash
{
"res": {
"input_path": {./general_ocr_002.png},
"class_ids": {0},
"scores": {0.926328},
"label_names": {0},
}
```
=== "文档图像矫正"
```bash
./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 预测结果文件和预测结果图片):
```bash
{
"res": {
"input_path": {./general_ocr_002.png},
"doctr_img": {...}
}
```
=== "文本行方向分类"
```bash
./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 预测结果文件和预测结果图片):
```bash
{
"res": {
"input_path": {./general_ocr_002.png},
"class_ids": {0},
"scores": {0.719926},
"label_names": {0_degree},
}
```
=== "文本检测"
```bash
./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 预测结果文件和预测结果图片):
```bash
{
"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, ...,
]
}
}
```
=== "文本识别"
```bash
./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 预测结果文件和预测结果图片):
```bash
{
"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`。
```c++
#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 为例,源码下载命令如下:
```bash
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依赖库
```bash
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}/opencv4`。`install_path` 在后续编译预测 demo 时,将作为 OpenCV 库的路径使用。
- d. 配置完成后,运行以下命令进行 OpenCV 的编译:
```bash
sh tools/build_opencv.sh
```
- e. 在 `tools/build.sh` 设置 `-DUSE_FREETYPE=ON` 开启文字渲染功能,设置 `--vis_font_dir your_ttf_path` 提供相应 ttf 字体文件路径。运行以下命令进行预测 demo 的编译:
```bash
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 编码。