Window C++ PaddleOCR v5部署 dll封装 接口扩展

📅 发布时间:2026/7/11 19:09:12 👁️ 浏览次数:
Window C++ PaddleOCR v5部署 dll封装 接口扩展
目录一、CPU版本1. 编译2. 运行命令行运行VS运行2. 接口扩展,支持直接传入cv::Mat3. dll封装和调用二、GPU版本一、CPU版本1. 编译参考教程:通用 OCR 产线 C++ 本地部署 - Windows - PaddleOCR 文档vs生成过程中会报错。添加#include unordered_map,重新生成即可。编译过程中需要注意版本,PaddleOCR和Paddle Inference版本要一致。2. 运行命令行运行2.x版本不支持OCRv5,命令如下:ppocr.exe system --det_model_dir=det模型所在路径 --rec_model_dir=rec模型所在路径 --image_dir=图片位置3.0版本支持OCRv5,命令如下:ppocr.exe ocr --text_detection_model_dir=C:\Desktop\PP-OCRv5_server_det --text_recognition_model_dir=C:\Desktop\PP-OCRv5_server_rec --input=D:\test_img.jpg其它具体命令参考args.cc即可。其中OCR模型下载地址:通用 OCR 产线 C++ 本地部署 - Linux - PaddleOCR 文档VS运行程序入口在cli.cc,可以修改cli.cc,也可以注释掉cli.cc中的main函数,新建自己的main函数,如下#include "src/api/pipelines/ocr.h" int main() { PaddleOCRParams params; params.use_doc_orientation_classify = false; // 文本检测模型路径 params.use_doc_unwarping = false; // 文本检测模型路径 params.use_textline_orientation = false; // 文本检测模型路径 params.text_detection_model_dir = "C:/Users/11141/Desktop/PP-OCRv5_server_det"; // 文本检测模型路径 params.text_recognition_model_dir = "C:/Users/11141/Desktop/PP-OCRv5_server_rec"; // 文本识别模型路径 // 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.text_detection_model_name = "PP-OCRv5_server_det"; // 使用 PP-OCRv5_server_det 模型进行检测。 // 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("D:/test_img.jpg"); for (auto output : outputs) { output-Print(); output-SaveToImg("./output/"); output-SaveToJson("./output/"); } }2. 接口扩展,支持直接传入cv::Mat现有接口只能传递图片路径,为了集成在软件中调用,传递内存中的图像,增加一个可传cv::Mat的接口。首先理清楚PaddleOCR的代码逻辑:PaddleOCR::Predict(string) → OCRPipeline::Predict(vectorstring) → _OCRPipeline::Predict(vectorstring) → ImageBatchSampler::SampleFromVector(strings) → BaseBatchSampler → 加载图片为 cv::Mat - 检测+识别关键发现: ImageBatchSampler 已经有 SampleFromMatVector(const std::vectorcv::Mat) 方法 (image_batch_sampler.h), BaseBatchSampler::Apply 也有 cv::Mat 的模板特化 (base_batch_sampler.h)。但从 BasePipeline 到 PaddleOCR 都只暴露了 Predict(string) 接口。方案: 沿着调用链逐层添加 Predict(const std::vectorcv::Mat) 重载,最终在 API.cpp 暴露 DLL 接口。1. 修改 BasePipeline- 添加 cv::Mat虚方法base_pipeline.h增加以下接口std::vectorstd::unique_ptrBaseCVResult Predict(const cv::Mat input) { std::vectorcv::Mat inputs = {input}; return Predict(inputs); } virtual std::vectorstd::unique_ptrBaseCVResult Predict(const std::vectorcv::Mat input) { return {}; }pipeline.h的class _OCRPipeline增加以下接口std::vectorstd::unique_ptrBaseCVResult Predict(const std::vectorcv::Mat input) override;pipeline.h的classOCRPipeline构造函数改成OCRPipeline(const OCRPipelineParams params) : AutoParallelSimpleInferencePipeline(params), thread_num_(params.thread_num), params_(params)并增加以下接口public: std::vectorstd::unique_ptrBaseCVResult Predict(const std::vectorcv::Mat input) override; private: OCRPipelineParams params_;pipeline.cc中的class _OCRPipeline增加以下函数实现std::vectorstd::unique_ptrBaseCVResult _OCRPipeline::Predict(const std::vectorcv::Mat input) { auto model_settings = GetModelSettings(); auto batches = batch_sampler_ptr_-Apply(input); if (!batches.ok()) { INFOE("pipeline get sample fail : %s", batches.status().ToString().c_str()); exit(-1); } int index = 0; std::vectorcv::Mat origin_image = {}; std::vectorstd::unique_ptrBaseCVResult base_results = {}; pipeline_result_vec_.clear(); for (int i = 0; i batches.value().size(); i++) { origin_image.reserve(batches.value()[i].size()); for (const auto mat : batches.value()[i]) { origin_image.push_back(mat.clone()); } std::vectorDocPreprocessorPipelineResult doc_preprocessors_pipeline_results = {}; if (use_doc_preprocessor_) { INFOW("Doc preprocessor is not supported with cv::Mat input, skipping."); } { DocPreprocessorPipelineResult result; for (auto image : batches.value()[i]) { result.output_image = i