【C++】调用dll(基于PaddleX部署生成的dll)

写在前面

这篇文章是基于PaddleX生成的DLL,使用C++调用。也可调用其他的DLL,都是同理的。

1、新建C++项目

用vs2019新建一个C++项目,并把基于PaddleX部署生成的DLL复制到项目目录下,同时还有把自己训练导出的模型和测试的图片也复制到项目目录下面。并在项目中配置好opencv的环境。
在这里插入图片描述

2、二次封装dll(可选)

这里是将model_infer.dll的函数,再封装成一个C++的类来调用。(这一步可以不做,根据需要选择)
在这里插入图片描述

2.1 paddlex.h

#pragma once
#include <iostream>
#include <Windows.h>

using namespace std;

// 定义函数指针类型
// Model initialization and destruction API
typedef void (*InitModel)(const char*, const char*, const char*, const char*, bool, int, char*);
typedef void (*DestructModel)();
// Model reasoning API: det, seg, clas, mask
typedef void (*Seg_ModelPredict)(const unsigned char*, int, int, int, unsigned char* , unsigned int*);

class PaddleX
{
    
    
public:
	PaddleX();
	PaddleX(HMODULE dll);
	~PaddleX();

private:
	HMODULE px_dll;

    InitModel initmodel_;
    DestructModel destructmodel_;
    // Model reasoning API
    Seg_ModelPredict seg_modelpredict_;

public:
	// 模型初始化
	void Init_Model(const char* model_type, const char* model_filename, const char* params_filename, const char* cfg_file, bool use_gpu, int gpu_id, char* paddlex_model_type);

	// 销毁模型
	void Destruct_Model();

	// 语义分割预测
	void Seg_Model_Predict(const unsigned char* img, int nWidth, int nHeight, int nChannel, unsigned char* output, unsigned int* tar_pos);
};

2.2 paddlex.cpp

#include "paddlex.h"

// 默认构造函数
PaddleX::PaddleX() {
    
    }

PaddleX::PaddleX(HMODULE dll) {
    
    
	this->px_dll = dll;

    // GetProcAddress返回指向的函数名的函数地址
    this->initmodel_ = (InitModel)GetProcAddress(this->px_dll, "InitModel");
    this->destructmodel_ = (DestructModel)GetProcAddress(this->px_dll, "DestructModel");
    // Model reasoning API
    this->seg_modelpredict_ = (Seg_ModelPredict)GetProcAddress(this->px_dll, "Seg_ModelPredict");
}

PaddleX::~PaddleX() {
    
    

}

// 模型初始化
void PaddleX::Init_Model(const char* model_type, const char* model_filename, const char* params_filename, const char* cfg_file, bool use_gpu, int gpu_id, char* paddlex_model_type)
{
    
    
	this->initmodel_(model_type, model_filename, params_filename, cfg_file, use_gpu, gpu_id, paddlex_model_type);
}

// 销毁模型
void PaddleX::Destruct_Model()
{
    
    
	this->destructmodel_();
}

// 语义分割预测
void PaddleX::Seg_Model_Predict(const unsigned char* img, int nWidth, int nHeight, int nChannel, unsigned char* output, unsigned int* tar_pos)
{
    
    
    this->seg_modelpredict_(img, nWidth, nHeight, nChannel, output, tar_pos);
}

3、主函数 paddleX_test.cpp

这里有一点很坑的是,我训练图像时把图像归一化再训练;但是这里调用把图像归一化推理出来的结果全是0,没有归一化就可以推理出正确结果,无语,不知道为什么。

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

#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
// 调用自己再封装的paddlex
#include "paddlex.h"

using namespace std;
using namespace cv;

int main()
{
    
    
    // 加载PaddleX
    HMODULE paddle_dll = LoadLibrary(_T("model_infer.dll"));
    if (paddle_dll == NULL) {
    
    
        cout << "加载model_infer.dll失败!" << endl;
    }
    else {
    
    
        cout << "加载model_infer.dll成功!" << endl;
    }
    // 创建paddlx实例(自己封装的)
    PaddleX px(paddle_dll);

    char paddlex_model_type[10] = "";

    // 初始化模型
    px.Init_Model("seg", "model/model.pdmodel", "model/model.pdiparams", "model/deploy.yaml", 1, 0, paddlex_model_type);

    // 加载图片
    String img_file = "images/test.jpg";
    Mat image = imread(img_file);  //BGR
    resize(image, image, Size(512, 512));

    // 设置输出
    unsigned char out_image[512 * 512];
    memset(out_image, 0, sizeof(out_image));
    unsigned int* pos = new unsigned int(0);

    // 预测
    px.Seg_Model_Predict((const uchar*)image.data, 512, 512, 3, out_image, pos);
    cout << "输出结果:" << *pos << endl;

    cout << "\n---------太diǎo了---------\n";

    // 销毁模型
    px.Destruct_Model();

    system("pause");

}

6.3、运行程序

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/iiinoname/article/details/124316092