paddleocr C++生成dll

目录

编译完成后修改内容:

新建ppocr.h头文件

注释掉main.cpp内全部内容,将下面内容替换进去。ppocr.h需要再环境配置中包含进去头文件

然后更改配置信息,将exe换成dll

随后右击重新编译会在根目录生成dll,lib文件。

注意这些dll一个也不能少。生成dll后,重新在vs中新建一个C++项目 

内容如下:

相关的配置如下:

需要更改输出目录,添加连接器,并将项目里需要的内容一并放入输出目录中

 结果展示:

 结语:


paddeocr用cmake编译生成exe请查阅我的另一篇博客,这里只看如何在exe的基础上生成dll

借鉴博主:

humour9

 准备版本:release2.5

编译完成后修改内容:

新建ppocr.h头文件

#pragma once
#include <vector>
#include <string>

#ifndef IMAGE_API
#define IMAGE_API

struct TextDetectionResult {
    std::vector<std::vector<int>> boxes;
};

struct TextRecognitionResult {
    std::string text;
    double score;
    
};

extern "C" {
    // 图像推理
    __declspec(dllexport) void ImageProcess(const char* image_dir, TextDetectionResult*** detection_results, int* num_detection_results,
        TextRecognitionResult*** recognition_results, int* num_recognition_results);
    /*__declspec(dllexport) void FreeMemory(TextDetectionResult** detection_results, int num_detection_results,
        TextRecognitionResult** recognition_results, int num_recognition_results);*/
}
#endif

注释掉main.cpp内全部内容,将下面内容替换进去。ppocr.h需要再环境配置中包含进去头文件

#include <iostream>
#include <include/paddleocr.h>
#include <include/args.h>
#include "ppocr.h"


using namespace PaddleOCR;



// 处理图片的函数
void ImageProcess(const char* image_dir, TextDetectionResult*** detection_results, int* num_detection_results,
    TextRecognitionResult*** recognition_results, int* num_recognition_results)
{
    std::cout << "--------" << image_dir << "-------" << std::endl;
    std::string dir(image_dir);
    std::replace(dir.begin(), dir.end(), '/', '\\');
    std::cout << "--------" << dir << "-------" << std::endl;
    std::vector<cv::String> cv_all_img_names;
    cv::glob(image_dir, cv_all_img_names);
    std::cout << "total images num: " << cv_all_img_names.size() << endl;

    PPOCR ocr = PPOCR();

    std::cout << "begin process" << std::endl;
    std::vector<std::vector<OCRPredictResult>> ocr_results = ocr.ocr(cv_all_img_names, FLAGS_det, FLAGS_rec, FLAGS_cls);
    std::cout << "finish process" << std::endl;
    auto ocr_result = ocr_results[0];

    std::vector<TextDetectionResult> detectionResults;
    std::vector<TextRecognitionResult> recognitionResults;


    for (int i = 0; i < ocr_result.size(); i++) {
        if (ocr_result[i].score != -1.0) {
            TextDetectionResult detectionResult;
            detectionResult.boxes = ocr_result[i].box;

            TextRecognitionResult recognitionResult;
            recognitionResult.text = ocr_result[i].text;
            recognitionResult.score = ocr_result[i].score;

            detectionResults.push_back(detectionResult);
            recognitionResults.push_back(recognitionResult);
        }
    }

    *num_detection_results = detectionResults.size();
    *detection_results = new TextDetectionResult * [*num_detection_results];
    for (int i = 0; i < *num_detection_results; i++) {
        (*detection_results)[i] = new TextDetectionResult(detectionResults[i]);
    }

    *num_recognition_results = recognitionResults.size();
    *recognition_results = new TextRecognitionResult * [*num_recognition_results];
    for (int i = 0; i < *num_recognition_results; i++) {
        (*recognition_results)[i] = new TextRecognitionResult(recognitionResults[i]);
    }
    std::cout << "in the end" << std::endl;

    if (*num_recognition_results == 0) {
        std::cout << "result is null" << std::endl;
    }
    
    ///*c*/onst char* img_dir = "E:\paddlepaddle\projects\PaddleOCR-release-2.5\deploy\cpp_infer\qt_project\qt4ocr\imgs\1.jpg";

    cv::Mat srcimg = cv::imread(dir, cv::IMREAD_COLOR);
    if (!srcimg.data) {
        std::cerr << "[ERROR] image read failed! image path: "
            << endl;
        exit(1);
    }
    std::string file_name = Utility::basename(image_dir);
    Utility::VisualizeBboxes(srcimg, ocr_results[0],
        FLAGS_output + file_name);
    std::cout << "***************************" << endl;

}
    

void FreeMemory(TextDetectionResult** detection_results, int num_detection_results,
    TextRecognitionResult** recognition_results, int num_recognition_results)
{
    for (int i = 0; i < num_detection_results; i++) {
        delete detection_results[i];
    }
    delete[] detection_results;

    for (int i = 0; i < num_recognition_results; i++) {
        delete recognition_results[i];
    }
    delete[] recognition_results;
}

然后更改配置信息,将exe换成dll

随后右击重新编译会在根目录生成dll,lib文件。

注意这些dll一个也不能少。生成dll后,重新在vs中新建一个C++项目 

内容如下:

#include <iostream>
#include <vector>
#include <string>
#include <Windows.h>

struct TextDetectionResult {
    std::vector<std::vector<int>> boxes;
};

struct TextRecognitionResult {
    std::string text;
    double score;
};

typedef void (*ImageProcessFunc)(const char* image_dir, TextDetectionResult*** detection_results, int* num_detection_results,
    TextRecognitionResult*** recognition_results, int* num_recognition_results);

void FreeMemory(TextDetectionResult** detection_results, int num_detection_results,
    TextRecognitionResult** recognition_results, int num_recognition_results)
{
    for (int i = 0; i < num_detection_results; i++) {
        delete detection_results[i];
    }
    delete[] detection_results;

    for (int i = 0; i < num_recognition_results; i++) {
        delete recognition_results[i];
    }
    delete[] recognition_results;
}

int main()
{
    system("chcp 65001");
    const char* image_dir = "C:\\Users\\lenovo\\source\\repos\\test_dll\\test_dll//1234.jpg";
    const char* dll_path = "C:\\Users\\lenovo\\source\\repos\\test_dll\\test_dll/ppocr.dll";

    HMODULE hModule = LoadLibraryA(dll_path);
    if (hModule == NULL) {
        std::cout << "Failed to load the DLL." << std::endl;
        return 1;
    }

    ImageProcessFunc ImageProcess = (ImageProcessFunc)GetProcAddress(hModule, "ImageProcess");
    if (ImageProcess == NULL) {
        std::cout << "Failed to get the function address." << std::endl;
        FreeLibrary(hModule);
        return 1;
    }

    TextDetectionResult** detection_results = nullptr;
    int num_detection_results = 0;
    TextRecognitionResult** recognition_results = nullptr;
    int num_recognition_results = 0;

    ImageProcess(image_dir, &detection_results, &num_detection_results, &recognition_results, &num_recognition_results);

    if (num_detection_results > 0) {
        std::cout << "get the result" << std::endl;
        for (int i = 0; i < num_detection_results; i++) {
            std::vector<std::vector<int>> boxes = detection_results[i]->boxes;
            std::cout << "det boxes: [";
            for (int n = 0; n < boxes.size(); n++) {
                std::cout << '[' << boxes[n][0] << ',' << boxes[n][1] << "]";
                if (n != boxes.size() - 1) {
                    std::cout << ',';
                }
            }
            std::string recognitionResult = recognition_results[i]->text;
            std::cout << "] " << "  " << " recognition text : " << recognitionResult << std::endl;

        }
    }
    std::cout << "begin clear" << std::endl;
    // 释放内存
    FreeMemory(detection_results, num_detection_results, recognition_results, num_recognition_results);

    // 卸载 DLL
    FreeLibrary(hModule);

    std::cout << "clear over" << std::endl;

    return 0;
}

相关的配置如下:

需要更改输出目录,添加连接器,并将项目里需要的内容一并放入输出目录中

 

 结果展示:

 结语:

只提供解决方案,非无偿解答问题。

===================2024.4.28日修改==============

