Qt+yolov8目標識別

這是一個基于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…