Vs2022 encapsulates Dll dynamic link library to realize target detection (simple yolov5 code)

Table of contents

1. Install vs2022

2. Create a new dynamic link library project

3. Configure opencv, and the corresponding attribute configuration

4. Code


1. Install vs2022

Use qt for interface design in vs2022, and the two software projects communicate with each other - Ji Wei's Blog - CSDN Blog

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

Guess you like

Origin blog.csdn.net/jifanyyds/article/details/130734098