# ppocr **Repository Path**: wyonging/ppocr ## Basic Information - **Project Name**: ppocr - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-05 - **Last Updated**: 2026-09-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PaddleOCR C++ 推理部署 基于 **PaddlePaddle C++ Inference** 的 OCR / PP-StructureV3 推理部署项目,支持 PP-OCRv5 文本检测与识别、PP-StructureV3 文档版面分析、表格识别、公式识别。 > 参考文档:[PaddleOCR C++ 推理部署](https://www.paddleocr.ai/latest/version3.x/inference_deployment/local_inference/cpp/OCR.html) --- ## 目录 - [系统架构](#系统架构) - [环境准备](#环境准备) - [编译](#编译) - [运行](#运行) - [GPU 编译与运行](#gpu-编译与运行) - [CPU / GPU 性能对比](#cpu--gpu-性能对比) - [PP-StructureV3 管线流程](#pp-structurev3-管线流程) - [模块说明](#模块说明) --- ## 系统架构 ``` pp-ocr-cpp-infer/ ├── CMakeLists.txt # 根构建脚本:编译 ppocr_core 静态库 │ ├── app/ │ ├── CMakeLists.txt # 应用构建脚本:编译 ppocr 可执行文件 │ ├── cli.cc # 完整版 CLI,支持多种 pipeline 和模型 │ └── main.cpp # PP-StructureV3 交互式 Demo(循环等待图片输入) │ ├── src/ # OCR 核心代码 → 编译为 ppocr_core.a │ ├── api/ # 高层 API 封装 │ │ ├── models/ # 模型接口(文本检测、识别、分类、矫正等) │ │ └── pipelines/ # Pipeline 接口(OCR、文档预处理、StructureV3) │ ├── base/ # 抽象基类(Predictor、Pipeline、BatchSampler、CVResult) │ ├── common/ # 通用工具(Paddle 推理引擎、图像预处理、线程池、并行管线) │ ├── modules/ # 各模块实现 │ │ ├── text_detection/ # 文本检测(DB) │ │ ├── text_recognition/ # 文本识别(CRNN + CTC) │ │ ├── image_classification/ # 图像分类(Topk) │ │ ├── image_unwarping/ # 文档图像矫正(UVDoc) │ │ ├── layout_analysis/ # 版面分析(DETR) │ │ ├── table_recognition/ # 表格识别(SLANet) │ │ └── formula_recognition/ # 公式识别(UniMERNet) │ ├── pipelines/ # Pipeline 编排实现 │ │ ├── ocr/ # OCR 管线 │ │ ├── doc_preprocessor/ # 文档预处理管线 │ │ └── structurev3/ # PP-StructureV3 管线 │ └── utils/ # 工具函数(YAML 配置、日志、命令行参数、Paddle 选项) │ ├── third_party/ # 第三方依赖 │ ├── paddle_inference/ # PaddlePaddle 推理库(需自行下载) │ ├── abseil-cpp/ # Abseil C++ 库(自动下载) │ ├── clipper_ver6.4.2/ # 多边形裁剪库(自动下载) │ └── nlohmann/ # JSON 库(自动下载) │ ├── models/ # 推理模型文件(软链接) ├── configs/ # 管线配置文件(YAML) ├── fonts/ # 可视化字体文件 ├── tools/ # 构建脚本 │ ├── build.sh # 一键编译脚本 │ └── build_opencv.sh # OpenCV 编译脚本 │ └── general_ocr_002.png # 测试图片 ``` ### 编译依赖关系 ``` third_party (abseil / clipper / nlohmann) ↓ ppocr_core.a (src/*.cc) ↓ ┌──────────────────┐ ↓ ↓ ppocr ppocr_demo (cli.cc) (main.cpp) 完整版 CLI StructureV3 交互式 Demo ``` ### 架构分层 项目采用严格的分层架构,共 **6 层**: | 层 | 目录 | 职责 | |---|------|------| | 🚪 入口层 | `app/` | CLI 入口和交互式 Demo | | 📦 API 封装 | `src/api/` | 面向用户的公共接口 | | 🔗 管线编排 | `src/pipelines/` | 组合多个模块完成复杂任务 | | 🧩 模型模块 | `src/modules/` | 单个神经网络模型推理(7 个模块) | | 🏗️ 抽象基类 | `src/base/` | Predictor / Pipeline / BatchSampler / CVResult | | 🛠️ 基础设施 | `src/common/` + `src/utils/` | 推理引擎 / 预处理 / 线程池 / 配置 / 日志 | --- ## 环境准备 ### 1. OpenCV ```bash ./tools/build_opencv.sh ``` `third_party/opencv4` 是编译好的文件。如果系统已安装 OpenCV 4.x,也可直接使用系统库: ```bash sudo apt install libopencv-dev ``` ### 2. PaddlePaddle 推理库 下载 [paddle_inference](https://www.paddleocr.ai/latest/version3.x/inference_deployment/local_inference/cpp/OCR.html) 并解压到: ``` third_party/paddle_inference/ ``` ### 3. 模型文件 将模型放在 `models/` 目录,支持以下模型: | 模型 | 用途 | 架构 | 配置特点 | |------|------|------|---------| | `PP-OCRv5_server_det` / `PP-OCRv5_mobile_det` | 文本检测 | DB | 960 resize_long | | `PP-OCRv5_server_rec` / `PP-OCRv5_mobile_rec` | 文本识别 | CRNN+CTC | 标准 CTC 解码 | | `PP-DocLayout_plus-L` / `PP-DocBlockLayout` | 版面分析 | DETR | 800×800, 多类别 | | `SLANet_plus` / `SLANeXt` | 表格识别 | Encoder-Decoder | 488×488, HTML 输出 | | `PP-FormulaNet_plus-L` | 公式识别 | UniMERNet | 768×768, LaTeX 输出 | | `PP-LCNet_x1_0_doc_ori` | 文档方向分类 | 分类 | 分类模型 | | `PP-LCNet_x0_25_textline_ori` | 文本行方向 | 分类 | 分类模型 | | `UVDoc` | 文档矫正 | 矫正 | 文档展平 | 可使用软链接指向模型目录: ```bash ln -sf /path/to/models/PP-DocLayout_plus-L models/ ln -sf /path/to/models/SLANet_plus models/ ln -sf /path/to/models/PP-FormulaNet_plus-L models/ ln -sf /path/to/models/PP-OCRv5_server_det models/ ln -sf /path/to/models/PP-OCRv5_server_rec models/ ``` ### 4. 字体文件(可选,可视化用) 将 `.ttf` 字体放到 `fonts/` 目录。 --- ## 编译 ### 方式一:一键编译 ```bash # 修改 tools/build.sh 中的路径后执行 ./tools/build.sh ``` ### 方式二:分步编译 **第一步:配置** ```bash mkdir -p build && cd build cmake .. \ -DPADDLE_LIB=../third_party/paddle_inference \ -DWITH_MKL=ON \ -DWITH_GPU=OFF \ -DWITH_STATIC_LIB=OFF \ -DWITH_TENSORRT=OFF \ -DOPENCV_DIR=../third_party/opencv4 \ -DOpenCV_DIR=../third_party/opencv4 \ -DOpenCV_STATIC=ON \ -DCMAKE_PREFIX_PATH=../third_party/opencv \ -DUSE_FREETYPE=ON \ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ``` > **提示:** 使用系统 OpenCV 时,可将 `-DOPENCV_DIR` 指向 `/usr`。 **第二步:编译库 + 可执行文件** ```bash # 编译 ppocr_core 静态库(src + third_party) make ppocr_core -j$(nproc) # 编译 ppocr 可执行文件 make ppocr -j$(nproc) ``` ### 日常开发 ```bash cd build # 只改了 cli.cc → 只编译,不动 src/ make ppocr -j$(nproc) # 改了 main.cpp → 编译 ppocr_demo make ppocr_demo -j$(nproc) # 改了 src/ 或 third_party → 重编库 + 可执行文件 make ppocr_core -j$(nproc) && make ppocr -j$(nproc) ``` ### 方式三:GPU 编译 使用 GPU 版 Paddle Inference 库(Paddle 3.0.0 / CUDA 11.8 / cuDNN 8.9 / TensorRT 8.6)编译 GPU 版本: ```bash ./tools/build_gpu.sh ``` 内部核心参数: ```bash LIB_DIR=../third_party/paddle_inference_gpu # GPU 版推理库 BUILD_DIR=build_gpu # 独立构建目录,不覆盖 CPU 构建 CUDA_LIB_DIR=/path/to/cudatoolkit-11.8/lib # 提供 libcudart.so.11.0 等运行时库 CUDNN_LIB_DIR=/path/to/cuda/cudnn8.9/lib # 提供 libcudnn.so.8 + split 库 cmake .. \ -DPADDLE_LIB=${LIB_DIR} \ -DWITH_GPU=ON \ ... ``` - 示例机器上 `CUDA_LIB_DIR=/root/anaconda3/pkgs/cudatoolkit-11.8.0-h6a678d5_0/lib`、`CUDNN_LIB_DIR=/usr/local/cuda-12.4/targets/x86_64-linux/lib` - `WITH_GPU=ON` 时默认设备自动变为 `gpu:0`(`src/utils/pp_option.h` 中 `DEVICE` 编译期常量) - 构建产物:CPU 版 `build/app/ppocr`、GPU 版 `build_gpu/app/ppocr` --- ## 运行 ### 设置环境变量 ```bash LIB_DIR=third_party/paddle_inference BUILTIN_INSTALL=${LIB_DIR}/third_party/install export LD_LIBRARY_PATH=\ ${BUILTIN_INSTALL}/openvino/intel64:\ ${BUILTIN_INSTALL}/onednn/lib:\ ${BUILTIN_INSTALL}/mklml/lib:\ ${LIB_DIR}/paddle/lib:\ ${BUILTIN_INSTALL}/tbb/lib:\ $LD_LIBRARY_PATH ``` ### OCR 管线 ```bash ./build/ppocr ocr \ --input ./general_ocr_002.png \ --save_path ./output/ \ --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 \ --vis_font_dir ./fonts/simhei.ttf ``` ### PP-StructureV3 管线 版面分析 + OCR + 表格 + 公式识别: ```bash ./build/ppocr structurev3 \ --input ./general_ocr_002.png \ --save_path ./output/ \ --use_doc_orientation_classify False \ --use_doc_unwarping False \ --use_textline_orientation False \ --device cpu ``` 模型路径通过 `src/configs/structurev3.yaml` 配置,也可通过命令行参数覆盖: ```bash ./build/ppocr structurev3 \ --input ./document.png \ --layout_model_dir models/PP-DocLayout_plus-L \ --table_model_dir models/SLANet_plus \ --formula_model_dir models/PP-FormulaNet_plus-L \ --text_detection_model_dir models/PP-OCRv5_server_det \ --text_recognition_model_dir models/PP-OCRv5_server_rec \ --device cpu ``` ### PP-StructureV3 交互式 Demo 适合快速测试和多轮调试,启动后进入交互式提示符,每次输入图片路径即可推理: ```bash # 编译 cd build make ppocr_demo -j$(nproc) cd .. # 设置环境变量(同 CLI 方式) export LD_LIBRARY_PATH=third_party/paddle_inference/third_party/install/openvino/intel64:third_party/paddle_inference/third_party/install/onednn/lib:third_party/paddle_inference/third_party/install/mklml/lib:third_party/paddle_inference/paddle/lib:third_party/paddle_inference/third_party/install/tbb/lib:$LD_LIBRARY_PATH # 运行 ./build/app/ppocr_demo ``` 运行示例: ``` ===== PP-StructureV3 Interactive Demo ===== Enter image path to process, or 'q'/'quit'/'exit' to quit. > ./general_ocr_002.png [info] Inference time: 31954.71 ms (./general_ocr_002.png) [info] Results saved to ./output/ > ./document2.png [info] Inference time: 28500.23 ms (./document2.png) [info] Results saved to ./output/ > q [info] Exiting. ``` - 每次推理自动输出**耗时**(毫秒) - 结果(JSON + 可视化图片)保存到 `./output/` ### 单独模型推理 ```bash # 文本检测 ./build/ppocr text_detection --input test.png --text_detection_model_dir models/det_infer # 文本识别 ./build/ppocr text_recognition --input test.png --text_recognition_model_dir models/rec_infer # 文档方向分类 ./build/ppocr doc_img_orientation_classification --input test.png --doc_orientation_classify_model_dir models/doc_ori_infer # 文档图像矫正 ./build/ppocr text_image_unwarping --input test.png --doc_unwarping_model_dir models/unwarp_infer ``` ``` 2. 模型路径可覆盖(CLI 优先,空则回退硬编码默认) - --layout_model_dir / --table_model_dir / --formula_model_dir / --text_detection_model_dir / --text_recognition_model_dir / --vis_font_dir 3. 功能开关透传(上一轮的全部优化开关) - --merge_text_det、--use_table_recognition、--use_formula_recognition、--use_layout_analysis - 文档预处理开关用 is_default 判定:用户显式传 --use_doc_orientation_classify=true 才启用,不传则保持原 demo 的关闭行为(避免 gflags 默认 "true" 意外启用重模型) 4. 引擎参数透传 - --device、--precision、--enable_mkldnn、--mkldnn_cache_capacity、--cpu_threads、--thread_num 使用示例 # 最快路径:关闭表格/公式/文档预处理,合并文本检测 ./build/app/ppocr_demo \ --use_table_recognition=false --use_formula_recognition=false \ --use_doc_orientation_classify=false --use_doc_unwarping=false \ --use_textline_orientation=false --merge_text_det=true \ --cpu_threads=4 --mkldnn_cache_capacity=200 # 回退到旧的逐区域文本检测 ./build/app/ppocr_demo --merge_text_det=false ``` --- ## GPU 编译与运行 ### GPU 编译 ```bash ./tools/build_gpu.sh ``` 脚本核心差异(见 [`tools/build_gpu.sh`](tools/build_gpu.sh)): ```bash LIB_DIR=../third_party/paddle_inference_gpu # GPU 版推理库 BUILD_DIR=build_gpu # 独立构建目录,不覆盖 CPU 构建 CUDA_LIB_DIR=/path/to/cudatoolkit-11.8/lib # 提供 libcudart.so.11.0 CUDNN_LIB_DIR=/path/to/cudnn8.9/lib # 提供 libcudnn.so.8 + split 库 cmake .. \ -DPADDLE_LIB=${LIB_DIR} \ -DWITH_GPU=ON \ ... ``` 本机实测路径: - `CUDA_LIB_DIR=/root/anaconda3/pkgs/cudatoolkit-11.8.0-h6a678d5_0/lib`(cudatoolkit-11.8 提供 `libcudart.so.11.0`、`libcublas.so.11`、`libcublasLt.so.11`) - `CUDNN_LIB_DIR=/usr/local/cuda-12.4/targets/x86_64-linux/lib`(cuDNN 8.9.1 全套 stub + split 库,与 GPU 库要求匹配) > `WITH_GPU=ON` 时默认设备自动变为 `gpu:0`(`src/utils/pp_option.h` 中 `DEVICE` 编译期常量)。 > 本仓库 GPU 包 `third_party/paddle_inference_gpu` 版本:**Paddle 3.0.0 / CUDA 11.8 / cuDNN 8.9 / TensorRT 8.6**。 ### GPU 运行环境变量 GPU 版二进制需要额外的运行时 CUDA 依赖(`libcudart.so.11.0` 等由 GPU 库 `DT_NEEDED` 指定,另有部分依赖运行时 dlopen): ```bash LIB_DIR=third_party/paddle_inference_gpu export LD_LIBRARY_PATH=\ ${LIB_DIR}/third_party/install/onednn/lib:\ ${LIB_DIR}/third_party/install/mklml/lib:\ ${LIB_DIR}/paddle/lib:\ /root/anaconda3/pkgs/cudatoolkit-11.8.0-h6a678d5_0/lib:\ /usr/local/cuda-12.4/targets/x86_64-linux/lib:\ $LD_LIBRARY_PATH ``` ### GPU 运行命令 ```bash # StructureV3 全管线(默认 gpu:0) ./build_gpu/app/ppocr structurev3 \ --input ./pp_structure_v3_demo.png \ --save_path ./output_gpu/ \ --vis_font_dir ./fonts/simhei.ttf \ --use_doc_orientation_classify False \ --use_doc_unwarping False \ --use_textline_orientation False # 可选:fp16 混合精度推理(--precision fp16 → paddle_fp16,需 GPU 支持) ./build_gpu/app/ppocr structurev3 --input ./pp_structure_v3_demo.png \ --save_path ./output_gpu/ --precision fp16 --device gpu:0 ``` CPU 版用同一命令,仅替换二进制与 `--device cpu`: ```bash ./build/app/ppocr structurev3 --input ./pp_structure_v3_demo.png \ --save_path ./output_cpu/ --device cpu --vis_font_dir ./fonts/simhei.ttf \ --use_doc_orientation_classify False --use_doc_unwarping False \ --use_textline_orientation False ``` --- ## CPU / GPU 性能对比 以下数据为本仓库在 **同一测试环境** 下实测结果,可复现。 ### 测试环境 | 项目 | 配置 | |------|------| | CPU | 8 线程,MKLDNN(`--cpu_threads` 默认 8) | | GPU | NVIDIA GeForce RTX 2060 6GB,驱动 550.144.03 | | 推理库 | Paddle Inference 3.0.0(CPU 版 / GPU 版 CUDA 11.8 + cuDNN 8.9) | | 测试输入 | `pp_structure_v3_demo.png`(新闻长文页,含 31 个版面区域) | | 管线 | structurev3(关闭文档预处理/文本行方向) | ### 端到端耗时 | 指标 | CPU | GPU 冷启动 | GPU 热启动 | |------|-----|-----------|-----------| | 墙钟时间 | **28.73s** | 13.54s | **8.38s** | | CPU user+sys | 188.9s + 14.2s | 8.0s + 3.5s | — | | 峰值内存 RSS | 2.99 GB | 1.68 GB | — | | 模型加载+初始化 | ~3s | ~4-5s(含首次 CUDA 上下文创建) | ~4s | ### 各模型推理耗时(`predictor_->Run()` 计时,不含预处理) | 模型 | 调用次数 | CPU 单次平均 | CPU 合计 | GPU 合计(热) | |------|---------|------------|---------|--------------| | PP-DocLayout_plus-L(版面分析) | 1 | 1046.5ms | 1.05s | 0.46s | | PP-OCRv5_server_det(文本检测) | 1 | 3012.1ms | 3.01s | 0.37s | | PP-OCRv5_server_rec(文本识别) | 23 | 734.8ms | 16.90s | 0.17s | | **推理合计** | | | **≈ 21.0s** | **≈ 1.0s** | > 测试图为纯文章页,**没有表格和公式区域**,因此 `SLANet_plus`、`PP-FormulaNet_plus-L` 未触发推理(模型仍会加载)。 ### 结论 - **纯推理加速比 ≈ 21×**(CPU 21.0s → GPU ≈1.0s) - 识别阶段(rec,CPU 上占推理 80%)GPU 加速 **≈ 99×**(16.90s → 0.17s) - 端到端加速 **≈ 3.4×**(28.7s → 8.4s);GPU 模型加载/初始化占 4-5s,占比随图片张数增加而摊薄 - 输出一致性:CPU / GPU 两次运行 JSON 完全一致(31 区域 / 25 文本区 / 136 文本行 / 2382 字) ### 性能统计说明 - 以上「各模型推理耗时」由 `src/common/static_infer.{h,cc}` 中的**计时插桩**统计:在 `predictor_->Run()` 前后用 `steady_clock` 计时累加,模型析构时打印一行汇总(例:`[timing] model=PP-OCRv5_server_rec runs=23 total=16901.0ms avg=734.8ms`) - 端到端耗时通过 `/usr/bin/time -v` 统计(wall / user / sys / RSS) --- ## PP-StructureV3 管线流程 ``` ┌─────────────┐ │ Input Image │ └──────┬──────┘ ↓ ┌──────────────────────┐ │ [DocPreprocessor] │ ← 可选:方向矫正 + 展平 └──────┬───────────────┘ ↓ ┌──────────────────────────────────────────────┐ │ [LayoutAnalysis] → 检测区域 │ │ (text / table / figure / formula / seal) │ └──────┬───────────────────────────────────────┘ ↓ 按区域标签分派 │ ├── "text" / "text_inline" → 裁剪 → 文本检测 → 文本识别 ├── "table" → 裁剪 → 表格识别 → HTML ├── "formula" → 裁剪 → 公式识别 → LaTeX ├── "figure" → 可选 图像分类 └── "seal" → 裁剪 → 文本检测 → 文本识别 │ ↓ ┌──────────────────┐ │ 结构化 JSON 输出 │ └──────────────────┘ ``` ### 输出结果 在 `output/` 目录下生成: - 可视化结果图片: `*_ocr_res_img.png` - 结构化 JSON 结果: `*_res.json` JSON 输出示例: ```json { "input_path": "./document.png", "model_settings": { "use_layout_analysis": true, "use_table_recognition": true, "use_formula_recognition": true }, "layout_regions": [ { "label": "text", "class_id": 2, "score": 0.95, "polygon": [[10, 20], [100, 20], [100, 50], [10, 50]], "ocr_results": [ { "rec_texts": ["识别文本"], "rec_scores": [0.99], "rec_polys": [...] } ] }, { "label": "table", "class_id": 8, "score": 0.92, "polygon": [[...], ...], "table_results": [ { "html_structure": "
| ... |