C++ 推理系统为在生产环境中部署 PaddleOCR 模型提供了高性能的部署能力。与 Python 实现相比,此实现性能更优,并支持 PP-OCRv5、PP-StructureV3 以及文档理解任务等全方位的 OCR 流程。
C++ 推理是 PaddleOCR 生态系统中一项关键的部署选项,介于开发接口和生产服务器部署之间。
C++ 推理系统采用模块化架构,以 ocr() 和 structure() 函数为两个主要入口点,位于 deploy/cpp_infer/src/main.cpp83-200 该系统通过专用的 C++ 类支持所有三个主要的 PaddleOCR 流程。
C++ 推理系统组件
来源: deploy/cpp_infer/src/main.cpp83-200 deploy/cpp_infer/include/paddleocr.h21-50 deploy/cpp_infer/include/paddlestructure.h21-44
C++ 实现支持所有主要的 PaddleOCR 流程
| 管道 | C++ 类 | 支持的操作 |
|---|---|---|
| PP-OCRv5 | PPOCR | 文本检测、识别、分类 |
| PP-StructureV3 | PaddleStructure | 布局分析、表格识别 |
| 文档理解 | PaddleStructure + PPOCR | 组合结构+OCR分析 |
该系统提供多种优化策略
FLAGS_cpu_threads 实现多线程,通过 FLAGS_enable_mkldnn 实现 MKLDNN 加速FLAGS_use_gpu 实现 CUDA 加速,通过 FLAGS_use_tensorrt 实现 TensorRT 优化FLAGS_precision 支持 FP32、FP16、INT8 精度模式来源: deploy/cpp_infer/src/ocr_det.cpp47-78 deploy/cpp_infer/src/ocr_rec.cpp163-193
要使用 C++ 推理功能,您需要以下组件
PaddleOCR 的 C++ 推理依赖 OpenCV 进行图像处理。您需要从源代码编译 OpenCV
来源: deploy/cpp_infer/readme.md30-76
您可以通过以下两种方式获取 Paddle 推理库
直接下载:从 Paddle 推理库官网 下载预编译版本
从源码编译:获取最新功能,您可以从源码编译库
编译好的库将位于 build/paddle_inference_install_dir/。
来源: deploy/cpp_infer/readme.md90-153
构建之前,您需要准备 OCR 模型。您可以
模型应按以下结构组织
inference/
|-- det_db
| |--inference.pdiparams
| |--inference.pdmodel
|-- rec_rcnn
| |--inference.pdiparams
| |--inference.pdmodel
|-- cls
| |--inference.pdiparams
| |--inference.pdmodel
|-- table
| |--inference.pdiparams
| |--inference.pdmodel
|-- layout
| |--inference.pdiparams
| |--inference.pdmodel
来源: deploy/cpp_infer/readme.md169-190
要编译 PaddleOCR C++ 推理程序
tools/build.sh 脚本,设置 OpenCV 和 Paddle 推理库的路径这将在 build 目录中生成一个名为 ppocr 的可执行文件。
来源: deploy/cpp_infer/readme.md194-214
C++ 推理系统由几个关键组件组成,它们协同工作以执行 OCR 任务。
来源: deploy/cpp_infer/include/paddleocr.h deploy/cpp_infer/src/paddleocr.cpp deploy/cpp_infer/include/paddlestructure.h deploy/cpp_infer/src/paddlestructure.cpp deploy/cpp_infer/include/ocr_det.h deploy/cpp_infer/src/ocr_det.cpp deploy/cpp_infer/include/ocr_rec.h deploy/cpp_infer/src/ocr_rec.cpp deploy/cpp_infer/include/ocr_cls.h deploy/cpp_infer/src/ocr_cls.cpp
PPOCR 类实现模式
来源: deploy/cpp_infer/include/paddleocr.h21-50 deploy/cpp_infer/src/paddleocr.cpp25-29 deploy/cpp_infer/include/ocr_det.h30-84 deploy/cpp_infer/include/ocr_rec.h30-99 deploy/cpp_infer/include/ocr_cls.h30-73
PPOCR::ocr() 中的 OCR 流程执行
来源: deploy/cpp_infer/src/paddleocr.cpp91-117 deploy/cpp_infer/src/ocr_det.cpp92-175 deploy/cpp_infer/src/ocr_rec.cpp24-135 deploy/cpp_infer/src/ocr_cls.cpp23-106
在 deploy/cpp_infer/src/main.cpp178 中,可执行文件 ppocr 使用 google::ParseCommandLineFlags() 进行参数解析。主执行逻辑根据 FLAGS_type 参数路由到 ocr() 或 structure() 函数。
执行入口
来源: deploy/cpp_infer/src/main.cpp176-200 deploy/cpp_infer/src/main.cpp83-119 deploy/cpp_infer/src/main.cpp121-174
参数系统定义在 deploy/cpp_infer/include/args.h,控制模型加载、硬件利用和处理行为。
| 参数 | 类型 | 默认 | 描述 |
|---|---|---|---|
FLAGS_use_gpu | bool | false | 通过 paddle_infer::Config::EnableUseGpu() 启用 GPU 加速 |
FLAGS_gpu_id | int | 0 | 用于 CUDA 操作的 GPU 设备索引 |
FLAGS_gpu_mem | int | 4000 | GPU 内存分配(MB) |
FLAGS_cpu_threads | int | 10 | 通过 SetCpuMathLibraryNumThreads() 配置 CPU 线程数 |
FLAGS_enable_mkldnn | bool | true | 通过 config.EnableMKLDNN() 启用 MKLDNN 加速 |
FLAGS_use_tensorrt | bool | false | 通过 config.EnableTensorRtEngine() 启用 TensorRT 优化 |
FLAGS_precision | 字符串 | "fp32" | 精度模式:"fp32"、"fp16" 或 "int8" |
| 参数 | 类型 | 默认 | 代码中的使用 |
|---|---|---|---|
FLAGS_det | bool | true | 在 PPOCR() 构造函数中控制 DBDetector 的实例化 |
FLAGS_rec | bool | true | 在 PPOCR() 构造函数中控制 CRNNRecognizer 的实例化 |
FLAGS_cls | bool | false | 在 PPOCR() 构造函数中控制 Classifier 的实例化 |
FLAGS_table | bool | false | 在 PaddleStructure() 中控制 StructureTableRecognizer |
FLAGS_layout | bool | false | 在 PaddleStructure() 中控制 StructureLayoutRecognizer |
| 参数 | 用途 | 验证 |
|---|---|---|
FLAGS_det_model_dir | 传递给 DBDetector() 构造函数 | 在 deploy/cpp_infer/src/main.cpp26-33 中的 check_params() 中进行检查 |
FLAGS_rec_model_dir | 传递给 CRNNRecognizer() 构造函数 | 在 deploy/cpp_infer/src/main.cpp34-47 中的 check_params() 中进行检查 |
FLAGS_cls_model_dir | 传递给 Classifier() 构造函数 | 在 deploy/cpp_infer/src/main.cpp48-55 中的 check_params() 中进行检查 |
FLAGS_table_model_dir | 传递给 StructureTableRecognizer() | 在 deploy/cpp_infer/src/main.cpp56-66 中的 check_params() 中进行检查 |
来源: deploy/cpp_infer/src/main.cpp25-81 deploy/cpp_infer/src/paddleocr.cpp31-54 deploy/cpp_infer/src/paddlestructure.cpp29-44
让我们看看主要组件的实现细节
DBDetector 类通过以下关键组件实现文本检测(使用 DB 算法)
模型配置与加载
DBDetector::Run() 中的处理流程
ResizeImgType0::Run() 和 Normalize::Run() 操作predictor_->Run()(带输入张量重塑)DBPostProcessor::BoxesFromBitmap() 和 FilterTagDetRes()检测处理流程
来源: deploy/cpp_infer/src/ocr_det.cpp23-90 deploy/cpp_infer/src/ocr_det.cpp92-175
CRNNRecognizer 类通过批量处理和 CTC 解码来处理文本识别
CRNNRecognizer::Run() 中的批量处理
Utility::argsort(width_list) 按宽度比例对图像进行排序rec_batch_num_ 的批量大小进行处理CrnnResizeImg::Run() 进行动态宽度调整CTC 解码逻辑
来源: deploy/cpp_infer/src/ocr_rec.cpp24-135 deploy/cpp_infer/src/ocr_rec.cpp105-128
PaddleStructure 类继承自 PPOCR,用于文档结构分析
PaddleStructure::structure() 中的结构分析流程
StructureLayoutRecognizer::Run() 识别区域StructureTableRecognizer::Run() 处理表格区域PPOCR::ocr() 应用于文本区域表格 HTML 重构
来源: deploy/cpp_infer/src/paddlestructure.cpp48-79 deploy/cpp_infer/src/paddlestructure.cpp137-195
C++ 推理实现提供了多种优化选项以提高性能
cpu_math_library_num_threads 控制线程数enable_mkldnn=true 启用 MKLDNN 加速使用 GPU 加速
use_gpu=truegpu_id 设置为所需的 GPU 索引gpu_mem 控制内存使用为了在 NVIDIA GPU 上获得最佳性能,提供了 TensorRT 集成
use_tensorrt=trueprecision 参数选择精度(fp32、fp16 或 int8)来源: deploy/cpp_infer/src/ocr_det.cpp23-68 deploy/cpp_infer/src/ocr_rec.cpp137-166 deploy/cpp_infer/src/ocr_cls.cpp108-151
如果遇到错误:“您正在使用已编译 TensorRT 的 Paddle,但未找到 TensorRT 动态库”
对于遇到构建错误的 Windows 用户
来源: deploy/cpp_infer/readme.md452-456 deploy/cpp_infer/docs/windows_vs2019_build.md140-141
PaddleOCR 的 C++ 推理实现为在生产环境中部署 OCR 模型提供了一个高性能的解决方案。通过遵循本文档中的设置、编译和使用说明,您可以有效地利用 C++ 推理功能来满足您的 OCR 应用需求。
模块化设计允许部署的灵活性,从简单的文本识别到复杂文档结构分析。各种优化选项使您能够根据硬件能力和需求来微调性能。