win10系统下使用openvino部署yolov5模型

news2025/2/23 23:02:12

文章目录

  • 前言
  • 一、环境
    • 1、硬件
    • 2、软件
  • 二、YOLO模型
  • 三、新建Qt项目
    • 1、pro文件
    • 2、main.cpp
  • 四、效果
  • 五、后记


前言

  上一篇介绍过使用onnxruntime实现模型推理部署,但在我的机器上视频效果仍不理想,本篇介绍使用openvino完成模型推理部署。
  openvino是Intel开发的深度学习模型推理加速引擎,支持python和C++,使用起来比较方便。

一、环境

1、硬件

Intel® Core i5-7400 CPU @ 3.00GHZ
Intel® HD Graphics 630 内存4G 核显
内存 8G
win10 64位系统

2、软件

opencv4.6.0
yolov5 6.2版本
qt5.6.2
openvino_2022.1.0.643 runtime版本(关于安装自行谷歌。。。)

二、YOLO模型

我使用的是onnx模型,如果没有训练过自己的模型,可以使用官方的yolov5s.pt模型,将其转化为yolov5s.onnx模型,转化方法如下:

python export.py

在yolov5-master目录下,可以看到yolov5s.onnx模型已生成。

三、新建Qt项目

1、pro文件

在pro文件中,添加opencv相关配置,内容如下:

#-------------------------------------------------
#
# Project created by QtCreator 2022-10-31T09:37:31
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = yolov5-openvino-cpp
TEMPLATE = app

CONFIG += C++11

#CONFIG(debug, debug|release){
#    DESTDIR = ../out
#}
#else {
#    DESTDIR = ../out
#}

SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

INCLUDEPATH += C:/opencv4.6.0/build/include
               C:/opencv4.6.0/build/include/opencv2
LIBS += -LC:/opencv4.6.0/build/x64/vc14/lib/ -lopencv_world460

INCLUDEPATH += C:/onnxruntime-win-x64-1.11.1/include
LIBS += -LC:/onnxruntime-win-x64-1.11.1/lib/ -lonnxruntime

INCLUDEPATH += 'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/include'
               'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/include/ie'
               'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/include/ngraph'
               'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/include/openvino'

LIBS += -L'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/lib/intel64/Release/' -lopenvino
LIBS += -L'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/lib/intel64/Release/' -lopenvino_c
LIBS += -L'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/lib/intel64/Release/' -lopenvino_ir_frontend
LIBS += -L'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/lib/intel64/Release/' -lopenvino_onnx_frontend
LIBS += -L'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/lib/intel64/Release/' -lopenvino_paddle_frontend
LIBS += -L'C:/Program Files (x86)/Intel/openvino_2022.1.0.643/runtime/lib/intel64/Release/' -lopenvino_tensorflow_fe

2、main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <fstream>
#include <iostream>
#include <sstream>
#include <opencv2\opencv.hpp>
#include <openvino\openvino.hpp>

using namespace std;
using namespace ov;
using namespace cv;

//数据集的标签 官方模型yolov5s.onnx为80种
vector<string> class_names = {"person", "bicycle", "car", "motorbike", "aeroplane", "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", "sofa", "pottedplant", "bed", "diningtable", "toilet", "tvmonitor", "laptop", "mouse","remote",
                              "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"};


//模型文件路径
string ir_filename = "G:/yolov5s.onnx";


/*@brief 对网络的输入为图片数据的节点进行赋值,实现图片数据输入网络
 @param input_tensor 输入节点的tensor
 @param inpt_image 输入图片数据
*/
void fill_tensor_data_image(ov::Tensor& input_tensor, const cv::Mat& input_image)
{
    // 获取输入节点要求的输入图片数据的大小
    ov::Shape tensor_shape = input_tensor.get_shape();
    const size_t width = tensor_shape[3]; // 要求输入图片数据的宽度
    const size_t height = tensor_shape[2]; // 要求输入图片数据的高度
    const size_t channels = tensor_shape[1]; // 要求输入图片数据的维度
    // 读取节点数据内存指针
    float* input_tensor_data = input_tensor.data<float>();
    // 将图片数据填充到网络中
    // 原有图片数据为 H、W、C 格式,输入要求的为 C、H、W 格式
    for (size_t c = 0; c < channels; c++)
    {
        for (size_t h = 0; h < height; h++)
        {
            for (size_t w = 0; w < width; w++)
            {
                input_tensor_data[c * width * height + h * width + w] = input_image.at<cv::Vec<float, 3>>(h, w)[c];
            }
        }
    }
}

