實用技能 | OpenCV演算法程式導出 DLL與調用演示

  • 2019 年 10 月 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::帶上。

最終的運行結果如下:

Tags: