栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【yolov5 ONNX】c++ 加载 导出的onnx模型

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【yolov5 ONNX】c++ 加载 导出的onnx模型

注意: cuda toolkit 版本 CUDA Toolkit 11.3 Downloads | NVIDIA Developer

                编译opencv使用的cuda toolkit版本

                cudnn版本与cuda对应

               

#include 

#include 
//#include 


std::vector load_class_list()
{
	std::vector class_list;
	std::ifstream ifs("weights/block.txt");
	std::string line;
	while (getline(ifs, line))
	{
		class_list.push_back(line);
	}
	return class_list;
}

void load_net(cv::dnn::Net& net, bool is_cuda)
{
	auto result = cv::dnn::readNetFromONNX("weights/best.onnx");//readNet   代码可用 版本有问题
	if (is_cuda)
	{
		std::cout << "Attempty to use CUDAn";
		result.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
		result.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
		//result.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA_FP16);
	}
	else
	{
		std::cout << "Running on CPUn";
		result.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
		result.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
	}
	net = result;
}

const std::vector colors = { cv::Scalar(255, 255, 0), cv::Scalar(0, 255, 0), cv::Scalar(0, 255, 255), cv::Scalar(255, 0, 0) };

const float INPUT_WIDTH = 416.0;//640
const float INPUT_HEIGHT = 416.0;//640
const float SCORE_THRESHOLD = 0.2;
const float NMS_THRESHOLD = 0.4;
const float CONFIDENCE_THRESHOLD = 0.4;

struct Detection
{
	int class_id;
	float confidence;
	cv::Rect box;
};

cv::Mat format_yolov5(const cv::Mat& source) {
	int col = source.cols;
	int row = source.rows;
	int _max = MAX(col, row);
	cv::Mat result = cv::Mat::zeros(_max, _max, CV_8UC3);
	source.copyTo(result(cv::Rect(0, 0, col, row)));
	return result;
}

void detect(cv::Mat& image, cv::dnn::Net& net, std::vector& output, const std::vector& className) {
	cv::Mat blob;

	auto input_image = format_yolov5(image);

	cv::dnn::blobFromImage(input_image, blob, 1. / 255., cv::Size(INPUT_WIDTH, INPUT_HEIGHT), cv::Scalar(), true, false);
	net.setInput(blob);
	std::vector outputs;
	std::vector blobnames = net.getUnconnectedOutLayersNames();
	std::cout << "before forwardn";
	net.forward(outputs, blobnames);//da4dnn::checkVersions CUDART version 11030 reported by cuDNN 8200 does not match with the version reported by CUDART 11010


	//outputs = net.forward();
	std::cout << "after forwardn";
	float x_factor = input_image.cols / INPUT_WIDTH;
	float y_factor = input_image.rows / INPUT_HEIGHT;

	float* data = (float*)outputs[0].data;

	const int dimensions = 85;
	const int rows = 1;//25200

	std::vector class_ids;
	std::vector confidences;
	std::vector boxes;

	for (int i = 0; i < rows; ++i) {

		float confidence = data[4];// data[4]
		if (confidence >= CONFIDENCE_THRESHOLD) {

			float* classes_scores = data + 5;
			cv::Mat scores(1, className.size(), CV_32FC1, classes_scores);
			cv::Point class_id;
			double max_class_score;
			minMaxLoc(scores, 0, &max_class_score, 0, &class_id);
			if (max_class_score > SCORE_THRESHOLD) {

				confidences.push_back(confidence);

				class_ids.push_back(class_id.x);

				float x = data[0];
				float y = data[1];
				float w = data[2];
				float h = data[3];
				int left = int((x - 0.5 * w) * x_factor);
				int top = int((y - 0.5 * h) * y_factor);
				int width = int(w * x_factor);
				int height = int(h * y_factor);
				boxes.push_back(cv::Rect(left, top, width, height));
			}

		}

		data += 85;

	}

	std::vector nms_result;
	cv::dnn::NMSBoxes(boxes, confidences, SCORE_THRESHOLD, NMS_THRESHOLD, nms_result);
	for (int i = 0; i < nms_result.size(); i++) {
		int idx = nms_result[i];
		Detection result;
		result.class_id = class_ids[idx];
		result.confidence = confidences[idx];
		result.box = boxes[idx];
		output.push_back(result);
	}
}

int main(int argc, char** argv)
{

	std::vector class_list = load_class_list();

	cv::Mat frame;
	cv::VideoCapture capture("1.mp4");
	if (!capture.isOpened())
	{
		std::cerr << "Error opening video filen";
		return -1;
	}

	bool is_cuda = argc > 1 && strcmp(argv[1], "cuda") == 0;
	is_cuda = true;//手动设置
	cv::dnn::Net net;
	load_net(net, is_cuda);

	auto start = std::chrono::high_resolution_clock::now();
	int frame_count = 0;
	float fps = -1;
	int total_frames = 0;

	while (true)
	{
		capture.read(frame);
		if (frame.empty())
		{
			std::cout << "End of streamn";
			break;
		}

		std::vector output;
		detect(frame, net, output, class_list);

		frame_count++;
		total_frames++;

		int detections = output.size();

		for (int i = 0; i < detections; ++i)
		{

			auto detection = output[i];
			auto box = detection.box;
			auto classId = detection.class_id;
			const auto color = colors[classId % colors.size()];
			cv::rectangle(frame, box, color, 3);

			cv::rectangle(frame, cv::Point(box.x, box.y - 20), cv::Point(box.x + box.width, box.y), color, cv::FILLED);
			cv::putText(frame, class_list[classId].c_str(), cv::Point(box.x, box.y - 5), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
		}

		if (frame_count >= 30)
		{

			auto end = std::chrono::high_resolution_clock::now();
			fps = frame_count * 1000.0 / std::chrono::duration_cast(end - start).count();

			frame_count = 0;
			start = std::chrono::high_resolution_clock::now();
		}

		if (fps > 0)
		{

			std::ostringstream fps_label;
			fps_label << std::fixed << std::setprecision(2);
			fps_label << "FPS: " << fps;
			std::string fps_label_str = fps_label.str();

			cv::putText(frame, fps_label_str.c_str(), cv::Point(10, 25), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 0, 255), 2);
		}

		cv::imshow("output", frame);

		if (cv::waitKey(1) != -1)
		{
			capture.release();
			std::cout << "finished by usern";
			break;
		}
	}

	std::cout << "Total frames: " << total_frames << "n";

	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/979785.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号