最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++調(diào)用實現(xiàn)yolov5轉(zhuǎn)onnx介紹

 更新時間:2021年12月22日 09:05:48   作者:小軍軍軍軍軍軍  
大家好,本篇文章主要講的是c++調(diào)用實現(xiàn)yolov5轉(zhuǎn)onnx介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽

介紹

現(xiàn)在很多開發(fā)都是需要用c++做最后一步的移植部署,手寫吧,先不說你會不會浪費時間,網(wǎng)上找吧,問題千奇百怪,所以給大家出這篇文章,做雷鋒教學(xué),話不多說,開始

訓(xùn)練模型.pt轉(zhuǎn)onnx

訓(xùn)練部分根據(jù)呼聲再決定要不要寫一份博客吧?。?br /> 注意事項:
1.訓(xùn)練代碼一定要選擇yolov5 5.0版本
2. 進入models/exprort.py;

請?zhí)砑訄D片描述

3.將紅框區(qū)域換成你自己的訓(xùn)練完的模型

請?zhí)砑訄D片描述

4.將版本換成12;

請?zhí)砑訄D片描述

5.直接運行即可,會生成出onnx的模型出來。

c++代碼解析

博主使用的是opencv4.5.3版本,已經(jīng)編譯好的,需要直接掃碼加我發(fā)你

main函數(shù)部分

請?zhí)砑訄D片描述

讀取模型利用的是dnn::readNet,opencv其實挺強大的博主已經(jīng)讀過tf模型,torch模型后續(xù)都會出對應(yīng)博客,這里總共有三點改,輸入圖片path,輸入類別名class_names,net部分改成自己的模型

net.set這些參數(shù)都固定就好,有興趣的同學(xué)可以研究研究DNN_TARGET_CPU這個地方,是可以使用gpu和cuda的,但是博主還沒復(fù)現(xiàn)過

推理部分講解

void postprocess(cv::Mat& cv_src, std::vector<cv::Mat>& outs, const std::vector<std::string>& classes, int net_size)
{
	float confThreshold = 0.1f;
	float nmsThreshold = 0.1f;
	std::vector<int> classIds;
	std::vector<float> confidences;
	std::vector<cv::Rect> boxes;
	int strides[] = { 8, 16, 32 };
	std::vector<std::vector<int> > anchors =
	{
		{ 10,13, 16,30, 33,23 },
		{ 30,61, 62,45, 59,119 },
		{ 116,90, 156,198, 373,326 }
	};
	for (size_t k = 0; k < outs.size(); k++)
	{
		float* data = outs[k].ptr<float>();
		int stride = strides[k];
		int num_classes = outs[k].size[4] - 5;
		for (int i = 0; i < outs[k].size[2]; i++)
		{
			for (int j = 0; j < outs[k].size[3]; j++)
			{
				for (int a = 0; a < outs[k].size[1]; ++a)
				{
					float* record = data + a * outs[k].size[2] * outs[k].size[3] * outs[k].size[4] +
						i * outs[k].size[3] * outs[k].size[4] + j * outs[k].size[4];
					float* cls_ptr = record + 5;
					for (int cls = 0; cls < num_classes; cls++)
					{
						float score = sigmoid(cls_ptr[cls]) * sigmoid(record[4]);
						if (score > confThreshold)
						{
							float cx = (sigmoid(record[0]) * 2.f - 0.5f + (float)j) * (float)stride;
							float cy = (sigmoid(record[1]) * 2.f - 0.5f + (float)i) * (float)stride;
							float w = pow(sigmoid(record[2]) * 2.f, 2) * anchors[k][2 * a];
							float h = pow(sigmoid(record[3]) * 2.f, 2) * anchors[k][2 * a + 1];
							float x1 = std::max(0, std::min(cv_src.cols, int((cx - w / 2.f) * (float)cv_src.cols / (float)net_size)));
							float y1 = std::max(0, std::min(cv_src.rows, int((cy - h / 2.f) * (float)cv_src.rows / (float)net_size)));
							float x2 = std::max(0, std::min(cv_src.cols, int((cx + w / 2.f) * (float)cv_src.cols / (float)net_size)));
							float y2 = std::max(0, std::min(cv_src.rows, int((cy + h / 2.f) * (float)cv_src.rows / (float)net_size)));
							classIds.push_back(cls);
							confidences.push_back(score);
							boxes.push_back(cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)));
						}
					}
				}
			}
		}
	}
	std::vector<int> indices;
	cv::dnn::NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);
	for (size_t i = 0; i < indices.size(); i++)
	{
		int idx = indices[i];
		cv::Rect box = boxes[idx];
		drawPred(classIds[idx], confidences[idx], box.x, box.y,
			box.x + box.width, box.y + box.height, cv_src, classes);
	}
}

抬頭部分是兩大目標檢測的閾值設(shè)置,然后anchors這些都不建議動,除非你在訓(xùn)練的時候用了你自己生成的anchors的話,就改成你自己的,然后根據(jù)訓(xùn)練推理后,會生成我們所對應(yīng)的坐標框以及分數(shù),將分數(shù)和狂送到容器中,dnn中有nms等底層函數(shù)哦
cv::dnn::NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);
對應(yīng)輸入就可以了,然后得到我們的Box,index,和置信度,接下來就到了我們的畫圖環(huán)節(jié)。

darpred部分

void drawPred(int classId, float conf, int left, int top, int right, int bottom, cv::Mat& frame,
	const std::vector<std::string>& classes)
{
	cv::rectangle(frame, cv::Point(left, top), cv::Point(right, bottom), cv::Scalar(0, 255, 0), 3);
	std::string label = cv::format("%.2f", conf);
	if (!classes.empty()) {
		CV_Assert(classId < (int)classes.size());
		label = classes[classId] + ": " + label;
	}
	int baseLine;
	cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
	top = std::max(top, labelSize.height);
	cv::rectangle(frame, cv::Point(left, top - round(1.5 * labelSize.height)), cv::Point(left + round(1.5 * labelSize.width), top + baseLine), cv::Scalar(0, 255, 0), cv::FILLED);
	cv::putText(frame, label, cv::Point(left, top), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(), 2);
}

sigmod部分

inline float sigmoid(float x)
{
	return 1.f / (1.f + exp(-x));
}

結(jié)尾

到此這篇關(guān)于c++調(diào)用實現(xiàn)yolov5轉(zhuǎn)onnx介紹的文章就介紹到這了,更多相關(guān)c++ yolov5轉(zhuǎn)onnx內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言 如何求兩整數(shù)的最大公約數(shù)與最小公倍數(shù)

    C語言 如何求兩整數(shù)的最大公約數(shù)與最小公倍數(shù)

    這篇文章主要介紹了C語言中如何求兩整數(shù)的最大公約數(shù)與最小公倍數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 詳解C語言之文件操作下)

    詳解C語言之文件操作下)

    這篇文章主要介紹了關(guān)于C語言文件操作方法的相關(guān)資料,小編覺得這篇文章寫的還不錯,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-11-11
  • C++中std::thread線程用法

    C++中std::thread線程用法

    本文主要介紹了C++中std::thread線程用法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • C++ class和struct到底有什么區(qū)別詳解

    C++ class和struct到底有什么區(qū)別詳解

    這篇文章主要介紹了C++ class和struct到底有什么區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C++中不能被重載的運算符介紹

    C++中不能被重載的運算符介紹

    其實在C/C++ 里大多數(shù)運算符都可以在C++中被重載的。C 的運算符中只有 . 和 ?:(以及 sizeof,技術(shù)上可以看作一個運算符)不可以被重載
    2013-10-10
  • C語言如何實現(xiàn)順序表(數(shù)據(jù)結(jié)構(gòu))

    C語言如何實現(xiàn)順序表(數(shù)據(jù)結(jié)構(gòu))

    這篇文章主要介紹了C語言如何實現(xiàn)順序表(數(shù)據(jù)結(jié)構(gòu))問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 淺析C語言中sscanf 的用法

    淺析C語言中sscanf 的用法

    以下是對C語言中sscanf函數(shù)的使用方法進行了詳細的分析介紹,需要的朋友參考下
    2013-07-07
  • C++矩陣運算的實現(xiàn)簡單

    C++矩陣運算的實現(xiàn)簡單

    本文主要介紹了C++矩陣運算的實現(xiàn)簡單,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++簡單又好用的基本運算符重載

    C++簡單又好用的基本運算符重載

    繼友元知識過后,就到了今天的C++運算符重載的內(nèi)容了,運算符重載是C++里比較重要的內(nèi)容。這篇博文不會一下子講完各種運算符重載,因為太多了了也不好吸收掌握,所以運算符重載我準備分多次記錄和分享,那么接下來進入正文
    2022-06-06
  • C++ const的各種用法詳解

    C++ const的各種用法詳解

    const名叫常量限定符,用來限定特定變量,以通知編譯器該變量是不可修改的。習(xí)慣性的使用const,可以避免在函數(shù)中對某些不應(yīng)修改的變量造成可能的改動。本文主要談?wù)刢onst的用法,感興趣的同學(xué)可以參考閱讀
    2023-04-04

最新評論

林西县| 安陆市| 巴塘县| 丰都县| 南昌县| 全州县| 延吉市| 柯坪县| 宝应县| 寿光市| 玛多县| 仙居县| 安远县| 同江市| 屯昌县| 乌鲁木齐县| 客服| 富平县| 弥渡县| 遵化市| 行唐县| 彩票| 东港市| 报价| 宝兴县| 樟树市| 吴桥县| 错那县| 静宁县| 班戈县| 德兴市| 霍林郭勒市| 都昌县| 民和| 洛隆县| 娄底市| 于都县| 当雄县| 沭阳县| 古蔺县| 宜都市|