实用技能 | OpenCV算法程序导出 DLL与调用演示

December 17, 2023
测试
测试
测试
测试
5 分钟阅读

阅读本文大概需要 4min

很多时候OpenCV开发者完成来了一个自定义的算法程序并不想给对方提供源代码调用,只想提供一个接口调用,这个时候我们可以把OpenCV的代码进行接口封装,然后导出成为DLL,给第三方应用程序调用,这个也是OpenCV开发者的基本功之一。下面分为两个部分来说明,第一部分是说明如何制作与生成DLL,第二部分说明如何调用导出DLL。

完整的示例以一个简单的图像卷积模糊为例,说明如何完成整个代码编写与DLL导出、参数传递与调用演示。

Part.1

实现DLL程序编写与导出!

首先新建一个DLL的空项目,选择控制台应用,然后再选择DLL项目,图示如下:

点击完成,就得到了一个控制台应用,分别新建头文件与源代码文件,头文件中的声明与定义如下:

#pragma once
#pragma once
#ifndef DLL_CELL_H
#define DLL_CELL_H

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

// 高斯模糊
const int GAUSSIAN_BLUR = 1;
// 均值模糊
const int SMOOTH_BLUR = 2;

#endif

实现模糊的代码如下:

#include"myblur.h"

//生成dll文件声明 , 支持高斯与均值模糊
extern "C" __declspec(dllexport) void myImageBlur(Mat &image,  int type, double sigma, int ksize);

void myImageBlur(Mat &image, int type, double sigma, int ksize) {
    if (type == GAUSSIAN_BLUR) {
        Mat temp;
        GaussianBlur(image, temp, Size(ksize, ksize), sigma);
        temp.copyTo(image);
    }
    else if (type == SMOOTH_BLUR) {
        Mat temp;
        blur(image, temp, Size(ksize, ksize), Point(-1, -1), 4);
        temp.copyTo(image);
    }
    else {
        printf("Unsupported blur type....");
    }
}

完成代码部分之后,需要添加一个DLL声明模板文件,选择项目右键点击添加之后,对话框图示如下:

点击添加之后,把下面的脚本copy到文件中去

LIBRARY "blur_dll"
EXPORTS 
        myImageBlur

其中:

第一行表示导出的DLL声明

下面的表示的导出的方法声明(给第三方调用的接口方法)

如果有多个方法,导出的格式如下:

方法名@方法序号, 举例如下:

LIBRARY "yourdllwithname"
EXPORTS
          Method1@1
          Method1@2
          Methodn@n

然后选择当前的项目右键 ->生成,即可得到生成好的dll文件,至此DLL文件导出成功,截图如下:

Part.2

调用导出的接口,这里分为两种情况,一种是静态调用,需要头文件、库文件支持,而且还要设置一堆配置。另外一种方式是直接加载DLL调用(动态调用),这种方法可以说是简单粗暴,只需要把编译好的dll文件copy到应用程序exe所在目录即可。

这里我们就采用第二种方法,首先新建一个OpenCV控制台空项目

加载DLL与调用接口方法的代码演示如下:

#include <iostream>  
#include <Windows.h>
#include <opencv2/opencv.hpp>  

typedef void(*Dllfun)(cv::Mat &image, int type, double sigma, int ksize);
int main()
{
    Dllfun myImageBlur;
    HINSTANCE hInst = LoadLibrary(L"blur_dll.dll");
    if (!hInst)
    {
        printf("加载dll失败!\n");
        return -1;
    }
    myImageBlur = (Dllfun)GetProcAddress(hInst, "myImageBlur");

    // 加载图像
    cv::Mat src = cv::imread("D:/images/flower.png");
    cv::Mat copy = src.clone();
    cv::namedWindow("input", cv::WINDOW_AUTOSIZE);
    cv::imshow("input", src);

    // 高斯模糊
    myImageBlur(src, 1, 15, 0);
    cv::imshow("gaussian blur", src);

    // 均值模糊
    myImageBlur(copy, 2, 0, 15);
    cv::imshow("box blur", copy);
    cv::waitKey(0);
    return 0;
}

这里需要注意的是windows.h中会有很多跟OpenCV中冲突的方法与常量命名,所以在调用OpenCV相关函数方法与常量时候只有老老实实的把前缀cv::带上。

最终的运行结果如下:

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多