使用opencv4.7.0部署yolov5

yolov5原理和部署原理就不說了,想了解的可以看看這篇部署原理文章

#include <fstream>
#include <sstream>
#include <iostream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>//using namespace cv;
//using namespace dnn;
//using namespace std;
int index = 0;struct Net_config
{float confThreshold; // Confidence thresholdfloat nmsThreshold;  // Non-maximum suppression thresholdfloat objThreshold;  //Object Confidence thresholdstd::string modelpath;
};int endsWith(std::string s, std::string sub) {return s.rfind(sub) == (s.length() - sub.length()) ? 1 : 0;
}class YOLO
{
public:YOLO(Net_config config);std::tuple<std::vector<cv::Rect>, std::vector<int>> detect(cv::Mat& frame);
private:float* anchors;int num_stride;int inpWidth;int inpHeight;std::vector<std::string> class_names;int num_class;float confThreshold;float nmsThreshold;float objThreshold;const bool keep_ratio = true;cv::dnn::Net net;void drawPred(float conf, int left, int top, int right, int bottom, cv::Mat& frame, int classid);cv::Mat resize_image(cv::Mat srcimg, int *newh, int *neww, int *top, int *left);};YOLO::YOLO(Net_config config)
{this->confThreshold = config.confThreshold;this->nmsThreshold = config.nmsThreshold;this->objThreshold = config.objThreshold;this->net = cv::dnn::readNet(config.modelpath);std::ifstream ifs("D:\\project_prj\\deeplearn\\yolov5\\class.names");std::string line;while (getline(ifs, line)) this->class_names.push_back(line);this->num_class = class_names.size();this->num_stride = 3;this->inpHeight = 640;this->inpWidth = 640;}cv::Mat YOLO::resize_image(cv::Mat srcimg, int *newh, int *neww, int *top, int *left)
{int srch = srcimg.rows, srcw = srcimg.cols;*newh = this->inpHeight;*neww = this->inpWidth;cv::Mat dstimg;if (this->keep_ratio && srch != srcw) {float hw_scale = (float)srch / srcw;if (hw_scale > 1) {*newh = this->inpHeight;*neww = int(this->inpWidth / hw_scale);resize(srcimg, dstimg, cv::Size(*neww, *newh), cv::INTER_AREA);*left = int((this->inpWidth - *neww) * 0.5);copyMakeBorder(dstimg, dstimg, 0, 0, *left, this->inpWidth - *neww - *left, cv::BORDER_CONSTANT, 114);}else {*newh = (int)this->inpHeight * hw_scale;*neww = this->inpWidth;resize(srcimg, dstimg, cv::Size(*neww, *newh), cv::INTER_AREA);*top = (int)(this->inpHeight - *newh) * 0.5;copyMakeBorder(dstimg, dstimg, *top, this->inpHeight - *newh - *top, 0, 0, cv::BORDER_CONSTANT, 114);}}else {resize(srcimg, dstimg, cv::Size(*neww, *newh), cv::INTER_AREA);}return dstimg;
}void YOLO::drawPred(float conf, int left, int top, int right, int bottom, cv::Mat& frame, int classid)   // Draw the predicted bounding box
{//Draw a rectangle displaying the bounding boxif(classid==0)cv::rectangle(frame, cv::Point(left, top), cv::Point(right, bottom), cv::Scalar(0, 0, 255), 2);elsecv::rectangle(frame, cv::Point(left, top), cv::Point(right, bottom), cv::Scalar(0, 255, 0), 2);//Get the label for the class name and its confidencestd::string label = cv::format("%.2f", conf);label = this->class_names[classid] + ":" + label;//Display the label at the top of the bounding boxint baseLine;cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);top = std::max(top, labelSize.height);if(classid == 0)//rectangle(frame, Point(left, top - int(1.5 * labelSize.height)), Point(left + int(1.5 * labelSize.width), top + baseLine), Scalar(0, 255, 0), FILLED);cv::putText(frame, label, cv::Point(left, top), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0, 0, 255), 1);elsecv::putText(frame, label, cv::Point(left, top), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0, 255, 0), 1);
}std::tuple<std::vector<cv::Rect>, std::vector<int>> YOLO::detect(cv::Mat& frame)
{int newh = 0, neww = 0, padh = 0, padw = 0;cv::Mat dstimg = this->resize_image(frame, &newh, &neww, &padh, &padw);cv::Mat blob = cv::dnn::blobFromImage(dstimg, 1 / 255.0, cv::Size(this->inpWidth, this->inpHeight), cv::Scalar(0, 0, 0), true, false);this->net.setInput(blob);std::vector<cv::Mat> outs;this->net.forward(outs, this->net.getUnconnectedOutLayersNames());int num_proposal = outs[0].size[1];int nout = outs[0].size[2];if (outs[0].dims > 2){outs[0] = outs[0].reshape(0, num_proposal);}/generate proposalsstd::vector<float> confidences;std::vector<cv::Rect> boxes;std::vector<int> classIds;float ratioh = (float)frame.rows / newh, ratiow = (float)frame.cols / neww;int n = 0, q = 0, i = 0, j = 0, row_ind = 0; ///xmin,ymin,xamx,ymax,box_score,class_scorefloat* pdata = (float*)outs[0].data;for (int i = 0; i < 25200 / 7; i++){float cx = pdata[i * 7+0];float cy = pdata[i * 7+1];float w = pdata[i * 7 + 2];float h = pdata[i * 7 + 3];float score = pdata[i * 7 + 4];if (score < this->objThreshold)continue;float class_num1 = pdata[i * 7 + 5];float class_num2 = pdata[i * 7 + 6];int left = int((cx - padw - 0.5 * w) * ratiow);int top = int((cy - padh - 0.5 * h) * ratioh);float max_class_socre = class_num1 > class_num2 ? class_num1 : class_num2;if (class_num1 > class_num2){max_class_socre = class_num1;classIds.push_back(0);}else{max_class_socre = class_num2;classIds.push_back(1);}confidences.push_back(max_class_socre);boxes.push_back(cv::Rect(left, top, (int)(w * ratiow), (int)(h * ratioh)));}// Perform non maximum suppression to eliminate redundant overlapping boxes with// lower confidencesstd::vector<cv::Rect> result_;std::vector<int> class_;std::vector<int> indices;cv::dnn::NMSBoxes(boxes, confidences, this->confThreshold, this->nmsThreshold, indices);for (size_t i = 0; i < indices.size(); ++i){int idx = indices[i];cv::Rect box = boxes[idx];result_.emplace_back(box);class_.emplace_back(classIds[idx]);this->drawPred(confidences[idx], box.x, box.y,box.x + box.width, box.y + box.height, frame, classIds[idx]);}imwrite("D:\\project_prj\\deeplearn\\yolov5\\result\\" + std::to_string(index++) + ".jpg", frame);//std::cout << "done" << std::endl;//delete pdata;return std::make_tuple(result_, class_);
}int main()
{Net_config yolo_nets = { 0.60, 0.5, 0.60, "D:\\project_prj\\run\\best_detectcircle_1.onnx" };YOLO yolo_model(yolo_nets);//string imgpath = "D:\\20230817-144309.jpg";std::string path = "C:\\datas_samll";std::vector<cv::String> result;cv::glob(path, result);for (auto x : result){std::cout << x << std::endl;cv::Mat srcimg = cv::imread(x);auto result = yolo_model.detect(srcimg);}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41484.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41484.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41484.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Java轉Go】快速上手學習筆記(二)之基礎篇一

目錄 創建項目數據類型變量常量類型轉換計數器鍵盤交互流程控制代碼運算符 創建項目 上篇我們安裝好了Go環境&#xff0c;和用IDEA安裝Go插件來開發Go項目&#xff1a;【Java轉Go】快速上手學習筆記&#xff08;一&#xff09;之環境安裝篇 。 這篇我們開始正式學習Go語言。我…

MyBatis動態SQL:打造靈活可變的數據庫操作

目錄 if標簽trim標簽where標簽set標簽foreach標簽 動態SQL就是根據不同的條件或需求動態地生成查詢語句&#xff0c;比如動態搜索條件、動態表或列名、動態排序等。 if標簽 在我們填寫一些信息時&#xff0c;有些信息是必填字段&#xff0c;有的則是非必填的&#xff0c;這些…

淘寶API接口的實時數據和緩存數據區別

電商API接口實時數據是指通過API接口獲取到的與電商相關的實時數據。這些數據可以包括商品庫存、訂單狀態、銷售額、用戶活躍度等信息。 通過電商API接口&#xff0c;可以實時獲取到電商平臺上的各種數據&#xff0c;這些數據可以幫助企業或開發者做出及時的決策和分析。例如&…

vue動態修改audio地址

問題&#xff1a;點擊后替換url地址&#xff0c;實現了&#xff0c;但是播放器依舊沒有反應。 解決&#xff1a;vue中動態替換只是替換了地址&#xff0c;并沒有告訴audio標簽是否要執行&#xff0c;執行什么操作。要load后才能讓它知道&#xff0c;是在喊他&#xff0c;他需求…

秒懂算法 | 漢諾塔問題與木棒三角形

在數學與計算機科學中&#xff0c;遞歸(recursion)是指一個過程或函數在其定義或說明中又直接或間接調用自身的一種方法。它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解。遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計算&#x…

Android性能優化——線程優化

一、線程調度原理 在任意時刻&#xff0c;CPU只能執行一條指令&#xff0c;每個線程獲取到CPU的使用權之后才可以執行指令也就是說在任意時刻&#xff0c;只有一個線程占用CPU 處于運行狀態 多線程并發&#xff0c;實際上是指多個線程輪流獲取CPU 的使用權然后分別執行各自的任…

系統安全測試要怎么做?

進行系統安全測試時&#xff0c;可以按照以下詳細的步驟進行&#xff1a; 1、信息收集和分析&#xff1a; 收集系統的相關信息&#xff0c;包括架構、部署環境、使用的框架和技術等。 分析系統的安全需求、威脅模型和安全策略等文檔。 2、威脅建模和風險評估&#xff1a; 使…

調用被fishhook的原函數

OC類如果通過runtime被hook了&#xff0c;可以通過逆序遍歷方法列表的方式調用原方法。 那系統庫的C函數被fish hook了該怎么辦呢&#xff1f; 原理和OC類異曲同工&#xff0c;即通過系統函數dlopen()獲取動態庫&#xff0c;以動態庫為參數通過系統函數dlsym()即可獲取目標系統…

leetcode292. Nim 游戲(博弈論 - java)

Nim 游戲 Nim 游戲題目描述博弈論 上期經典算法 Nim 游戲 難度 - 簡單 原題鏈接 - Nim游戲 題目描述 你和你的朋友&#xff0c;兩個人一起玩 Nim 游戲&#xff1a; 桌子上有一堆石頭。 你們輪流進行自己的回合&#xff0c; 你作為先手 。 每一回合&#xff0c;輪到的人拿掉 1 -…

494. 目標和

494. 目標和 原題鏈接&#xff1a;完成情況&#xff1a;解題思路&#xff1a;數組回溯法動態規劃 參考代碼&#xff1a;數組回溯法__494目標和__動態規劃 經驗吸取 原題鏈接&#xff1a; 494. 目標和 https://leetcode.cn/problems/target-sum/description/ 完成情況&#…

Android進階之多級列表

遇到一個需求需要顯示多級列表&#xff0c;因為界面是在平板上的&#xff0c;所以層級是從左向右往下排的&#xff0c;類似于 我當時的寫法是在xml布局里一個個RecyclerView往下排的 當然前提是已經規定好最大的層級我才敢如此去寫界面&#xff0c;如果已經明確規定只有兩級或…

69 # 強制緩存的配置

強制緩存 強制緩存&#xff1a;以后的請求都不需要訪問服務器&#xff0c;狀態碼為 200協商緩存&#xff1a;每次都判斷一下&#xff0c;告訴是否需要找緩存&#xff0c;狀態碼為 304 默認強制緩存&#xff0c;不緩存首頁&#xff08;如果已經斷網&#xff0c;那這個頁面應該…

Python發送QQ郵件

使用Python的smtplib可以發送QQ郵件&#xff0c;代碼如下 #!/usr/bin/python3 import smtplib from email.mime.text import MIMEText from email.header import Headersender 111qq.com # 發送郵箱 receivers [222qq.com] # 接收郵箱 auth_code "abc" # 授權…

Dockerfile概念、鏡像原理、制作及案例講解

1.Docker鏡像原理 Linux文件操作系統講解 2.鏡像如何制作 3.Dockerfile概念 Docker網址&#xff1a;https://hub.docker.com 3.1 Dockerfile關鍵字 4.案例

【數據結構OJ題】鏈表分割

原題鏈接&#xff1a;https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId8&&tqId11004&rp2&ru/activity/oj&qru/ta/cracking-the-coding-interview/question-ranking 目錄 1. 題目描述 2. 思路分析 3. 代碼實現 1. 題目描述 2…

AMD卡啟動Stable Diffusion AI繪畫的方法

WindowsAMD安裝法 1.安裝python 3.10.6&#xff0c;在python官網上下載安裝程序&#xff0c;***重要*** 在安裝的第一個窗口下方勾選“將python添加到path”。 2.安裝git 3.WindowsAMD使用AUTOMATIC1111的directml這一個fork&#xff0c;在這個頁面的第一段&#xff1a;https:/…

題目:2614.對角線上的質數

??題目來源&#xff1a; leetcode題目&#xff0c;網址&#xff1a;2614. 對角線上的質數 - 力扣&#xff08;LeetCode&#xff09; 解題思路&#xff1a; 遍歷對角線上的元素&#xff0c;返回最大的質數或 0 即可。 解題代碼&#xff1a; class Solution {public int dia…

e.target.value和 binding.value 區別

e.target.value 和 binding.value 都是在 Vue.js 中用于處理事件綁定時的值&#xff0c;但它們的使用場景和含義有所不同&#xff0c;分別用于普通的 DOM 事件和自定義指令。 e.target.value&#xff1a; 這是常用于原生 DOM 事件處理函數中的一個屬性&#xff0c;用于獲取事件…

爬蟲逆向實戰(十七)--某某丁簡歷登錄

一、數據接口分析 主頁地址&#xff1a;某某丁簡歷 1、抓包 通過抓包可以發現數據接口是submit 2、判斷是否有加密參數 請求參數是否加密&#xff1f; 通過查看“載荷”模塊可以發現有一個enPassword加密參數 請求頭是否加密&#xff1f; 通過查看請求頭可以發現有一個To…

【面試高頻題】難度 3/5,字典樹熱門運用題

題目描述 這是 LeetCode 上的 「745. 前綴和后綴搜索」 &#xff0c;難度為 「困難」。 Tag : 「字典樹」 設計一個包含一些單詞的特殊詞典&#xff0c;并能夠通過前綴和后綴來檢索單詞。 實現 WordFilter 類&#xff1a; WordFilter(string[] words) 使用詞典中的單詞 words 初…