int main(int argc, char *argv[])
{
    ov::Core ie;
    ov::CompiledModel compiled_model = ie.compile_model(ir_filename, "AUTO");//AUTO  GPU CPU
    ov::InferRequest infer_request = compiled_model.create_infer_request();
    // 预处理输入数据 - 格式化操作
    cv::VideoCapture cap("G:/1.mp4");//
    //VideoCapture cap;
    if (!cap.isOpened())
    {
        std::cerr << "Error opening video file\n";
        return -1;
    }
    // 获取输入节点tensor
    Tensor input_image_tensor = infer_request.get_tensor("images");
    int input_h = input_image_tensor.get_shape()[2]; //获得"images"节点的Height
    int input_w = input_image_tensor.get_shape()[3]; //获得"images"节点的Width
    //int input_c = input_image_tensor.get_shape()[1]; //获得"images"节点的channel
    cout << "input_h:" << input_h << "; input_w:" << input_w << endl;
    cout << "input_image_tensor's element type:" << input_image_tensor.get_element_type() << endl;
    cout << "input_image_tensor's shape:" << input_image_tensor.get_shape() << endl;
    // 获取输出节点tensor
    Tensor output_tensor = infer_request.get_tensor("output");
    int out_rows = output_tensor.get_shape()[1]; //获得"output"节点的out_rows
    int out_cols = output_tensor.get_shape()[2]; //获得"output"节点的Width
    cout << "out_cols:" << out_cols << "; out_rows:" << out_rows << endl;
    //
    Mat frame;
    //连续采集处理循环
    while (true)
    {
        cap.read(frame);
        if (frame.empty())
        {
            std::cout << "End of stream\n";
            break;
        }
        //imshow("frame", frame);
        int64 start = cv::getTickCount();
        // 图像预处理 视频分辨率
        int w = frame.cols;
        int h = frame.rows;
        //qDebug()<<"w ="<<w<<"h ="<<h;
        int _max = std::max(h, w);
        cv::Mat image = cv::Mat::zeros(cv::Size(_max, _max), CV_8UC3);
        cv::Rect roi(0, 0, w, h);
        frame.copyTo(image(roi));
        cvtColor(image, image, COLOR_BGR2RGB); //交换RB通道
        //qDebug()<<"image cols ="<<image.cols<<"image rows"<<image.rows
        //       <<"input_w ="<<input_w<<"input_h ="<<input_h;
        float x_factor = image.cols / input_w;
        float y_factor = image.rows / input_h;

        cv::Mat blob_image;
        cv::resize(image, blob_image, cv::Size(input_w, input_h));
        //cv::cvtColor(blob_image, blob_image, cv::COLOR_BGR2RGB);
        blob_image.convertTo(blob_image, CV_32F);
        blob_image = blob_image / 255.0;
        // 将图片数据填充到tensor数据内存中
        fill_tensor_data_image(input_image_tensor, blob_image);
        // 执行推理计算
        infer_request.infer();
        // 获得推理结果
        const ov::Tensor& output_tensor = infer_request.get_tensor("output");
        // 解析推理结果,YOLOv5 output format: cx,cy,w,h,score
        cv::Mat det_output(out_rows, out_cols, CV_32F, (float*)output_tensor.data());
        //
        vector<cv::Rect> boxes;
        vector<int> classIds;
        vector<float> confidences;

        for (int i = 0; i < det_output.rows; i++)
        {
            float confidence = det_output.at<float>(i, 4);
            //qDebug()<<"confidence ="<<confidence;
            if (confidence < 0.4)
            {
                continue;
            }
            //官方模型为85
            cv::Mat classes_scores = det_output.row(i).colRange(5, 85);
            cv::Point classIdPoint;
            double score;
            cv::minMaxLoc(classes_scores, 0, &score, 0, &classIdPoint);
            // 置信度 0~1之间
            //qDebug()<<"score ="<<score;
            if (score > 0.8)//0.65
            {
                float cx = det_output.at<float>(i, 0);
                float cy = det_output.at<float>(i, 1);
                float ow = det_output.at<float>(i, 2);
                float oh = det_output.at<float>(i, 3);
                int x = static_cast<int>((cx - 0.5 * ow) * x_factor);
                int y = static_cast<int>((cy - 0.5 * oh) * y_factor);
                int width = static_cast<int>(ow * x_factor);
                int height = static_cast<int>(oh * y_factor);
                //qDebug()<<"cx ="<<cx<<"cy ="<<cy
                //       <<"ow ="<<ow<<"oh ="<<oh
                //      <<"x ="<<x<<"y ="<<y
                //     <<"width ="<<width<<"height ="<<height;
                //
                cv::Rect box;
                box.x = x;
                box.y = y;
                box.width = width;
                box.height = height;

                boxes.push_back(box);
                classIds.push_back(classIdPoint.x);
                confidences.push_back(score);
            }
        }
        // NMS
        vector<int> indexes;
        cv::dnn::NMSBoxes(boxes, confidences, 0.25, 0.45, indexes);
        for (size_t i = 0; i < indexes.size(); i++)
        {
            int index = indexes[i];
            int idx = classIds[index];
            float iscore = confidences[index];
            //
            cv::rectangle(frame, boxes[index], cv::Scalar(0, 0, 255), 2, 8);
            cv::rectangle(frame, cv::Point(boxes[index].tl().x, boxes[index].tl().y - 20),
                cv::Point(boxes[index].br().x, boxes[index].tl().y), cv::Scalar(0, 255, 255), -1);
            //
            String nameText = class_names[idx];
            nameText.append(to_string(iscore));
            cv::putText(frame, nameText/*class_names[idx]*/, cv::Point(boxes[index].tl().x, boxes[index].tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .5, cv::Scalar(0, 0, 0));
            //目标中心点
            Point2f point(boxes[index].x + boxes[index].width/2,boxes[index].y + boxes[index].height/2);
            circle(frame, point, 3, Scalar(0, 255, 0), -1);
            //
            String posText = "x:";
            posText.append(to_string(boxes[index].x + + boxes[index].width/2));
            posText.append(",");
            posText.append("y:");
            posText.append(to_string(boxes[index].y + + boxes[index].height/2));
            //qDebug()<<QString::fromStdString(posText);
            cv::putText(frame, posText, point, cv::FONT_HERSHEY_SIMPLEX, .8, cv::Scalar(255, 255, 255));
        }
        // 计算FPS render it
        float t = (cv::getTickCount() - start) / static_cast<float>(cv::getTickFrequency());
        //cout << "Infer time(ms): " << t * 1000 << "ms; Detections: " << indexes.size() << endl;
        putText(frame, cv::format("FPS: %.2f", 1.0 / t), cv::Point(20, 40), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 0, 0), 2, 8);
        cv::namedWindow("YOLOv5-6.2 + OpenVINO 2022.1 C++ Demo",0);
        cv::imshow("YOLOv5-6.2 + OpenVINO 2022.1 C++ Demo", frame);

        char c = cv::waitKey(1);
        if (c == 27)
        {
            // ESC
            break;
        }
    }

    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

四、效果

  以本地视频文件1.mp4为例,效果如下:
在这里插入图片描述
  可以看到FPS获得较大提升,视频流明显比之前效果要好。

五、后记

  以上代码是基于qt5.6.2 编译的64位程序,32位编译不通过,貌似需要自己编译openvino 32bit版本。我尝试编译过openvino 32bit,但部分库编译失败,该qt demo运行失败。如果有博主编译成功该版本openvino 32bit,辛苦告知一下,万分感谢!!!

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

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

相关文章

Windows OpenGL ES 图像透明度

目录 一.OpenGL ES 图像透明度 1.原始图片2.效果演示 二.OpenGL ES 图像透明度源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 Open…

linux下gcc编程11-window下clion编译调试nginx+集成lua-nginx-module+安装开源x-waf

nginx模块 nginx作为项目的7层代理入口&#xff0c;对于http请求的过滤&#xff0c;如sql注入&#xff0c;xss攻击等过滤功能较弱&#xff0c;研究了下开源的一些waf&#xff0c;完全开源的https://github.com/xsec-lab/x-waf&#xff0c;利用lua来过滤请求&#xff0c;同时拥…

TuckER 论文笔记

Modeling Relation Paths for Representation Learning of Knowledge Bases- Introduction- Background- Algorithm- Experiment- Conclusion- CodeIvana Balazevic, Carl Allen, Timothy M.Hospedales - Introduction TuckERuckER是一个相对简单但功能强大的线性模型&#xf…

网络营销中 SEO 的作用

与其有时间去阅读各种SEO知识&#xff0c;不如多做一些实际的测试和练习。在百度官方发布的网页质量白皮书中&#xff0c;其实重点介绍了网页速度对SEO优化的影响&#xff0c;前面也出现了一种叫做闪电算法的算法&#xff0c;对于移动排名1.5秒内加载首屏即可打开的网页&#x…

2022亚马逊云科技re:Invent科创风尚,抢占下一个万亿赛道

新风向&#xff1a;重塑科技创投格局 面向未来增长&#xff0c;聚焦投资风向&#xff0c;演绎全新技术。11月28日至12月2日&#xff0c;2022亚马逊云科技re:Invent即将重磅来袭&#xff0c;在美国拉斯维加斯再度盛启。改变世界的全新云技术、不同领域的优选实践&#xff0c;都…

【仿真建模】第一课:AnyLogic入门基础教程 - 行人库入门讲解

文章目录一、AnyLogic介绍二、设置2.1 设置中文三、新建项目四、行人库介绍五、创建新行人六、切换3D视角七、增加墙八、行人密度图一、AnyLogic介绍 二、设置 2.1 设置中文 三、新建项目 四、行人库介绍 点击面板&#xff0c;选择第三个图标&#xff0c;就是行人库 行人库分…

react--编程式导航、antd的使用

编程式 1. 借助路由对象中的history 获取&#xff1a; this.props.history.push(/xx/xx) | this.props.history.replace(/xx/xx) 2. 传递sreach参数 this.props.history.push(/xx/xx?xxx100&xx111) 3. 传state参数 this.props.history.push(/xx,{id:1,title:…

web前端期末大作业 HTML+CSS+JavaScript仿唯品会购物商城网页设计实例 企业网站制作

常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他等网页设计题目, A…

ISO 5659-2塑料 烟生成 第2 部分:单室法测定烟密度试验方法

本标准适用于测定塑料燃烧时所产生烟雾的比光密度&#xff0c;并以最大比光密度为试验结果。它用于评定在规定条件下塑料的发烟性能。 ISO5659-2 建筑材料阻燃防火测试-标准名称&#xff1a; ISO 5659-2: 塑料&#xff0d;生烟性测定&#xff0d;第2部分&#xff1a;单烟箱光…

echarts看板效果图:流光折线图、3d柱状图、3d饼图

前言 现在展厅的大看板是越花里胡哨越好,不过真的挺难做的。好在可以百度找到一些大神的作品进行参考。 下面的内容都是基于echarts 5.3.3 和 vue3 。另外demo都是参考别人的案例。 流光折线图 效果图 代码 <template><div id="demo"></div&g…

从零开始学JAVA(01):配置Java运行环境、实现HelloWorld

一、下载安装JDK 1、下载安装 Oracle | Cloud Applications and Cloud Platform 2、验证&#xff08;控制太输入java、java-version、javac&#xff09; 二、 实现HelloWorld 1、下载 Sublime Text Sublime Text - Text Editing, Done Right 2、编写HelloWorld.java文件 …

数据恢复方法有哪些?如何恢复误删照片

数据恢复方法有哪些&#xff1f;电脑文件数据的误删除&#xff0c;基本每个人都遇到过。当我们还是一个电脑小白的时候&#xff0c;说实话这是非常让人崩溃的事情&#xff0c;不过不用担心&#xff0c;今天小编就以自己的亲身经历告诉大家几种比较好用的数据恢复方法。 删除的文…

PyTorch深度学习基础之Tensor对象及其应用的讲解及实战(附源码 简单易懂 包括分段 映射 矩阵乘法 随机数等等)

觉得有帮助请点赞关注收藏 有问题可评论区留言~~~ Tensor对象是一个维度任意的矩阵&#xff0c;但是一个Tensor中所有元素的数据类型必须一致。torch包含的数据类型和普遍编程语言的数据类型类似&#xff0c;包含浮点型&#xff0c;有符号整型和无符号整形&#xff0c;这些类型…

typora免费安装版教程,支持Windows、Mac、Linux

大家好&#xff0c;我是可乐&#xff0c;本篇文章为大家介绍 Typora快捷键、Typora免费安装教程。 Typora是一款简单易用的Markdown编辑器。 目前 Typora 官方是不提供免费版下载了&#xff0c;需要一次性购买版权&#xff0c;支持正版的可以直接前往官网购买&#xff0c;89 …

深圳CPDA认证|学数据分析,其实就是寻找数据背后的规律

现如今&#xff0c;我们正处在一个互联网发展的时代&#xff0c;大大小小的企业对于数据分析相关岗位的需求正开始逐渐增加&#xff0c;因为所有的企业都有数据&#xff0c;企业需要让数据分析师通过整理、分析企业数据总结出企业目前的发展现状&#xff0c;并且也要为企业做出…

【c++】虚函数,纯虚函数,抽象类

这里写目录标题虚函数纯虚函数抽象类为什么抽象类不能创建对象&#xff1f;注意点&#xff1a;接口类如何设计虚析构总结&#xff1a;构造函数为什么不能是虚函数有虚函数的对象创建过程虚函数 虚函数&#xff1a;给成员函数前面加上virtual关键字。 1.派生类中定义虚函数必须…

RS485电工详解

串口数据帧我们学过&#xff0c;但到RS485是不是就卡壳了&#xff1f; 空闲状态&#xff1a;AB线悬浮在2.3V的样子。GND是0V&#xff0c;5V是4.75v 工作时&#xff0c;AB线在2.3v上做逻辑01&#xff08;-2v&#xff0c;2v&#xff09;跳变。 这图是不是还不太好理解&#xff1…

Spring事务数据库连接池流程原理详细分析

文章目录 文章目录文章目录[toc]▌Spring事务管理环境搭建标准配置声明式事务总结▌SqlSessionFactoryXML 中构建 SqlSessionFactory获得 SqlSession 的实例代码实现▌作用域&#xff08;Scope&#xff09;和生命周期SqlSessionFactoryBuilder&#xff08;构造器&#xff09;Sq…

Android App开发中OpenGL三维投影的讲解及实现(附源码和演示 简单易懂)

运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一、三维投影 OpenGL&#xff0c;定义了跨语言跨平台的图形程序接口&#xff0c;对于Android开发者来说&#xff0c;OpenGL就是用来绘制三维图形的技术手段。当然OpenGL并不仅限于展示静止的三维图形&#xff0c;也能用来播…

【0基础百日刷题】洛谷刷题知识拾遗

百日刷题一.洛谷刷题得1.P1420差分数组2.P2669数列求和3.P1307数字反转4.P5725三角形5.P1980计数问题6.P1217回文质数刷题得意义&#xff1a; 有时候会发现一个简单的题目总是通不过测试&#xff0c;调试一次 就能找出一处bug。这都是我们编程时对逻辑的思考不充分而导致的失误…