當前位置: 妍妍網 > 碼農

手把手教你 封裝YOLOv8推理位DLL 給客戶端呼叫

2024-03-04碼農

點選上方 藍字 關註我們

微信公眾號: OpenCV學堂

關註獲取更多電腦視覺與深度學習知識

前言

建立DLL有幾種不同的方式,最簡單直接的的方式就是透過VS內建的動態連結庫(DLL)計畫,把相關的功能封裝成一個類,然後匯出幾個介面方法,編譯成功以後生成DLL檔,就可以在其他地方跟正常的第三方庫配置之後一樣呼叫了。

01

建立DLL

首先開啟VS建立一個DLL空計畫,開啟VS的桌面精靈如下:

建立DLL連結庫計畫

然後在表頭檔中添加mytest.h檔,添加程式碼如下:

#pragma once
#ifdef _DLL_EXPORTS
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif
#include<opencv2/opencv.hpp>
//=========匯出函式C++呼叫介面============
classDLL_APIMyTestDLL {
public:
intaddData(int a, int b);
~MyTestDLL();
};

然後在原始檔中添加mytest.cpp檔,添加程式碼如下:

#define _DLL_EXPORTS
#include<mytest.h>
MyTestDLL::~MyTestDLL() {
std::cout << "destory instance done!" << std::endl;
}
int MyTestDLL::addData(int a, int b) {
int sum = 0;
sum = a + b;
std::cout << "sum: " << sum << std::endl;
return sum;
}

編譯執行成功,顯示如下:

02

DLL測試程式

建立測試程式,來測試DLL。新建一個控制台空計畫,在原始檔中添加main.cpp檔,然後添加如下程式碼:

#include"opencv2/opencv.hpp"
#include"mytest.h"
intmain(int argc, char** argv){
std::cout << "test mydll..." << std::endl;
std::shared_ptr<MyTestDLL> mydll(new MyTestDLL());
int sum = mydll->addData(35);
std::cout << "DLL invoke result : " << sum << std::endl;
return0;
}

執行結果如下:

YOLOv8物件檢測DLL測試

采用相同的方法,基於ONNXRUNTIME深度學習模型庫框架, 我對以前ONNXRUNTIME + YOLOv8物件檢測C++程式碼稍作修改,封裝了一個YOLOv8物件檢測推理類為DLL,支持C++與C#介面呼叫。客戶端呼叫程式碼如下:

#include"yolov8_infer.h"
#include<iostream>
#include<fstream>
std::string label_map = "D:/python/yolov5-7.0/ classes.txt";
intmain(int argc, char** argv){
std::string names = "10:bike";
int pos = names.find_first_of(":");
std::cout << names.substr(0, pos) << " -->> " << names.substr(pos + 1) << std::endl;
std::vector<std::string> classNames;
std::ifstream fp(label_map);
std::string name;
while (!fp.eof()) {
getline(fp, name);
if (name.length()) {
classNames.push_back(name);
}
}
fp.close();
// std::shared_ptr<YOLOv5ORTDetector> detector(new YOLOv5ORTDetector());
std::shared_ptr<YOLOv8ORTDetector> detector(new YOLOv8ORTDetector());
detector->initConfig("D:/python/my_yolov8_train_demo/yolov8n.onnx"6406400.25f0.5);
cv::VideoCapture capture("D:/images/video/sample.mp4");
cv::Mat frame;
std::vector<DetectResult> results;
while (true) {
bool ret = capture.read(frame);
if (frame.empty()) {
break;
}
int64 start = cv::getTickCount();
detector->detect(frame, results);
float fps = static_cast<float>(cv::getTickFrequency()) / (cv::getTickCount() - start);
cv::putText(frame, cv::format("FPS: %.2f", fps), cv::Point(5050), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(2550255), 28); 
for (DetectResult dr : results) {
cv::Rect box = dr.box;
cv::putText(frame, classNames[dr. classId], cv::Point(box.tl().x, box.tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .5, cv::Scalar(000));
}
cv::imshow("YOLOv8 + ONNXRUNTIME - DLL匯出演示", frame);
char c = cv::waitKey(1);
if (c == 27) { // ESC 結束
break;
}
// reset for next frame
results.clear();
}
return0;
}

執行截圖如下:

系統化學習直接掃碼檢視

推薦閱讀