paddleocr C++生成dll

news2024/11/28 7:32:01

目录

编译完成后修改内容:

新建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.coloradmin.cn/o/1631553.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML5(2)

目录 一.列表、表格、表单 1.列表标签 2.表格 4.无语义的布局标签 5.字符实体 6.综合案例--1 7.综合案例--表单 一.列表、表格、表单 1.列表标签 1.1 无序列表 1.2 有序列表 1.3 定义列表 定义列表一般用于网页底部的帮助中心 2.表格 2.1 2.2 表格结构标签 shiftaltf 格…

计算机网络之传输层TCP\UDP协议

UDP协议 用户数据报协议UDP概述 UDP只在IP数据报服务之上增加了很少功能&#xff0c;即复用分用和差错检测功能 UDP的主要特点&#xff1a; UDP是无连接的&#xff0c;减少开销和发送数据之前的时延 UDP使用最大努力交付&#xff0c;即不保证可靠交付&#xff0c;可靠性由U…

《Fundamentals of Power Electronics》——全桥型隔离降压转换器

以下是关于全桥型隔离降压转换器的相关知识点&#xff1a; 全桥变压器隔离型降压转换器如下图所示。 上图展示了一个具有二次侧绕组中心抽头的版本&#xff0c;该电路常用于产生低输出电压。二次侧绕组的上下两个绕组可以看作是两个单独的绕组&#xff0c;因此可以看成是具有变…

#const成员

基于写的日期类的实现&#xff0c;去分析const成员的问题。 需要用到下面的两个函数。 这个时候我们去构建一个const Date,如下&#xff0c;这是不和法的&#xff0c;为什么呢&#xff1f; 其实这里涉及一个权限放大的问题&#xff0c;之前就说了&#xff0c;权限可以缩小&…

项目部署总结

1、安装jdk 第一步&#xff1a;上传jdk压缩安装包到服务器 第二步&#xff1a;将压缩安装包解压 tar -xvf jdk-8uXXX-linux-x64.tar.gz 第三步&#xff1a;配置环境变量 编辑/etc/profile文件&#xff0c;在文件末尾添加以下内容&#xff1a; export JAVA_HOME/path/to/j…

应急学院物联网应急安全产教融合基地解决方案

第一章 背景 1.1物联网应急安全产教融合发展概况 物联网应急安全产教融合发展是当前社会发展的重要趋势。随着物联网技术的广泛应用&#xff0c;应急安全领域对人才的需求日益迫切。因此&#xff0c;产教融合成为培养高素质、专业化人才的关键途径。在这一背景下&#xff0c;…

Kotlin泛型之 循环引用泛型(A的泛型是B的子类,B的泛型是A的子类)

IDE(编辑器)报错 循环引用泛型是我起的名字&#xff0c;不知道官方的名字是什么。这个问题是我在定义Android 的MVP时提出来的。具体是什么样的呢&#xff1f;我们看一下我的基础的MVP定义&#xff1a; interface IPresenter<V> { fun getView(): V }interface IVie…

云原生Kubernetes: K8S 1.29版本 部署Sonarqube

一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构版本IP备注masterK8S master节点1.29.0192.168.204.8 node1K8S node节点1.29.0192.168.204.9node2K8S node节点1.29.0192.168.204.10已部署Kuboard &#xff08;2&#xff09;master节点查看集群 1&…

【已解决】Python Selenium chromedriver Pycharm闪退的问题

概要 根据不同的业务场景需求&#xff0c;有时我们难免会使用程序来打开浏览器进行访问。本文在pycharm中使用selenium打开chromedriver出现闪退问题&#xff0c;根据不断尝试&#xff0c;最终找到的问题根本是版本问题。 代码如下 # (1) 导入selenium from selenium import …

RDD算子使用----transformation转换操作

RDD算子使用 transformation转换操作 map算子 rdd.map(p: A > B):RDD&#xff0c;对rdd集合中的每一个元素&#xff0c;都作用一次该func函数&#xff0c;之后返回值为生成元素构成的一个新的RDD。 val sc new SparkContext(conf)//map 原集合*7val list 1 to 7//构建…

纯血鸿蒙APP实战开发——全局状态保留能力弹窗

全局状态保留能力弹窗 介绍 全局状态保留能力弹窗一种很常见的能力&#xff0c;能够保持状态&#xff0c;且支持全局控制显隐状态以及自定义布局。使用效果参考评论组件 效果图预览 使用说明 使用案例参考短视频案例 首先程序入口页对全局弹窗初始化&#xff0c;使用Globa…

Redis基本數據結構 ― List

Redis基本數據結構 ― List 介紹常用命令範例1. 將元素推入List中2. 取得List內容3. 彈出元素 介紹 Redis中的List結構是一個雙向鏈表。 LPUSH LPOP StackLPUSH RPOP QueueLPUSH BRPOP Queue(消息隊列) 常用命令 命令功能LPUSH將元素推入列表左端RPUSH將元素推入列表右…

ZooKeeper 环境搭建详细教程之三(真集群)

ZooKeeper 搭建详细步骤之三(真集群) ZooKeeper 搭建详细步骤之二(伪集群模式) ZooKeeper 搭建详细步骤之一(单机模式) ZooKeeper 及相关概念简介 真集群搭建 搭建 ZooKeeper 真集群涉及多个步骤,包括准备环境、配置文件设置、启动服务以及验证集群状态。 以下是一个简…

如何基于Zookeeper实现注册中心模型?

在分布式系统中&#xff0c;通常会存在几十个甚至上百个服务&#xff0c;开发人员可能甚至都无法明确系统中到底有哪些服务正在运行。另一方面&#xff0c;我们很难同时确保所有服务都不出现问题&#xff0c;也很难保证当前的服务部署方式不做调整和优化。由于自动扩容、服务重…

天冕科技亮相第十七届深圳国际金融博览会!

第十七届深圳国际金融博览会在深圳会展中心正式开幕&#xff0c;天冕科技跟随南山区组团集体亮相&#xff0c;充分展现金融活力。此次金博会&#xff0c;南山区政府共遴选了包括天冕科技在内的三家优秀金融科技企业组团参展&#xff0c;以特色与创新的案例展示了辖区金融业发展…

Power BI:如何将文件夹批量Excel(多sheet页)文件导入?

故事背景&#xff1a; 业务同事想用Power BI分析近两年市场费用。 数据源全部是Excel文件&#xff0c;并且以每月一个Excel文件的方式&#xff0c;统一存放到同一文件夹下面。 重点&#xff0c;每张Excel文件会有多张sheet页&#xff0c;用区分每家分公司的费用信息。 目前…

照片误删怎么办?华为手机删除的照片如何恢复?

我们在使用华为手机时&#xff0c;可能会因为各种原因不小心删除一些照片。如果这些照片对我们来说很重要&#xff0c;那么恢复它们是非常必要且急迫的。那么华为手机删除的照片如何恢复呢&#xff1f;本文将为您介绍3种恢复华为手机中误删照片的方法。 如何恢复华为手机中被删…

Vue3 v3.4之前如何实现组件中多个值的双向绑定?

文章目录 基础代码1. watch2. computed&#xff08;推荐&#xff09; 官方给的例子是关于el-input的&#xff0c;如下。但是input不是所有组件标签都有的属性啊&#xff0c;有没有一种通用的办法呢&#xff1f; <script setup> defineProps({firstName: String,lastName…

VS2022 配置OpenCV开发环境详细教程

OpenCV OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库&#xff0c;由Intel开发并首先发布于1999年。OpenCV被广泛用于实时图像处理、视频分析、物体检测、面部识别、机器人视觉以及许多其他领域。它支持C、Pytho…

【vscode环境配置系列】vscode远程debug配置

VSCODE debug环境配置 插件安装配置文件debug 插件安装 安装C/C, C/C Runner 配置文件 在项目下建立.vscode文件夹&#xff0c;然后分别建立c_cpp_properties.json&#xff0c; launch.json&#xff0c;tasks.json&#xff0c;内容如下&#xff1a; c_cpp_properties.json:…