Vs2022 encapsula la biblioteca de enlaces dinámicos Dll para realizar la detección de objetivos (código yolov5 simple)

Tabla de contenido

1. Instalar vs2022

2. Cree un nuevo proyecto de biblioteca de vínculos dinámicos

3. Configure opencv y la configuración de atributos correspondiente

4. Código


1. Instalar vs2022

Use qt para el diseño de interfaz en vs2022, y los dos proyectos de software se comunican entre sí - Blog de Ji Wei - Blog de CSDN

2. Cree un nuevo proyecto de biblioteca de vínculos dinámicos

Haga clic para crear un nuevo proyecto, busque dll para encontrar el nuevo proyecto de la biblioteca de enlaces dinámicos

 

 Cómo se ve después de la creación

3. Configure opencv y la configuración de atributos correspondiente

La premisa es configurar las variables de entorno para opencv por ti mismo.

 Agregue de acuerdo con la ruta opencv que instaló

 Directorio VC++ -> incluir directorio: opencv\build\include\opencv2 y opencv\build\include

 Directorio VC++ -> directorio de la biblioteca: opencv\build\x64\vc15\lib y opencv\build\x64\vc15\bin

 Conector -> Entrada -> Dependencias adicionales: opencv_world460d.lib (con d está ejecutando Debug, sin d es Release)

 CONJUNTO DE CARACTERES A CONJUNTO DE CARACTERES MULTIBYTE

 C/C++->Encabezado precompilado->Encabezado precompilado: Cree (/Yc) en su lugar, cámbielo más tarde según sus propias necesidades o elimine el archivo .h en el archivo de encabezado precompilado

4. Código

Cree archivos de encabezado y fuente con nombres arbitrarios

//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;
}

 La palabra clave "extern" es una palabra clave que se usa en C/C++ para declarar variables o funciones externas. Le dice al compilador que esta variable o función está definida en otros archivos y debe usarse en el archivo actual. Porque en C/C++, todas las variables y funciones son internas por defecto, es decir, solo se pueden usar en el archivo actual, si se quieren usar en otros archivos, deben declararse con la palabra clave extern.

"_declspec(dllexport)" es una palabra clave específica de la plataforma Windows, que se utiliza para especificar la función o variable de exportación al escribir una biblioteca de vínculos dinámicos (DLL). En la plataforma de Windows, las funciones y variables de la biblioteca de vínculos dinámicos deben declararse con la palabra clave _declspec (dllexport) y luego exportarse nuevamente en la DLL. Si lo hace, permite que otros programas llamen a funciones o variables en esta DLL.

En resumen, extern "C" _declspec(dllexport) es una palabra clave utilizada para definir y exportar funciones o variables a la biblioteca de vínculos dinámicos en lenguaje C/C++.

Si su video es demasiado grande, puede cambiar su tamaño en el código

cv::resize(resultado, resultado, cv::Size(680, 560));   

 Después de ajustar el código, haga clic con el botón derecho en el proyecto que creó, generó o reconstruyó.

 Similar a esto significa que la creación es exitosa y la ruta que se muestra es donde se encuentra su biblioteca de vínculos dinámicos.

Enlace: https://pan.baidu.com/s/1HHbGwC62KG1skNc5ocvSXA

Código de extracción: rjaz

Este es el modelo onnx en el código.

 Haga clic derecho en la solución, agregue un nuevo proyecto, todo el proyecto vacío está bien

Configuración de propiedades opencv

El directorio de inclusión adicional en la figura agrega la ruta donde se encuentra el código en la biblioteca de vínculos dinámicos (yolo.h y yolo.cpp)

 

 El directorio de biblioteca adicional en la figura agrega la ruta donde se encuentra la biblioteca de enlace dinámico generada

Las dependencias adicionales agregan el nombre de la librería generada

#pragma comment(dll,"Dll1.dll") Agregue su propio nombre para ejecutar después de la generación

Efecto

Cualquier duda, área de comentarios.

Supongo que te gusta

Origin blog.csdn.net/jifanyyds/article/details/130734098
Recomendado
Clasificación