这是一个基于ONNX Runtime的YOLOv8目标检测项目,支持CPU和GPU加速,使用Qt框架构建图形化界面。

摄像头实时画面识别

视频文件识别,能正常识别目标:红绿灯,人,公交,巴士,摩托车 等

YOLOv8推理引擎 核心检测算法实现
ONNX Runtime 1.20.1 - 支持CPU和GPU两个版本
OpenCV 4.5.4 - 图像处理和计算机视觉
tl-expected- 错误处理库

QT += core gui widgets
CONFIG += c++17 consoleCONFIG += WIN_MSVC
#CONFIG += LINUX_X86CONFIG += CPU
#CONFIG += GPU##############WIN_MSVC###############
CONFIG(WIN_MSVC){
DESTDIR = ./bin_win/#opecv
INCLUDEPATH += $$PWD\ThirdParty\opencv454\include
CONFIG(debug,debug|release): LIBS += $$PWD\ThirdParty\opencv454\x64\vc16\lib\opencv_world454d.lib
CONFIG(release,debug|release): LIBS += $$PWD\ThirdParty\opencv454\x64\vc16\lib\opencv_world454.lib#onnxruntime
CONFIG(CPU){
DEFINES += CPU
INCLUDEPATH += $$PWD\ThirdParty\onnxruntime-win-x64-1.20.1\include
LIBS += $$PWD\ThirdParty\onnxruntime-win-x64-1.20.1\lib\onnxruntime.lib
}CONFIG(GPU){
DEFINES += GPU
INCLUDEPATH += $$PWD\ThirdParty\onnxruntime-win-x64-gpu-1.20.1\include
LIBS += $$PWD\ThirdParty\onnxruntime-win-x64-gpu-1.20.1\lib\onnxruntime.lib
}
}##############LINUX_X86###############
CONFIG(LINUX_X86){
DESTDIR = ./bin_linux/#opecv
INCLUDEPATH += $$PWD\ThirdParty\opencv454\include
LIBS += -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_video -lopencv_videoio -lopencv_calib3d#onnxruntime
CONFIG(CPU){
DEFINES += CPU
INCLUDEPATH += $$PWD\ThirdParty\onnxruntime-win-x64-1.20.1\include
LIBS += -lonnxruntime
}CONFIG(GPU){
DEFINES += GPU
INCLUDEPATH += $$PWD\ThirdParty\onnxruntime-win-x64-gpu-1.20.1\include
LIBS += -lonnxruntime
}
}
######################################SOURCES += \inference.cpp \main.cpp \mainwindow.cppHEADERS += \inference.h \mainwindow.h \tl-expected.hppFORMS += \mainwindow.uiMOC_DIR = tmp/moc
RCC_DIR = tmp/rcc
UI_DIR = tmp/ui
OBJECTS_DIR = tmp/obj
#include "inference.h"
#include <filesystem>
#include <fstream>
#include <codecvt> // macos必须,否则提示String2WString函数报错namespace fs = std::filesystem;std::vector<std::string> YoloV8::st_classes_;tl::expected<bool, std::string> YoloV8::create_session(const std::string &model_path)
{// 检查模型文件是否存在if (!fs::exists(model_path))  return tl::unexpected("模型文件不存在!");// 创建Ort环境env_ = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "Yolo");Ort::SessionOptions session_options;// 添加CUDA执行提供程序
#ifdef GPUOrtSessionOptionsAppendExecutionProvider_CUDA(session_options, 0);
#endif// 设置图优化级别session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);// 设置线程数session_options.SetIntraOpNumThreads(5);// 设置日志级别session_options.SetLogSeverityLevel(ORT_LOGGING_LEVEL_WARNING);// 创建会话std::wstring model_path_w = String2WString(model_path);session_ = Ort::Session(env_, model_path_w.c_str(), session_options);Ort::AllocatorWithDefaultOptions allocator;// 获取输入节点名称size_t input_count = session_.GetInputCount();for (size_t i = 0; i < input_count; i++)input_node_names_.emplace_back(session_.GetInputNameAllocated(i, allocator));// 获取输出节点名称size_t output_count = session_.GetOutputCount();for (size_t i = 0; i < output_count; i++)output_node_names_.emplace_back(session_.GetOutputNameAllocated(i, allocator));// 创建运行选项options_ = Ort::RunOptions{nullptr};return true;
}// 对输入的图像进行预处理
tl::expected<cv::Mat, std::string> YoloV8::pre_process(cv::Mat &img, cv::Size img_size)
{// 如果输入的图像为空,则返回一个错误信息if (img.empty()){return tl::unexpected("图片为空");}// 获取输入图像的宽度和高度的最大值int max_side = std::max(img.cols, img.rows);// 计算输入图像的缩放比例resize_scales_ = max_side / static_cast<float>(img_size.width);// 创建一个与输入图像大小相同的空白图像,填充值为114, 114, 114cv::Mat tmp(max_side, max_side, CV_8UC3, cv::Scalar(114, 114, 114));// 将输入图像复制到空白图像中img.copyTo(tmp(cv::Rect(0, 0, img.cols, img.rows)));// 将空白图像转换为深度学习模型所需的输入格式cv::Mat res = cv::dnn::blobFromImage(tmp, 1.0 / 255.0, img_size, cv::Scalar(0, 0, 0), true, false, CV_32F);// 返回转换后的图像return res;
}std::vector<DlResult> YoloV8::post_process(std::vector<Ort::Value> &outputs, float conf_threshold, float iou_threshold)
{// 定义一个存储结果的向量std::vector<DlResult> vec_results;// 获取输出的类型信息Ort::TypeInfo type_info = outputs.front().GetTypeInfo();// 获取输出的张量类型和形状信息auto tensor_info = type_info.GetTensorTypeAndShapeInfo();// 获取输出的形状std::vector<int64_t> output_node_dims = tensor_info.GetShape();// 获取输出的数据auto output = outputs.front().GetTensorMutableData<float>(); // 8400// 输出的形状是 [1, 84, 8400]int stride_num = output_node_dims[2];        // 8400int signal_result_num = output_node_dims[1]; // 84// 定义存储类别、置信度和框的向量std::vector<int> class_ids;std::vector<float> confidences;std::vector<cv::Rect> boxes;// 为存储类别、置信度和框的向量预留空间class_ids.reserve(stride_num / 8);confidences.reserve(stride_num / 8);boxes.reserve(stride_num / 8);// 将输出的数据转换为矩阵cv::Mat raw_data = cv::Mat(signal_result_num, stride_num, CV_32F, output).t();// 获取矩阵的指针float *data = raw_data.ptr<float>(0);// 遍历每个输出for (int i = 0; i < stride_num; ++i){// 找到置信度最高的类别auto max_it = std::max_element(data + 4, data + 80); // std::max_element返回指向最大元素的迭代器float max_class_socre = *max_it;int max_idx = std::distance(data + 4, max_it);// 如果置信度大于阈值,则存储类别、置信度和框if (max_class_socre > conf_threshold){confidences.push_back(max_class_socre);class_ids.push_back(max_idx);float x = data[0];float y = data[1];float w = data[2];float h = data[3];// 计算框的位置和大小int left = int((x - 0.5 * w) * resize_scales_);int top = int((y - 0.5 * h) * resize_scales_);int width = int(w * resize_scales_);int height = int(h * resize_scales_);// 存储框boxes.emplace_back(left, top, width, height);}// 移动到下一个输出data += signal_result_num;}// 进行非极大值抑制std::vector<int> nms_result;cv::dnn::NMSBoxes(boxes, confidences, conf_threshold, iou_threshold, nms_result);// 将结果存储到向量中for (int i = 0; i < nms_result.size(); ++i){int idx = nms_result[i];DlResult result;result.class_id = class_ids[idx];result.confidence = confidences[idx];result.box = boxes[idx];vec_results.push_back(result);}// 返回结果return vec_results;
}// 定义一个函数,用于将Ort::AllocatedStringPtr类型的向量转换为const char*类型的向量
std::vector<const char *> YoloV8::get_name_data(std::vector<Ort::AllocatedStringPtr> &names)
{// 定义一个const char*类型的向量,用于存储转换后的数据std::vector<const char *> res;// 遍历names向量中的每一个元素for (const auto &name : names){// 将每一个元素转换为const char*类型,并添加到res向量中res.push_back(name.get());}// 返回转换后的向量return res;
}tl::expected<std::vector<DlResult>, std::string> YoloV8::run_session(cv::Mat &img, cv::Size input_size, float confidence_threshold, float iou_threshold)
{// 预处理图像auto ex_img = pre_process(img, input_size);// 如果预处理失败,返回错误信息if (!ex_img){return tl::unexpected(ex_img.error());}// 定义输入张量的形状std::vector<int64_t> input_shape = {1, 3, input_size.height, input_size.width};// 创建输入张量Ort::Value input_tensor = Ort::Value::CreateTensor<float>(Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU), ex_img.value().ptr<float>(0), 3 * input_size.height * input_size.width, input_shape.data(), input_shape.size());// 运行会话auto output_tensor = session_.Run(options_, get_name_data(input_node_names_).data(), &input_tensor, input_node_names_.size(), get_name_data(output_node_names_).data(),output_node_names_.size());// 后处理输出张量auto outputs = post_process(output_tensor, confidence_threshold, iou_threshold);// 返回后处理结果return outputs;
}void YoloV8::draw_boxes(cv::Mat &img, std::vector<DlResult> &results)
{if (st_classes_.size() == 0)return;for (auto &re : results){cv::RNG rng(cv::getTickCount());cv::Scalar color(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));cv::rectangle(img, re.box, color, 3);float confidence = floor(100 * re.confidence) / 100;std::string label = st_classes_[re.class_id] + " " +std::to_string(confidence).substr(0, std::to_string(confidence).size() - 4);cv::rectangle(img,cv::Point(re.box.x, re.box.y - 25),cv::Point(re.box.x + label.length() * 15, re.box.y),color,cv::FILLED);cv::putText(img,label,cv::Point(re.box.x, re.box.y - 5),cv::FONT_HERSHEY_SIMPLEX,0.75,cv::Scalar(0, 0, 0),2);}
}

