目录
准备版本:
准备事项:
选择配置界面:
下载界面:
编辑 添加VS配置:
准备代码:
yolov8.h
yolov8.cpp
detect.cpp
如何找到并放置DLL:
准备版本:
opencv 4.6.0
openvino 2024.0.0.14509
准备事项:
V8模型转换: pt to xml
from ultralytics import YOLO# Load a model
model = YOLO("./models\yolov8s.pt") # load an official model# Export the model
model.export(format="openvino")
openvino下载路径:点击跳转
选择配置界面:
下载界面:
添加VS配置:
准备代码:
yolov8.h
#pragma once
#include<string>
#include <iostream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include<openvino/openvino.hpp>
#include <fstream>
#include <vector>
#include <random>struct Config {float confThreshold;float nmsThreshold;float scoreThreshold;int inpWidth;int inpHeight;std::string onnx_path;
};struct Resize
{cv::Mat resized_image;int dw;int dh;
};struct Detection {int class_id;float confidence;cv::Rect box;
};class YOLOV8 {
public:YOLOV8(Config config);~YOLOV8();void detect(cv::Mat& frame);private:float confThreshold;float nmsThreshold;float scoreThreshold;int inpWidth;int inpHeight;float rx; // the width ratio of original image and resized imagefloat ry; // the height ratio of original image and resized imagestd::string onnx_path;Resize resize;ov::Tensor input_tensor;ov::InferRequest infer_request;ov::CompiledModel compiled_model;void initialmodel();void preprocess_img(cv::Mat& frame);void postprocess_img(cv::Mat& frame, float* detections, ov::Shape& output_shape);
};
yolov8.cpp
#include"yolov8.h"
#include<iostream>
#include<string>
#include<time.h>using namespace cv;
using namespace std;
using namespace dnn;const vector<string> coconame = { "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","kite","baseball bat","baseball glove","skateboard","surfboard","tennis racket","bottle","wine glass","cup","fork","knife","spoon","bowl","banana","apple","sandwich","orange","broccoli","carrot","hot dog","pizza","donut","cake","chair","couch","potted plant","bed","dining table","toilet","tv","laptop","mouse","remote","keyboard","cell phone","microwave","oven","toaster","sink","refrigerator","book","clock","vase","scissors","teddy bear","hair drier","toothbrush" };YOLOV8::YOLOV8(Config config) {this->confThreshold = config.confThreshold;this->nmsThreshold = config.nmsThreshold;this->scoreThreshold = config.scoreThreshold;this->inpWidth = config.inpWidth;this->inpHeight = config.inpHeight;this->onnx_path = config.onnx_path;this->initialmodel();}
YOLOV8::~YOLOV8() {}
void YOLOV8::detect(Mat& frame) {preprocess_img(frame);infer_request.infer();const ov::Tensor& output_tensor = infer_request.get_output_tensor();ov::Shape output_shape = output_tensor.get_shape();float* detections = output_tensor.data<float>();this->postprocess_img(frame, detections, output_shape);
}void YOLOV8::initialmodel() {ov::Core core;std::shared_ptr<ov::Model> model = core.read_model(this->onnx_path);ov::preprocess::PrePostProcessor ppp = ov::preprocess::PrePostProcessor(model);ppp.input().tensor().set_element_type(ov::element::u8).set_layout("NHWC").set_color_format(ov::preprocess::ColorFormat::RGB);ppp.input().preprocess().convert_element_type(ov::element::f32).convert_color(ov::preprocess::ColorFormat::RGB).scale({ 255, 255, 255 });// .scale({ 112, 112, 112 });ppp.input().model().set_layout("NCHW");ppp.output().tensor().set_element_type(ov::element::f32);model = ppp.build();this->compiled_model = core.compile_model(model, "CPU");this->infer_request = compiled_model.create_infer_request();
}void YOLOV8::preprocess_img(Mat& frame) {try {float width = frame.cols;float height = frame.rows;cv::Size new_shape = cv::Size(inpWidth, inpHeight);float r = float(new_shape.width / max(width, height));int new_unpadW = int(round(width * r));int new_unpadH = int(round(height * r));cv::resize(frame, resize.resized_image, cv::Size(new_unpadW, new_unpadH), 0, 0, cv::INTER_AREA);resize.dw = new_shape.width - new_unpadW;resize.dh = new_shape.height - new_unpadH;cv::Scalar color = cv::Scalar(100, 100, 100);cv::copyMakeBorder(resize.resized_image, resize.resized_image, 0, resize.dh, 0, resize.dw, cv::BORDER_CONSTANT, color);this->rx = (float)frame.cols / (float)(resize.resized_image.cols - resize.dw);this->ry = (float)frame.rows / (float)(resize.resized_image.rows - resize.dh);float* input_data = (float*)resize.resized_image.data;input_tensor = ov::Tensor(compiled_model.input().get_element_type(), compiled_model.input().get_shape(), input_data);infer_request.set_input_tensor(input_tensor);}catch (const std::exception& e) {std::cerr << "exception: " << e.what() << std::endl;}catch (...) {std::cerr << "unknown exception" << std::endl;}}void YOLOV8::postprocess_img(Mat& frame, float* detections, ov::Shape& output_shape) {std::vector<cv::Rect> boxes;vector<int> class_ids;vector<float> confidences;int out_rows = output_shape[1];int out_cols = output_shape[2];const cv::Mat det_output(out_rows, out_cols, CV_32F, (float*)detections);for (int i = 0; i < det_output.cols; ++i) {const cv::Mat classes_scores = det_output.col(i).rowRange(4, 84);cv::Point class_id_point;double score;cv::minMaxLoc(classes_scores, nullptr, &score, nullptr, &class_id_point);if (score > 0.3) {const float cx = det_output.at<float>(0, i);const float cy = det_output.at<float>(1, i);const float ow = det_output.at<float>(2, i);const float oh = det_output.at<float>(3, i);cv::Rect box;box.x = static_cast<int>((cx - 0.5 * ow));box.y = static_cast<int>((cy - 0.5 * oh));box.width = static_cast<int>(ow);box.height = static_cast<int>(oh);boxes.push_back(box);class_ids.push_back(class_id_point.y);confidences.push_back(score);}}std::vector<int> nms_result;cv::dnn::NMSBoxes(boxes, confidences, this->scoreThreshold, this->nmsThreshold, nms_result);std::vector<Detection> output;for (int i = 0; i < nms_result.size(); i++){Detection result;int idx = nms_result[i];result.class_id = class_ids[idx];result.confidence = confidences[idx];result.box = boxes[idx];output.push_back(result);}cout << "output_size:" << output.size() << endl;for (int i = 0; i < output.size(); i++){auto detection = output[i];auto box = detection.box;auto classId = detection.class_id;// if (classId != 0) continue;auto confidence = detection.confidence;box.x = this->rx * box.x;box.y = this->ry * box.y;box.width = this->rx * box.width;box.height = this->ry * box.height;float xmax = box.x + box.width;float ymax = box.y + box.height;// detection boxstd::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<int> dis(100, 255);cv::Scalar color = cv::Scalar(dis(gen),dis(gen),dis(gen));cv::rectangle(frame, cv::Point(box.x, box.y), cv::Point(xmax, ymax), color, 3);// Detection box textstd::string classString = coconame[classId] + ' ' + std::to_string(confidence).substr(0, 4);cv::Size textSize = cv::getTextSize(classString, cv::FONT_HERSHEY_DUPLEX, 1, 2, 0);cv::Rect textBox(box.x, box.y - 40, textSize.width + 10, textSize.height + 20);cv::rectangle(frame, textBox, color, cv::FILLED);cv::putText(frame, classString, cv::Point(box.x + 5, box.y - 10), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 0, 0), 2, 0);// cv::rectangle(frame, cv::Point(box.x, box.y - 20), cv::Point(xmax, box.y), cv::Scalar(0, 255, 0), cv::FILLED);// cv::putText(frame, coconame[classId], cv::Point(box.x, box.y - 5), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));}
}
detect.cpp
# include"yolov8.h"int main(int argc, char* argv[]) {try {//if (argc != 3) {// std::cout << "Usage:" << argv[0] << " <path_to_model> <path_to_image>" << std::endl;// return EXIT_FAILURE;//}//const std::string input_model_path{ argv[1] };//const std::string input_image_path{ argv[2] };std::string input_model_path = "E:\\yoloV8\\ultralytics-main\\models\\yolov8s_openvino_model\\yolov8s.xml";std::string input_image_path = "E:\\yoloV8\\ultralytics-main\\ultralytics\\assets\\bus.jpg";Config config = { 0.2,0.4,0.4,640,640, input_model_path };clock_t start, end;cv::Mat img = cv::imread(input_image_path);YOLOV8 yolomodel(config);start = clock();yolomodel.detect(img);end = clock();std::cout << "infer time = " << double(end - start) / CLOCKS_PER_SEC << "s" << std::endl;cv::imwrite("./result.jpg", img);}catch (const std::exception& ex) {std::cerr << ex.what() << std::endl;return EXIT_FAILURE;}return EXIT_SUCCESS;}
如何找到并放置DLL:
为了防止程序运行缺少dll 可以把dll全部拷贝到程序输出所在目录里 也就是exe所在目录
dll所在目录: