Table of contents
2. Create a new dynamic link library project
3. Configure opencv, and the corresponding attribute configuration
1. Install vs2022
2. Create a new dynamic link library project
Click to create a new project, search for dll to find the new project of the dynamic link library
What it looks like after creation
3. Configure opencv, and the corresponding attribute configuration
The premise is to configure the environment variables for opencv for yourself
Add according to the opencv path you installed
VC++ directory -> include directory: opencv\build\include\opencv2 and opencv\build\include
VC++ directory -> library directory: opencv\build\x64\vc15\lib and opencv\build\x64\vc15\bin
Connector -> Input -> Additional dependencies: opencv_world460d.lib (with d is running Debug, without d is Release)
CHARACTER SET TO MULTIBYTE CHARACTER SET
C/C++->Precompiled Header->Precompiled Header: Create (/Yc) instead, change it later according to your own needs, or remove the .h file in the precompiled header file
4. Code
Create header and source files with arbitrary names
//yolo.h
#pragma once
#ifndef MY_HEADER_H
#define MY_HEADER_H
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include "windows.h"
using namespace std;
using namespace cv;
const int INPUT_WIDTH = 640;
const int INPUT_HEIGHT = 640;
const float SCORE_THRESHOLD = 0.5;
const float NMS_THRESHOLD = 0.45;
const float CONFIDENCE_THRESHOLD = 0.45;
extern "C" _declspec(dllexport) void pre_process(cv::Mat & image, cv::Mat & blob);
extern "C" _declspec(dllexport) void a_process(cv::Mat & blob, cv::dnn::Net & net, std::vector<cv::Mat>&outputs);
extern "C" _declspec(dllexport) void draw_result(cv::Mat & image, std::string label, cv::Rect box);
extern "C" _declspec(dllexport) cv::Mat post_process(cv::Mat& image, std::vector<cv::Mat>& outputs, std::vector<std::string>& class_name);
extern "C" _declspec(dllexport) int main();
#endif
//yolo.cpp
#include "yolo.h"
#include "pch.h"
void pre_process(cv::Mat& image, cv::Mat& blob)
{
cv::dnn::blobFromImage(image, blob, 1. / 255., cv::Size(INPUT_WIDTH, INPUT_HEIGHT), cv::Scalar(), true, false);
}
void a_process(cv::Mat& blob, cv::dnn::Net& net, std::vector<cv::Mat>& outputs)
{
net.setInput(blob);
net.forward(outputs, net.getUnconnectedOutLayersNames());
}
void draw_result(cv::Mat& image, std::string label, cv::Rect box)
{
cv::rectangle(image, box, cv::Scalar(255, 0, 0), 2);
int baseLine;
cv::Size label_size = cv::getTextSize(label, 0.8, 0.8, 1, &baseLine);
cv::Point tlc = cv::Point(box.x, box.y);
cv::Point brc = cv::Point(box.x, box.y + label_size.height + baseLine);
cv::putText(image, label, cv::Point(box.x, box.y), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(0, 255, 255), 1);
}
cv::Mat post_process(cv::Mat& image, std::vector<cv::Mat>& outputs, std::vector<std::string>& class_name)
{
std::vector<int> class_ids;
std::vector<float> confidences;
std::vector<cv::Rect> boxes;
float x_factor = (float)image.cols / INPUT_WIDTH;
float y_factor = (float)image.rows / INPUT_HEIGHT;
float* data = (float*)outputs[0].data;
const int dimensions = 85;
const int rows = 25200;
for (int i = 0; i < rows; ++i)
{
float confidence = data[4];
if (confidence >= CONFIDENCE_THRESHOLD)
{
float* classes_scores = data + 5;
cv::Mat scores(1, class_name.size(), CV_32FC1, classes_scores);
cv::Point class_id;
double max_class_score;
cv::minMaxLoc(scores, 0, &max_class_score, 0, &class_id);
if (max_class_score > SCORE_THRESHOLD)
{
float x = data[0];
float y = data[1];
float w = data[2];
float h = data[3];
int left = int((x - 0.5 * w) * x_factor);
int top = int((y - 0.5 * h) * y_factor);
int width = int(w * x_factor);
int height = int(h * y_factor);
boxes.push_back(cv::Rect(left, top, width, height));
confidences.push_back(confidence);
class_ids.push_back(class_id.x);
}
}
data += dimensions;
}
std::vector<int> indices;
cv::dnn::NMSBoxes(boxes, confidences, SCORE_THRESHOLD, NMS_THRESHOLD, indices);
for (int i = 0; i < indices.size(); i++)
{
int idx = indices[i];
cv::Rect box = boxes[idx];
std::string label = class_name[class_ids[idx]] + ":" + cv::format("%.2f", confidences[idx]);
draw_result(image, label, box);
}
return image;
}
int main()
{
std::vector<std::string> class_name = { "person", "bicycle", "car","motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball" ,"toothbrush" };
std::string line;
//输入一个自己的视频路径,也可以加图片
cv::VideoCapture cap("C:/Users/le/Desktop/ceshi.mp4");
cv::Mat image, blob;
while (cap.read(image))
{
pre_process(image, blob);
cv::dnn::Net net = cv::dnn::readNet("C:/Users/le/Desktop/yolov5/yolov5-cls-det-seg-opencv-main/yolov5n-det.onnx");
std::vector<cv::Mat> detections;
a_process(blob, net, detections);
cv::Mat result = post_process(image, detections, class_name);
cv::imshow("detection", result);
if (waitKey(25) == 27) {
break;
}
}
cap.release();
return 0;
}
The "extern" keyword is a keyword used in C/C++ to declare external variables or functions. It tells the compiler that this variable or function is defined in other files and needs to be used in the current file. Because in C/C++, all variables and functions are internal by default, that is, they can only be used in the current file. If they want to be used in other files, they need to be declared with the extern keyword.
"_declspec(dllexport)" is a keyword specific to the Windows platform, which is used to specify the export function or variable when writing a dynamic link library (DLL). On the windows platform, the functions and variables of the dynamic link library need to be declared with the _declspec(dllexport) keyword, and then exported in the DLL again. Doing so allows other programs to call functions or variables in this DLL.
In short, extern "C" _declspec(dllexport) is a keyword used to define and export functions or variables to the dynamic link library in C/C++ language.
If your video is too large, you can resize it in the code
cv::resize(result, result, cv::Size(680, 560));
After adjusting the code, right-click the project you created, generate or rebuild.
Similar to this means that the creation is successful, and the displayed path is where your dynamic link library is located.
Link: https://pan.baidu.com/s/1HHbGwC62KG1skNc5ocvSXA
Extraction code: rjaz
This is the onnx model in the code
Right click on the solution, add a new project, the entire empty project is fine
Property configuration opencv
The additional include directory in the figure adds the path where the code in the dynamic link library is located (yolo.h and yolo.cpp)
The additional library directory in the figure adds the path where the generated dynamic link library is located
Additional dependencies add the name of the generated lib
#pragma comment(dll,"Dll1.dll") Add your own name to run after generation
Effect
Any questions, comment area