主要功能特性
- **CPU推理**: 使用标准ONNX Runtime
- **GPU推理**: 支持CUDA加速

2. 完整的检测流水线

**预处理** (`pre_process`)
- 图像尺寸调整到640x640
- Letterbox填充保持宽高比
- 像素值归一化

**推理** (`run_session`)
- ONNX模型前向推理
- 批量处理支持

**后处理** (`post_process`)
- 非极大值抑制(NMS)
- 置信度过滤
- 边界框坐标转换

3. 可视化功能
- 检测框绘制
- 类别标签显示
- 置信度分数展示

内存管理
- 使用ONNX Runtime的内存分配器
- 智能指针管理资源生命周期
- 避免内存泄漏

性能优化
- 支持GPU加速推理
- 批量处理能力
- 高效的图像预处理pipeline

适用场景

这个项目特别适合:
- **实时目标检测应用**
- **工业质检系统**
- **监控分析系统**  
- **教学和研究项目**

项目提供了完整的从模型加载到结果可视化的端到端解决方案,是学习和部署YOLOv8模型的优秀起点。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NLP分词notes

BPE 贪心提取所有出现频率高的成为词。 BPE的训练流程 1.初始化&#xff1a;将所有单个字符作为初始词汇表的元素。 2.迭代合并&#xff1a; 统计语料中所有相邻符号对&#xff08;包括字符和合并后的符号&#xff09;的出现频率。找到出现频率最高的符号对&#xff0c;将其合并…

