Windows C++ VS2022 OpenVINO 物体检测 Demo

news2024/11/25 12:53:43

准备工作:

1、下载opencv

地址:Releases - OpenCV

我下载的是opencv-4.5.5,存放的路径为:

2、下载OpenVino

地址:https://storage.openvinotoolkit.org/repositories/openvino/packages/2023.0.1/

我存放的路径为:

  • C++预处理器所需的头文件:include文件夹
  • C++链接器所需的lib文件:lib文件夹
  • 可执行文件(*.exe)所需的动态链接库文件:bin文件夹
  • OpenVINO runtime第三方依赖库文件:3rdparty文件夹

 新建项目

main.cpp代码 如下:

#include <iostream>
#include <string>
#include <vector>
#include <openvino/openvino.hpp> //openvino header file
#include <opencv2/opencv.hpp>    //opencv header file
#include  <direct.h>  
#include  <stdio.h> 
#include <time.h> 

std::vector<cv::Scalar> colors = { cv::Scalar(0, 0, 255) , cv::Scalar(0, 255, 0) , cv::Scalar(255, 0, 0) ,
								   cv::Scalar(255, 100, 50) , cv::Scalar(50, 100, 255) , cv::Scalar(255, 50, 100) };

const std::vector<std::string> class_names = {
	"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" };

using namespace cv;
using namespace dnn;

// Keep the ratio before resize
Mat letterbox(const cv::Mat& source)
{
	int col = source.cols;
	int row = source.rows;
	int _max = MAX(col, row);
	Mat result = Mat::zeros(_max, _max, CV_8UC3);
	source.copyTo(result(Rect(0, 0, col, row)));
	return result;
}

int main()
{
	clock_t start, end;//定义clock_t变量
	std::cout << "共8步" << std::endl;

	char   buffer[100];
	_getcwd(buffer, 100);
	std::cout << "当前路径:" << buffer << std::endl;

	// -------- Step 1. Initialize OpenVINO Runtime Core --------
	std::cout << "1. Initialize OpenVINO Runtime Core" << std::endl;
	ov::Core core;

	// -------- Step 2. Compile the Model --------
	std::cout << "2. Compile the Model" << std::endl;
	String model_path = String(buffer) + "\\yolov8s.xml";
	std::cout << "model_path:\t" << model_path << std::endl;
	ov::CompiledModel compiled_model;
	try {
		compiled_model = core.compile_model(model_path, "CPU");
	}
	catch (std::exception& e) {
		std::cout << "Compile the Model 异常:" << e.what() << std::endl;
		return 0;
	}
	//auto compiled_model = core.compile_model("C:\\MyPro\\yolov8\\yolov8s.xml", "CPU");


	// -------- Step 3. Create an Inference Request --------
	std::cout << "3. Create an Inference Request" << std::endl;
	ov::InferRequest infer_request = compiled_model.create_infer_request();


	// -------- Step 4.Read a picture file and do the preprocess --------
	std::cout << "4.Read a picture file and do the preprocess" << std::endl;
	String img_path = String(buffer) + "\\test.jpg";
	std::cout << "img_path:\t" << img_path << std::endl;
	Mat img = cv::imread(img_path);


	// Preprocess the image
	Mat letterbox_img = letterbox(img);
	float scale = letterbox_img.size[0] / 640.0;
	Mat blob = blobFromImage(letterbox_img, 1.0 / 255.0, Size(640, 640), Scalar(), true);

	// -------- Step 5. Feed the blob into the input node of the Model -------
	std::cout << "5. Feed the blob into the input node of the Model" << std::endl;
	// Get input port for model with one input
	auto input_port = compiled_model.input();
	// Create tensor from external memory
	ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), blob.ptr(0));
	// Set input tensor for model with one input
	infer_request.set_input_tensor(input_tensor);

	start = clock();//开始时间
	// -------- Step 6. Start inference --------
	std::cout << "6. Start inference" << std::endl;
	infer_request.infer();
	end = clock();//结束时间
	std::cout << "inference time = " << double(end - start) << "ms" << std::endl;

	// -------- Step 7. Get the inference result --------
	std::cout << "7. Get the inference result" << std::endl;
	auto output = infer_request.get_output_tensor(0);
	auto output_shape = output.get_shape();
	std::cout << "The shape of output tensor:\t" << output_shape << std::endl;
	int rows = output_shape[2];        //8400
	int dimensions = output_shape[1];  //84: box[cx, cy, w, h]+80 classes scores

	std::cout << "8. Postprocess the result " << std::endl;
	// -------- Step 8. Postprocess the result --------
	float* data = output.data<float>();
	Mat output_buffer(output_shape[1], output_shape[2], CV_32F, data);
	transpose(output_buffer, output_buffer); //[8400,84]
	float score_threshold = 0.25;
	float nms_threshold = 0.5;
	std::vector<int> class_ids;
	std::vector<float> class_scores;
	std::vector<Rect> boxes;

	// Figure out the bbox, class_id and class_score
	for (int i = 0; i < output_buffer.rows; i++) {
		Mat classes_scores = output_buffer.row(i).colRange(4, 84);
		Point class_id;
		double maxClassScore;
		minMaxLoc(classes_scores, 0, &maxClassScore, 0, &class_id);

		if (maxClassScore > score_threshold) {
			class_scores.push_back(maxClassScore);
			class_ids.push_back(class_id.x);
			float cx = output_buffer.at<float>(i, 0);
			float cy = output_buffer.at<float>(i, 1);
			float w = output_buffer.at<float>(i, 2);
			float h = output_buffer.at<float>(i, 3);

			int left = int((cx - 0.5 * w) * scale);
			int top = int((cy - 0.5 * h) * scale);
			int width = int(w * scale);
			int height = int(h * scale);

			boxes.push_back(Rect(left, top, width, height));
		}
	}
	//NMS
	std::vector<int> indices;
	NMSBoxes(boxes, class_scores, score_threshold, nms_threshold, indices);

	// -------- Visualize the detection results -----------
	for (size_t i = 0; i < indices.size(); i++) {
		int index = indices[i];
		int class_id = class_ids[index];
		rectangle(img, boxes[index], colors[class_id % 6], 2, 8);
		std::string label = class_names[class_id] + ":" + std::to_string(class_scores[index]).substr(0, 4);
		Size textSize = cv::getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, 0);
		Rect textBox(boxes[index].tl().x, boxes[index].tl().y - 15, textSize.width, textSize.height + 5);
		cv::rectangle(img, textBox, colors[class_id % 6], FILLED);
		putText(img, label, Point(boxes[index].tl().x, boxes[index].tl().y - 5), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255));
	}

	//namedWindow("YOLOv8 OpenVINO Inference C++ Demo", WINDOW_AUTOSIZE);
	//imshow("YOLOv8 OpenVINO Inference C++ Demo", img);
	//waitKey(0);
	//destroyAllWindows();

	cv::imwrite("detection.png", img);
	std::cout << "detect success" << std::endl;

	system("pause");

	return 0;
}

我们直接使用 Release

设置包含目录和库目录

包含目录:

C:\Program Files\opencv-4.5.5\build\include;
C:\Program Files\opencv-4.5.5\build\include\opencv2;
C:\Program Files\openvino_2023.0.1.11005\runtime\include;
C:\Program Files\openvino_2023.0.1.11005\runtime\include\ie;

库目录

C:\Program Files\opencv-4.5.5\build\x64\vc15\lib;
C:\Program Files\openvino_2023.0.1.11005\runtime\lib\intel64\Release;

 添加附加依赖项

openvino.lib
opencv_world455.lib

生成

 配置环境变量

或者复制Opencv和OpenVino的DLL到 C:\yolov8_det_openvino\x64\Release

