跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
|注册
博客列表

目录

  1. 前言
  2. 准备工作
  3. 开始编译
  4. 封装自己的动态库
  5. 如何在自己的项目中使用
C++AI算法

C++调用PaddleOCR进行图像推理

本文记录了在 Windows 环境下编译 PaddleOCR 源码并封装为 C++ 动态库的过程。主要步骤包括准备 CMake、OpenCV 及 Paddle Inference 库,配置 CMake GUI 解决依赖问题,编写封装接口(init、run_det、run_rec),并在 MFC 项目中调用该库进行图像文字检测与识别。文中提供了关键代码示例及编译注意事项,解决了 C++ 集成 PaddleOCR 的常见问题。

CodeArtist发布于 2026/3/29更新于 2026/4/131 浏览

前言

本文记录了在 Windows 环境下编译 PaddleOCR 源码并封装为 C++ 动态库的过程。

准备工作

在对 paddleocr 进行编译前,需要提前准备需要的文件:

  1. CMake 4.2.1 版本较新即可
  2. OpenCv 库,官网下载最新的 Windows 安装包即可
  3. paddle_inference 库,同样的在百度飞桨官网上可以找到,也是 windows 预编译版,下载下来即可使用。地址 https://www.paddleocr.ai/latest/version3.x/pipeline_usage/OCR.html#1-ocr
  4. VS2019 及以上。

检测模型和识别模型,在 paddleocr GitHub 上可以下载到,分为服务端模型和移动端模型,如下:

开始编译

首先,在 PaddleOcr 源码 PaddleOCR-3.3.0\deploy\cpp_infer 目录下创建一个 build 目录,打开 Cmake 的 gui,将此目录下的 cmakelist 拖入其中。将编译完保存的目录改成 PaddleOCR-3.3.0\deploy\cpp_infer\build。然后点击 Configure,等执行失败后,设置 openCv 库,以及 paddle_inference 库的目录。

这里的设置千万不要错,否则后面生成的 vs 工程很多东西需要手动去改,烦的很。 设置完成后继续点击 Configure,中途可能会出现提示某些 CMake 版本较低,无需多言,根据提示手动找到对应文件的 CMakeList 将 CMake 版本标识改成 4.2.1,然后继续编译即可。 这里大致上就会显示成功,然后点击 Generate 生成对应的 VS 工程,生成的 VS 工程位于 build 目录下 ppocr.sln。打开此项目,将编译版本改为 Release X64,点击编译。中途会提示缺少某个头文件。下载 dirent.h,并拷贝到 Visual Studio 的 include 文件夹下,如 C:\Program Files (x86)\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include。(此头文件可以在 此地址 里面找到)。 继续点击编译,不出意外,此时会显示编译成功。 在 build\release 目录下,会生成一个 ppocr.exe 的 demo 程序。在命令行中可以验证是否编译成功。

PS F:\project\paddleOcr\deploy\cpp_infer\build\Release> ./ppocr ocr --input ./test10.jpg --save_path F:/project/paddleOcr/output --text_detection_model_dir F:/project/paddleOcr/models/PP-OCRv5_server_det --text_recognition_model_dir \F:/project/paddleOcr/models\PP-OCRv5_server_rec --use_doc_orientation_classify False --use_doc_unwarping False --use_textline_orientation False --device cpu 

相关参数很简单。执行,然后就会显示识别的内容。在此过程中如果提示缺少某某动态库,需要手动将其放置到 ppocr.exe 目录下。

封装自己的动态库

经过上面的操作,已经能够在 c++ 中进行推理识别了。但是此时是一个 ppocr.exe 的程序,用起来肯定是不方便的。我们需要将其封装成动态库,更方便我们使用。在 ppocr 项目下有个 cli.cc 文件。此程序的 main 函数就在这里面。 此时在 ppocr 项目中新建一个 myocr.h 和 myocr.cpp 文件。在里面自己封装识别的逻辑,代码如下:

#pragma once
#include<string>
#include<opencv2/opencv.hpp>
#define OCR_API __declspec(dllexport)
 ocr {
  Result { cv::Mat img; std::string text;  score; cv::Rect rect;};
;
;
;
}
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • C++ 二叉搜索树原理与高效实现
  • Linux 下 Vim 编辑器使用详解
  • Mac 系统 OpenClaw 本地 AI 执行引擎安装与配置指南
  • Java AWT 布局管理器详解
  • Visual C++ 运行库安装故障诊断与修复指南
  • Testsigma 开源自动化测试平台实战部署指南
  • AI 辅助 C++ 正确使用 override 关键字
  • LeetCode 206:反转链表

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown 转 HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online

namespace
struct
OCR_API
float
OCR_API bool init(const std::string &det_name,const std::string& det_dir,const std::string& rec_name,const std::string&rec_dir)
OCR_API std::vector<Result> run_det(cv::Mat& input)
OCR_API void run_rec(Result& result)
#include"paddle_ocr.h"
#include"src/api/pipelines/ocr.h"
static std::unique_ptr<TextDetPredictor> det_Predictor;
static std::unique_ptr<TextRecPredictor> rec_Predictor;
bool ocr::init(const std::string& det_name,const std::string& det_dir,const std::string& rec_name,const std::string& rec_dir){
try{ TextDetPredictorParams det_Params; det_Params.model_name = det_name; det_Params.model_dir = det_dir; det_Predictor = std::make_unique<TextDetPredictor>(det_Params);}
catch(std::exception &e){return false;}
try{ TextRecPredictorParams rec_Params; rec_Params.model_name = rec_name; rec_Params.model_dir = rec_dir; rec_Predictor = std::make_unique<TextRecPredictor>(rec_Params);}
catch(std::exception& e){return false;}
return true;}
std::vector<ocr::Result> ocr::run_det(cv::Mat& input){
std::vector<cv::Mat>inputs ={ input };
det_Predictor->ResetResult();
det_Predictor->Process(inputs);
std::vector<TextDetPredictorResult>det_results = det_Predictor->PredictorResult();
std::vector<ocr::Result>result;
for(int i =0; i < det_results.size(); i++){
TextDetPredictorResult det_result = det_results[i];
for(int j =0; j < det_result.dt_scores.size(); j++){
ocr::Result r; r.score = det_result.dt_scores[j];
std::vector<cv::Point2f>item = det_result.dt_polys[j];
r.rect = cv::Rect(item[0], item[2]);
r.img = det_result.input_image(r.rect).clone();
result.push_back(r);
}}
return result;}
void ocr::run_rec(ocr::Result& result){
std::vector<cv::Mat>inputs ={result.img};
rec_Predictor->ResetResult();
rec_Predictor->Process(inputs);
std::vector<TextRecPredictorResult> rec_results = rec_Predictor->PredictorResult();
result.text = rec_results[0].rec_text;
result.score = rec_results[0].rec_score;}

可以根据自己的需求,随意封装,此处只为一个例子,优化的地方还很多。 可以在 cil.cc 中验证自己的封装。将里面的代码注释掉,例如添加如下代码:

#include"./build/paddle_ocr.h"
#include<Windows.h>
int main(){
SetConsoleOutputCP(CP_UTF8);
bool ret = ocr::init("PP-OCRv5_server_det","F:/project/paddleOcr/models/PP-OCRv5_server_det","PP-OCRv5_server_rec","F:/project/paddleOcr/models/PP-OCRv5_server_rec");
std::cout << "ret is" << ret << std::endl;
cv::Mat img = cv::imread("F:/project/paddleOcr/deploy/cpp_infer/build/Release/test10.png", cv::IMREAD_COLOR_BGR);
std::vector<ocr::Result>results = ocr::run_det(img);
for(int i=0;i<results.size();i++){
ocr::Result item = results[i];
ocr::run_rec(item);
std::cout << item.score << "\t["<< item.rect.x <<","<< item.rect.y <<","<< item.rect.width <<","<< item.rect.height <<"]\t"<< item.text << std::endl;
}}

用来检验自己封装的正确性。 在成功之后,在 VS 工程的配置属性中,将输出文件拓展名改成.dll,配置类型改为动态库。然后重新编译生成此项目。

如何在自己的项目中使用

以上已经完成对 paddleocr 动态库的封装,下面介绍如何使用。 首先对动态库的头文件进行稍加修改。如下:

#pragma once
// ocr_api.h
#include<string>
#include<vector>
#include<opencv2/opencv.hpp>
// 注意:这里不能用 __declspec(dllexport),而是 dllimport!
#ifdef OCR_DLL
#define OCR_API __declspec(dllexport)
#else
#define OCR_API __declspec(dllimport)
#endif
namespace ocr {
struct OCR_API Result { cv::Mat img; std::string text; float score; cv::Rect rect;};
OCR_API bool init(const std::string& det_name,const std::string& det_dir,const std::string& rec_name,const std::string& rec_dir);
OCR_API std::vector<Result> run_det(cv::Mat& input);
OCR_API void run_rec(Result& result);
}

具体原因,不多赘述。 然后在需要使用的地方进行测试,例如在 MFC 项目中:

void CPaddocrTestDlg::OnBnClickedButton1(){
//server mobile
bool ret = ocr::init("PP-OCRv5_mobile_det","F:/project/paddleOcr/models/PP-OCRv5_mobile_det","PP-OCRv5_mobile_rec","F:/project/paddleOcr/models/PP-OCRv5_mobile_rec");
CString initMsg; initMsg.Format(_T("ocr::init() 返回:%s\\n"), ret ?_T("true"):_T("false"));
OutputDebugString(initMsg);
if(!ret){
OutputDebugString(_T("OCR 初始化失败!请检查模型路径和依赖 DLL。\\n"));
return;}
cv::Mat img = cv::imread("F:/project/paddleOcr/deploy/cpp_infer/build/Release/test10.png", cv::IMREAD_COLOR);
if(img.empty()){
OutputDebugString(_T("无法加载图像 test10.png!\\n"));
return;}
std::vector<ocr::Result> results = ocr::run_det(img);
CString detMsg;
detMsg.Format(_T("检测到 %d 个文本区域\\n"),(int)results.size());
OutputDebugString(detMsg);
for(auto& r : results){
ocr::run_rec(r);
CString text = CA2T(r.text.c_str(), CP_UTF8);
CString msg;
msg.Format(_T("文本:\"%s\", 置信度:%.2f, 位置:[%d,%d,%d,%d]\\n"), text, r.score, r.rect.x, r.rect.y, r.rect.width, r.rect.height );
OutputDebugString(msg);
}}

此处同样需要对库目录的链接加载配置正确。 注:此封装的 dll 只能在 release 状态下使用,对调试有一定的限制。

C++ 多态核心原理与虚函数表详解
  • C++23 常用特性详解
  • MuJoCo 足式机器人强化学习:URDF 转 XML 配置指南
  • 飞书 OpenClaw 机器人接入指南:基于长连接无需服务器
  • 西门子 S7-1200 PLC 与爱普生机器人 Modbus TCP 通讯配置
  • 解决 Python pip 报错 Preparing metadata (pyproject.toml) failed
  • 医疗 AI 场景下模型融合与集成策略深度解析
  • OpenClaw 新手指南:AI 机器人搭建与配置全攻略
  • 操作系统智能助手 OS Copilot 新功能测评
  • Matlab 一键生成 FPGA 存储器初始化文件:MIF、COE 及 TXT 格式详解
  • WebRTC 播放器横向测评:H5 低延迟直播方案选型
  • Eino 组件核心篇:Embedding 功能解析与使用指南