【数据结构】栈和队列-----数据结构中的双生花

文章目录[toc]栈与队列&#xff1a;数据结构中的双生花1. 栈&#xff1a;后进先出的有序世界1.1 概念及结构剖析1.2 实现方式深度解析数组 vs 链表实现1.3 动态栈实现详解&#xff08;附程序源码&#xff09;1.定义一个动态栈2.初始化3.销毁4.入栈5.出栈6.取栈顶数据7.判空8.获…

Mybatis-2快速入门

学习主线 必学必会属于优化的东西。 快速入门需求说明 要求&#xff1a;开发一个MyBatis项目&#xff0c;通过MyBatis的方式可以完成对monster表的crud操作 1.创建mybatis数据库-monster表 主键Primary Key默认非空Not null&#xff0c;就省略了 create database mybatis us…

Web基础 -java操作数据库

一、JDBCJDBC&#xff1a;&#xff08;Java DataBase Connectivity&#xff09;&#xff0c;就是使用Java语言操作关系型数据库的一套API。为了使用JDBC操作数据库&#xff0c;首先&#xff0c;我们需要在pom.xml文件中引入依赖<dependencies><!-- MySQL JDBC driver …

cell2location复现

https://github.com/BayraktarLab/cell2location/issues/348 根据你已下载的本地 wheel 文件&#xff0c;可以通过以下方式修改安装命令&#xff0c;优先从本地路径安装 jaxlib&#xff0c;同时保持其他依赖的安装方式不变&#xff1a; 解决方案 # 安装 jax (从远程 PyPI 源) p…

什么是 npm、Yarn、pnpm? 有什么区别? 分别适应什么场景?

什么是 npm、Yarn、pnpm? 有什么区别? 分别适应什么场景? 在前端开发中&#xff0c;包管理工具扮演着非常重要的角色。它们帮助开发者高效地管理项目的依赖&#xff0c;确保项目中所需的所有第三方库和工具都能按时安装&#xff0c;并且兼容版本。npm、Yarn 和 pnpm 是三款…

深度隐匿源IP:高防+群联AI云防护防绕过实战

隐蔽性挑战 黑客常通过以下手段绕过基础防护&#xff1a; HTTPS证书嗅探&#xff1a;访问 https://源站IP&#xff0c;通过证书域名匹配暴露真实IP历史解析记录追踪&#xff1a;从DNS数据库获取旧A记录CDN缓存渗透&#xff1a;利用边缘节点回源漏洞定位源站 三重防护方案 高防I…

如何加快golang编译速度

跟着我的步骤来&#xff1a;第一步&#xff1a;(点击edit)第二步&#xff1a;将go tool arguments设置为-p4&#xff0c;初始值设为4&#xff0c; 代表最多同时编译4个包&#xff08;非文件&#xff09;。电脑性能好时&#xff0c;可设为CPU最大核心数&#xff08;充分利用多核…

浏览器自动化方案

B端后台列表页自动新增素材方案 我设计了一套完整的浏览器自动化方案&#xff0c;使用 Puppeteer 实现B端后台列表页的自动新增素材功能。该方案包含数据组织、浏览器操作、错误处理等完整流程。 一、技术选型 浏览器自动化工具&#xff1a;Puppeteer (https://pptr.dev)任务调…

MPPT电路设计

反激的具体计算过程要写好起码要一天&#xff0c;所以本次先更MPPT。这章不计算具体参数&#xff0c;只做分析。 目录 一、电路作用 二、电路设计 采样电路和输入电路 主体电路 驱动电路 一、电路作用 MPPT电路是一种广泛应用于光伏发电、风力发电等新能源系统中的关键电…

【基于飞浆训练车牌识别模型】

基于飞浆训练车牌识别模型 基于飞浆训练车牌识别模型 LPRNet&#xff08;License Plate Recognition via Deep Neural Networks&#xff09;是一种轻量级卷积神经网络&#xff0c;专为端到端车牌识别设计&#xff0c;由Intel IOTG Computer Vision Group的Sergey Zherzdev于201…

No module named ‘sklearn‘

1、运行python数据分析库时报错 No module named sklearn2、原因 虚拟环境未安装 sklearn 库&#xff08;即 scikit-learn&#xff09;。 3、解决方案 pip install scikit-learn使用国内镜像源&#xff1a; pip install scikit-learn -i https://mirrors.aliyun.com/pypi/simpl…

XPath注入攻击详解:原理、危害与防御

什么是XPath注入&#xff1f; XPath注入&#xff08;XPath Injection&#xff09;是一种针对使用XPath查询语言的应用程序的安全攻击技术&#xff0c;类似于SQL注入。当应用程序使用用户提供的输入来构造XPath查询而没有进行适当的过滤或转义时&#xff0c;攻击者可以通过构造恶…

网络编程(套接字)

目录 一、套接字 1、套接字的作用 2、关于TCP和UDP协议 1. TCP协议 2. UDP协议 3. 两者的区别 2、套接字函数 1&#xff09;函数 socket&#xff08;创建套接字同文件描述符&#xff09; 2&#xff09;准备套接字用结构体 1. 套接字的结构体 2. 客户端的套接字&…

R语言安装包

# 在安装过程中指定源地址 install.packages("RCurl", repos "https://mirrors.tuna.tsinghua.edu.cn/CRAN/") # 查看当前镜像 options()$repos # 设置为中科大镜像 options("repos" c(CRAN"https://mirrors.ustc.edu.cn/CRAN/")…

微服务引擎 MSE 及云原生 API 网关 2025 年 5 月产品动态

点击此处&#xff0c;了解微服务引擎 MSE 产品详情。

性能测试过程中监控linux服务器资源情况

文章目录1. cpu使用情况&#xff08;1&#xff09;性能瓶颈类型CPU密集型瓶颈​​I/O或等待瓶颈​&#xff08;2&#xff09;资源分配与竞争​资源争用分析​虚拟化环境资源分配​&#xff08;3&#xff09;系统稳定性与异常​​异常波动与毛刺​​过热降频影响​&#xff08;4…

使用defineExpose暴露子组件的属性和方法、页面生命周期onLoad和onReady的使用

欢迎来到我的UniApp技术专栏&#xff01;&#x1f389; 在这里&#xff0c;我将与大家分享关于UniApp开发的实用技巧、最佳实践和项目经验。 专栏特色&#xff1a; &#x1f4f1; 跨平台开发一站式解决方案 &#x1f680; 从入门到精通的完整学习路径 &#x1f4a1; 实战项目经…

新手必看!VSCodePyCharm 配置 OpenCV 超详细教程(支持 Python 和 C++ 双语言)

新手必看&#xff01;VSCode&PyCharm 配置 OpenCV 超详细教程&#xff08;支持 Python 和 C 双语言&#xff09; 适用对象&#xff1a;初学者&#xff0c;希望在 VSCode 与 PyCharm 两款常用 IDE 中&#xff0c;学会配置并使用 OpenCV&#xff0c;分别实现 Python 与 C 环境…

PyTorch深度学习框架入门案例实战

PyTorch深度学习框架详解与实战 1. PyTorch简介与环境配置 1.1 安装与导入 # 基础导入 import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset import numpy as np import…