新增release2.7版本修改内容

mian.cpp内容    2.7及以后版本 ocr.ocr函数内容传参变为img_list, FLAGS_det, FLAGS_rec, FLAGS_cls。  所以将mian函数修改一下重新定义一个img_list 这个团队的源码里面也有。其他与之前的内容保持一致。

#include <iostream>
#include <include/paddleocr.h>
#include <include/args.h>
#include "ooccrr.h"


using namespace PaddleOCR;
// 处理图片的函数
void ImageProcess(const char* image_dir, TextDetectionResult*** detection_results, int* num_detection_results,
    TextRecognitionResult*** recognition_results, int* num_recognition_results)
{
    std::cout << "--------" << image_dir << "-------" << std::endl;
    std::string dir(image_dir);
    std::replace(dir.begin(), dir.end(), '/', '\\');
    std::cout << "--------" << dir << "-------" << std::endl;
    std::vector<cv::String> cv_all_img_names;
    cv::glob(image_dir, cv_all_img_names);
    std::cout << "total images num: " << cv_all_img_names.size() << std::endl;

    PPOCR ocr = PPOCR();

    std::cout << "begin process" << std::endl;
    //PPOCR::ocr(std::vector<cv::Mat> img_list, bool det, bool rec, bool cls)
    std::vector<cv::Mat> img_list;
    std::vector<cv::String> img_names;
    for (int i = 0; i < cv_all_img_names.size(); ++i) {
        cv::Mat img = cv::imread(cv_all_img_names[i], cv::IMREAD_COLOR);
        if (!img.data) {
            std::cerr << "[ERROR] image read failed! image path: "
                << cv_all_img_names[i] << std::endl;
            continue;
        }
        img_list.push_back(img);
        img_names.push_back(cv_all_img_names[i]);
    }

    std::vector<std::vector<OCRPredictResult>> ocr_results = ocr.ocr(img_list, FLAGS_det, FLAGS_rec, FLAGS_cls);

    std::cout << "finish process" << std::endl;
    auto ocr_result = ocr_results[0];

    std::vector<TextDetectionResult> detectionResults;
    std::vector<TextRecognitionResult> recognitionResults;


    for (int i = 0; i < ocr_result.size(); i++) {
        if (ocr_result[i].score != -1.0) {
            TextDetectionResult detectionResult;
            detectionResult.boxes = ocr_result[i].box;

            TextRecognitionResult recognitionResult;
            recognitionResult.text = ocr_result[i].text;
            recognitionResult.score = ocr_result[i].score;

            detectionResults.push_back(detectionResult);
            recognitionResults.push_back(recognitionResult);
        }
    }

    *num_detection_results = detectionResults.size();
    *detection_results = new TextDetectionResult * [*num_detection_results];
    for (int i = 0; i < *num_detection_results; i++) {
        (*detection_results)[i] = new TextDetectionResult(detectionResults[i]);
    }

    *num_recognition_results = recognitionResults.size();
    *recognition_results = new TextRecognitionResult * [*num_recognition_results];
    for (int i = 0; i < *num_recognition_results; i++) {
        (*recognition_results)[i] = new TextRecognitionResult(recognitionResults[i]);
    }
    std::cout << "in the end" << std::endl;

    if (*num_recognition_results == 0) {
        std::cout << "result is null" << std::endl;
    }

    ///*c*/onst char* img_dir = "E:\paddlepaddle\projects\PaddleOCR-release-2.5\deploy\cpp_infer\qt_project\qt4ocr\imgs\1.jpg";

    cv::Mat srcimg = cv::imread(dir, cv::IMREAD_COLOR);
    if (!srcimg.data) {
        std::cerr << "[ERROR] image read failed! image path: "
            << std::endl;
        exit(1);
    }
    std::string file_name = Utility::basename(image_dir);
    Utility::VisualizeBboxes(srcimg, ocr_results[0],
        FLAGS_output + file_name);
    std::cout << "***************************" << std::endl;

}


void FreeMemory(TextDetectionResult** detection_results, int num_detection_results,
    TextRecognitionResult** recognition_results, int num_recognition_results)
{
    for (int i = 0; i < num_detection_results; i++) {
        delete detection_results[i];
    }
    delete[] detection_results;

    for (int i = 0; i < num_recognition_results; i++) {
        delete recognition_results[i];
    }
    delete[] recognition_results;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/581761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

伪装目标检测论文阅读 SAM大模型之参数微调:Conv LoRA

paper&#xff1a;link code&#xff1a;还没公开 摘要 任意分割模型(SAM)是图像分割的基本框架。虽然它在典型场景中表现出显著的零镜头泛化&#xff0c;但当应用于医学图像和遥感等专门领域时&#xff0c;其优势就会减弱。针对这一局限性&#xff0c;本文提出了一种简单有效…

Java进阶-JavaStreamAPI的使用

本文全面介绍了 Java Stream API 的概念、功能以及如何在 Java 中有效地使用它进行集合和数据流的处理。通过详细解释和示例&#xff0c;文章展示了 Java Stream API 在简化代码、提高效率以及支持函数式编程方面的优势。文中还比较了 Java Stream API 与其他集合处理库的异同&…

Django之搭配内网穿透

一&#xff0c;安装coplar 二&#xff0c;开启8087的内网穿透 三&#xff0c;setting.py中加入如下配置&#xff1a; ALLOWED_HOSTS [*]CSRF_TRUSTED_ORIGINS ["https://localhost:8087", "http://localhost:8087"]四&#xff0c;启动项目 五&#xff…

比较美观即将跳转html源码

源码介绍 比较美观即将跳转html源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 源码截图 比较美观的一个跳转界面&#xff0c;修改方法如上&…

MATLAB实现果蝇算法优化BP神经网络预测分类(FOA-BP)

果蝇算法&#xff08;Fruit Fly Optimization Algorithm, FFOA&#xff09;是一种启发式优化算法&#xff0c;受果蝇觅食行为的启发。将其应用于优化BP神经网络&#xff0c;主要是为了寻找BP神经网络中的最佳权重和偏置值。以下是一个基本的流程&#xff1a; 初始化&#xff1a…

Ubuntu20.04 [Ros Noetic]版本——在catkin_make编译时出现报错的解决方案

今天在新的笔记本电脑上进行catkin_make的编译过程中遇到了报错&#xff0c;这个报错在之前也遇到过&#xff0c;但是&#xff0c;我却忘了怎么解决。很是头痛&#xff01; 经过多篇博客的查询&#xff0c;特此解决了这个编译报错的问题&#xff0c;于此特地记录&#xff01;&…

【bug已解决】发生错误,导致虚拟 CPU 进入关闭状态。如果虚拟机外部发生此错误,则可能已导致物理计算机重新启动......

本bug报错已找到原因,并成功解决。 项目场景: vmware安装ubuntu报错。 如下: 发生错误,导致虚拟 CPU 进入关闭状态。如果虚拟机外部发生此错误,则可能已导致物理计算机重新启动。错误配置虚拟机、客户机操作系统中的错误或 VMware Workstation 中的问题都可以导致关闭状…

kaggle(4) Regression with an Abalone Dataset 鲍鱼数据集的回归

kaggle&#xff08;4&#xff09; Regression with an Abalone Dataset 鲍鱼数据集的回归 import pandas as pd import numpy as npimport xgboost import lightgbm import optuna import catboostfrom sklearn.model_selection import train_test_split from sklearn.metrics …

C++之list模拟实现

1、定义 定义一个结点&#xff1a; 在list类中的定义&#xff1a; 2、push_back() 3、迭代器 3.1迭代器的构造和定义 3.2、迭代器中的取值 3.3、迭代器的迭代(前置或前置--) 3.4、迭代器的迭代(后置或后置--) 3.5、迭代器的判断 3.6、在类list的定义 4.begin()和end() 5.con…

Nodejs 第六十九章(杀毒)

杀毒 杀毒&#xff08;Antivirus&#xff09;是指一类计算机安全软件&#xff0c;旨在检测、阻止和清除计算机系统中的恶意软件&#xff0c;如病毒、蠕虫、木马、间谍软件和广告软件等。这些恶意软件可能会对计算机系统和用户数据造成损害&#xff0c;包括数据丢失、系统崩溃、…

⑥ - 后端工程师通识指南

&#x1f4d6; 该文隶属 程序员&#xff1a;职场关键角色通识宝典 ✍️ 作者&#xff1a;哈哥撩编程&#xff08;视频号同名&#xff09; 博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 &#x1f3c6; 推荐专栏…

windows下git提交修改文件名大小写提交无效问题

windows系统不区分大小写&#xff0c;以及git提交忽略大小写&#xff0c;git仓库已存在文件A.js&#xff0c;本地修改a.js一般是没有提交记录的&#xff0c;需要手动copy一份出来A.js&#xff0c;再删除A.js文件提交仓库删除后&#xff0c;再提交修改后的a.js文件。 windows决…

岚图汽车与东软睿驰签署战略合作协议

4月26日,东软睿驰与岚图汽车正式签署战略合作协议,双方将结合在各自领域拥有的产业资源、技术研发和资本运作等优势,聚焦智能化产品和应用,建立长期共赢的战略合作伙伴关系,通过不断探索未来新技术、新产业、新业态和新模式,围绕用户需求共同打造极致的智能出行体验。 图为岚图…

【AIGC调研系列】llama3微调具体案例

Llama3的微调可以通过多种方式进行&#xff0c;具体案例包括&#xff1a; 使用XTuner进行微调&#xff0c;尝试让Llama3具有"它是SmartFlowAI打造的人工智能助手"的自我认知。这涉及到准备自我认知训练数据集&#xff0c;并通过脚本生成数据[2][8]。利用Unsloth和Go…

GD32E103C8T6 封装LQFP-48 GigaDevice(兆易创新) 单片机

GD32E103C8T6 是由GigaDevice&#xff08;兆易创新&#xff09;公司生产的一款基于ARM Cortex-M4内核的32位MCU&#xff08;微控制器&#xff09;。以下是GD32E103C8T6的一些主要功能和参数介绍&#xff1a; 主要功能&#xff1a; 高性能ARM Cortex-M4内核: 采用120MHz的ARM …

求解素数环问题

注&#xff1a;这里我的代码是以第一位为最大数n为首元素不动的 思路&#xff1a; 首先我们分析问题要以较小规模的样例进行分析&#xff0c;例如n3时 第一步&#xff1a;深入搜索 我们先不管后面怎么样&#xff0c;当前的首要目标是先确定第一个元素的值&#xff0c;可知有…

paddlehub的简单应用

1、下载安装 pip install paddlehub -i https://pypi.tuna.tsinghua.edu.cn/simple 报错&#xff1a; Collecting onnx<1.9.0 (from paddle2onnx>0.5.1->paddlehub)Using cached https://pypi.tuna.tsinghua.edu.cn/packages/73/e9/5b953497c0e36df589fc60cc6c6b35…

Java中集合概述(补充ing)

一、集合分类 Java中的集合框架提供了多种类型的集合&#xff0c;主要分为两大类&#xff1a;单列集合&#xff08;只保存单一类型的对象&#xff09;和双列集合&#xff08;保存具有键值对关系的对象&#xff09;。下面对这些集合进行分类介绍&#xff0c;但由于源码分析会涉…

开源相机管理库Aravis例程学习(五)——camera-api

开源相机管理库Aravis例程学习&#xff08;五&#xff09;——camera-api 简介例程代码函数说明arv_camera_get_regionarv_camera_get_pixel_format_as_stringarv_camera_get_pixel_formatARV_PIXEL_FORMAT_BIT_PER_PIXEL 简介 本文针对官方例程中的&#xff1a;03-camera-api…

沉浸式翻译 chrome 插件 Immersive Translate - Translate Website PDF

免费翻译网站&#xff0c;翻译PDF和Epub电子书&#xff0c;双语翻译视频字幕 &#x1f4e3; 网络上口碑爆炸的网站翻译扩展工具【沉浸式翻译】⭐⭐⭐⭐⭐ &#x1f4bb; 功能特点如下&#xff1a; &#x1f4f0; 网站翻译 &#x1f680; 提供双语网站翻译&#xff0c;智能识…