复制测试图片和模型

运行exe

效果

 代码参考:GitHub - openvino-book/yolov8_openvino_cpp: YOLOv8 Inference C++ sample code based on OpenVINO C++ API

 

exe程序下载 

 

Demo下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1004058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝牙运动耳机哪款好用、最好用的运动耳机推荐

运动耳机现如今可谓是备受热捧的运动潮流单品&#xff0c;消费者对于耳机的需求实际上非常多元化。一款出色的运动耳机不仅要满足基本的运动需求&#xff0c;还需要具备丰富的使用功能&#xff0c;这直接决定了耳机的附加价值。接下来&#xff0c;我将向大家推荐5款佩戴舒适、牢…

HarmonyOS应用开发—资源分类与访问

应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同的设备或配置中的表…

idea装载jerbel以及文件上传下载

一、JRebel 1.1 Jrebel介绍 JRebel是一个Java开发工具&#xff0c;它是一款用于实时代码重载的插件。它的主要功能是在不重新启动应用程序的情况下&#xff0c;将修改后的Java代码实时应用到正在运行的应用程序中&#xff0c;从而加快开发周期&#xff0c;提高开发效率。 实…

算法通关村第十九关:青铜-动态规划是怎么回事

青铜挑战-动态规划是怎么回事 动态规划&#xff08;简称DP&#xff0c;Dynamic Programming&#xff09;&#xff1a;最热门、最重要的算法之一。面试中大量出现&#xff0c;整体偏难。 1. 热身&#xff1a;重复计算和记忆化搜索&#xff08;如何说一万次"我爱你"&…

Windows驱动开发(一)

1. 引言 很难为术语 “驱动程序”提供一个精确的定义。 就最基本的意义而言&#xff0c;驱动程序是一个软件组件&#xff0c;可让操作系统和设备彼此通信。 例如&#xff0c;假设应用程序需要从设备中读取某些数据。 应用程序会调用由操作系统实现的函数&#xff0c;操作系统…

WPF——Control与Template理解

文章目录 一、前言二、控件三、模板3.1 DataTemplate3.2 ControlTemplate3.3 ContentPresenter 四、结语 一、前言 最近又翻看了下刘铁猛的《深入浅出WPF》&#xff0c;发现对模板章节中的部分内容有了更深的体会&#xff0c;所以写篇文扯扯。 文章标题是Control与Template&a…

画流程图用什么软件好?安利这几款

画流程图用什么软件好&#xff1f;画流程图是一项非常重要的技能&#xff0c;它可以帮助我们更好地规划和管理工作流程&#xff0c;提高工作效率。在现代的企业中&#xff0c;流程图已经成为了不可或缺的一部分&#xff0c;它可以用来描述各种业务流程、流程控制、组织结构等等…

数据治理实战步骤

写在前面:数据治理是数字化转型的基础,是数字要素流通的首要任务。但是面对不同的情况,数据治理的手段不同。 数据治理专员要转换思想,数据治理中单靠技术、软件是不行的,比如一些单位认为数据治理平台是万能的,直接上平台一般是做不好的,需基于企业的组织文化、愿景等对…

vue全局使用sass变量

需求&#xff1a;框架需要使用scss&#xff0c;之后不想把很多重复的css一个一个写&#xff0c;就提取出来咯&#xff0c;到时候只需要更改scss文件就可以了&#xff0c;不用一个一个的找 1.下载sass 这我下的俩个版本&#xff0c;如果你们下载最新版不兼容可以参考我的版本下…

高效办公利器:批量重命名与翻译文件名一步到位

在我们的日常工作中&#xff0c;我们经常需要处理大量的文件&#xff0c;包括图片、文档、视频等各种类型。有时候&#xff0c;我们需要对文件进行重命名或者翻译&#xff0c;以便于我们更方便地管理和使用这些文件。但是&#xff0c;如果一个一个手动操作&#xff0c;将是非常…

《树莓派4B家庭服务器搭建指南》第二十一期:安装开源远程桌面服务rustdesk, 内网丝滑,外网流畅控制

title: 《树莓派4B家庭服务器搭建指南》第二十一期&#xff1a;安装开源远程桌面服务rustdesk, 内网丝滑,外网流畅控制Windows,macOS,Linux设备 tags: 个人成长 categories:树莓派不吃灰 前段时间, 有一台老式MacBook Pro被我改造成了影视资源解码主机, 《树莓派4B家庭服务器搭…

老师怎样发布查询

作为一名老师&#xff0c;我们经常需要向家长发布各种查询&#xff0c;比如成绩查询、作业查询等。以往&#xff0c;我们可能会将查询结果整理成Excel表格&#xff0c;然后通过各种渠道发送给家长&#xff0c;这样既繁琐又不够高效。幸好&#xff0c;现在有了易查分&#xff0c…

MybatisPlus(4)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 在之前我们讲解了大部分查询相关的操作&#xff0c;接下来进行增删改的学…

SpringBoot项目--电脑商城【增加/减少购物车商品数量】

1.持久层[Mapper] 1.1规划需要执行的SQL语句 1.更新该商品的数量.此SQL语句无需重复开发 update t_cart set num?,modified_user?,modified_time? where cid? 2.首先进行查询需要操作的购物车数据信息【查看该条数据是否存在】 SELECT * FROM t_cart WHERE cid?2.接口…

如何解决实时语音通讯技术的延迟问题?

实时语音通讯技术的延迟问题一直是人们关注的焦点。在实时通讯中&#xff0c;延迟会影响到通话的质量和用户体验&#xff0c;因此如何解决实时语音通讯技术的延迟问题是一个重要的挑战。本文将探讨如何解决实时语音通讯技术的延迟问题。 一、延迟的定义和分类 延迟是指从说话…

C语言和汇编到底谁更厉害呢?

今日话题&#xff0c;C语言和汇编到底谁更厉害呢&#xff1f; 有位毕业生与我分享了他的经历。在学校&#xff0c;他学习了汇编和C语言。毕业后&#xff0c;他加入了一家嵌入式企业&#xff0c;发现C语言因其可移植性、开发效率和可读性而更为通用和适用。事实证明&#xff0c;…

排序算法-----冒泡排序与选择排序

目录 前言: 冒泡排序 原理图 代码实现 分析总结 选择排序 原理图 代码实现 分析总结 前言: 今天我们就开始学习排序算法&#xff0c;排序算法也是数据结构与算法在重要组成部分之一&#xff0c;排序算法是最经典的算法知识。因为其实现代码短&#xff0c;应该广&#x…

【设计模式】桥接模式在开发中的应用

1. 概述 桥接模式是一个非常简单的设计模式&#xff0c;可能大家在开发的过程中已经使用到了这种模式而不自知。总的来说&#xff0c;桥接模式最大的作用就是解耦&#xff0c;所谓的解耦&#xff0c;就是通过转换代码的设计&#xff0c;减少类与类&#xff0c;模块与模块之间的…

监听器,过滤器,拦截器

参考博文 文章目录 作用三者区别启动顺序拦截器简要说明实现接口HandlerInterceptor自定义拦截器配置拦截器 过滤器简要说明在springboot 启动类添加该注解ServletComponentScan写个过滤器类&#xff0c;实现Filter接口 监听器简要说明如何使用自定义事件自定义过滤器接口调用…

图片怎么转换成pdf格式?几种方法轻松转换

图片怎么转换成pdf格式&#xff1f;将图片转换成PDF格式的主要原因是方便共享和存储。PDF格式可以在不同的设备和操作系统上轻松打开和查看&#xff0c;而且可以保持原始图片的质量和分辨率。如果你需要将一些图片转换成PDF格式&#xff0c;你可能会问&#xff0c;“该如何做呢…