目录
准备版本:
准备事项:
选择配置界面:
下载界面:
编辑 添加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 image
float ry; // the height ratio of original image and resized image
std::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 box
std::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 text
std::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所在目录: