openvino2022 C++部署yolov5安全帽检测模型

#include <fstream>                   //C++ 文件操作
#include <iostream>                  //C++ input & output stream
#include <sstream>                   //C++ String stream, 读写内存中的string对象
#include <opencv2\opencv.hpp>        //OpenCV 头文件
#include <openvino\openvino.hpp>     //OpenVINO >=2022.1
#include "utils.hpp"

using namespace std;
using namespace ov;
using namespace cv;
//安全帽数据集的标签
vector<string> class_names = { "person", "hat"};
//OpenVINO IR模型文件路径
string ir_filename = "D:\\code\\Python\\YOLO5\\yolov5-master\\best.onnx";

// @brief 对网络的输入为图片数据的节点进行赋值,实现图片数据输入网络
// @param input_tensor 输入节点的tensor
// @param inpt_image 输入图片数据
void fill_tensor_data_image(ov::Tensor& input_tensor, const cv::Mat& input_image) {
	// 获取输入节点要求的输入图片数据的大小
	ov::Shape tensor_shape = input_tensor.get_shape();
	const size_t width = tensor_shape[3]; // 要求输入图片数据的宽度
	const size_t height = tensor_shape[2]; // 要求输入图片数据的高度
	const size_t channels = tensor_shape[1]; // 要求输入图片数据的维度
	auto image_size = width * height;
	// 读取节点数据内存指针
	float* input_tensor_data = input_tensor.data<float>();
	// 将图片数据填充到网络中
	// 原有图片数据为 H、W、C 格式,输入要求的为 C、H、W 格式
	for (size_t c = 0; c < channels; c++)
	{
		for (size_t h = 0; h < height; h++) 
		{
			for (size_t w = 0; w < width; w++) 
			{
				input_tensor_data[c * image_size + h * width + w] = input_image.at<Vec3f>(h, w)[c];
			}
		}
	}
}

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

	//创建OpenVINO Core
	ov::Core ie;
	ov::CompiledModel compiled_model = ie.compile_model(ir_filename, "AUTO");
	ov::InferRequest infer_request = compiled_model.create_infer_request();

	// 预处理输入数据 - 格式化操作
	cv::VideoCapture cap("D:/images/hatDect.mp4");

	// 获取输入节点tensor
	Tensor input_image_tensor = infer_request.get_tensor("images");
	int input_h = input_image_tensor.get_shape()[2]; //获得"images"节点的Height
	int input_w = input_image_tensor.get_shape()[3]; //获得"images"节点的Width
	int input_c = input_image_tensor.get_shape()[1]; //获得"images"节点的channel
	cout << "input_h:" << input_h << "; input_w:" << input_w << endl;
	cout << "input_image_tensor's element type:" << input_image_tensor.get_element_type() << endl;
	cout << "input_image_tensor's shape:" << input_image_tensor.get_shape() << endl;
	// 获取输出节点tensor
	Tensor output_tensor = infer_request.get_tensor("output");
	int out_rows = output_tensor.get_shape()[1]; //获得"output"节点的out_rows
	int out_cols = output_tensor.get_shape()[2]; //获得"output"节点的Width
	cout << "out_cols:" << out_cols << "; out_rows:" << out_rows << endl;

	//连续采集处理循环
	while (true) {

		Mat frame, image;
		cap >> frame;
		//cvShow("frame", frame);

		int64 start = cv::getTickCount();
		frame.copyTo(image);
		//cvShow("image", image);

		float x_factor = image.cols / input_w;
		float y_factor = image.rows / input_h;

		cv::Mat blob_image;
		cv::resize(image, blob_image, cv::Size(input_w, input_h));
		cv::cvtColor(blob_image, blob_image, cv::COLOR_BGR2RGB);
		blob_image.convertTo(blob_image, CV_32F, 1.0 / 255);

		// 将图片数据填充到tensor数据内存中
		fill_tensor_data_image(input_image_tensor, blob_image);

		// 执行推理计算
		infer_request.infer();

		// 获得推理结果
		const ov::Tensor& output_tensor = infer_request.get_tensor("output");

		// 解析推理结果,YOLOv5 output format: cx,cy,w,h,score
		cv::Mat det_output(out_rows, out_cols, CV_32F, (float*)output_tensor.data());

		vector<cv::Rect> boxes;
		vector<int> classIds;
		vector<float> confidences;

		for (int i = 0; i < det_output.rows; i++) 
		{
			float confidence = det_output.at<float>(i, 4);
			if (confidence < 0.4)
			{
				continue;
			}
			cv::Mat classes_scores = det_output.row(i).colRange(5, 7);
			cv::Point classIdPoint;
			double score;
			cv::minMaxLoc(classes_scores, 0, &score, 0, &classIdPoint);

			// 置信度 0~1之间
			if (score > 0.5)
			{
				float cx = det_output.at<float>(i, 0);
				float cy = det_output.at<float>(i, 1);
				float ow = det_output.at<float>(i, 2);
				float oh = det_output.at<float>(i, 3);
				int x = static_cast<int>((cx - 0.5 * ow) * x_factor);
				int y = static_cast<int>((cy - 0.5 * oh) * y_factor);
				int width = static_cast<int>(ow * x_factor);
				int height = static_cast<int>(oh * y_factor);
				cv::Rect box;
				box.x = x;
				box.y = y;
				box.width = width;
				box.height = height;

				boxes.push_back(box);
				classIds.push_back(classIdPoint.x);
				confidences.push_back(score);
			}
		}
		// NMS
		vector<int> indexes;
		cv::dnn::NMSBoxes(boxes, confidences, 0.25, 0.45, indexes);
		for (size_t i = 0; i < indexes.size(); i++) 
		{
			int index = indexes[i];
			int idx = classIds[index];
			cv::rectangle(frame, boxes[index], cv::Scalar(0, 0, 255), 2, 8);
			cv::rectangle(frame, cv::Point(boxes[index].tl().x, boxes[index].tl().y - 20),
				cv::Point(boxes[index].br().x, boxes[index].tl().y), cv::Scalar(0, 255, 255), -1);
			cv::putText(frame, class_names[idx], cv::Point(boxes[index].tl().x, boxes[index].tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .5, cv::Scalar(0, 0, 0));
		}

		// 计算FPS render it
		float t = (cv::getTickCount() - start) / static_cast<float>(cv::getTickFrequency());
		cout << "Infer time(ms): " << t * 1000 << "ms; Detections: " << indexes.size() << endl;
		putText(frame, cv::format("FPS: %.2f", 1.0 / t), cv::Point(20, 40), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 0, 0), 2, 8);
		cv::imshow("YOLOv5-6.1 + OpenVINO 2022.1 C++ Demo", frame);

		char c = cv::waitKey(60);
		if (c == 27) 
		{ // ESC
			break;
		}
	}

	cv::waitKey(0);
	cv::destroyAllWindows();

	return 0;
}

这里难点一个是图像载入模型

for (size_t c = 0; c < channels; c++)
	{
		for (size_t h = 0; h < height; h++) 
		{
			for (size_t w = 0; w < width; w++) 
			{
				input_tensor_data[c * image_size + h * width + w] = input_image.at<Vec3f>(h, w)[c];
			}
		}
	}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
YOLOv5是一种流行的目标检测算法,而OpenVINO 2022是一款用于深度学习模型部署和加速推理的工具包。结合使用YOLOv5OpenVINO 2022可以实现高效的目标检测应用部署。 使用OpenVINO 2022部署YOLOv5的推理有以下步骤: 1. 安装OpenVINO 2022:首先需要下载和安装OpenVINO 2022工具包。安装完成后,配置OpenVINO的环境变量等设置。 2. 模型转换:YOLOv5的原始模型是使用PyTorch训练的,为了能够在OpenVINO中进行推理,需要将模型转换为OpenVINO支持的IR(Intermediate Representation)格式。可以使用OpenVINO提供的Model Optimizer工具来完成模型转换,具体命令如下: ```bash mo.py --input_model <path_to_yolov5_model> --model_name yolov5 -o <output_dir> --data_type FP16 ``` 这里的`<path_to_yolov5_model>`是原始YOLOv5模型的路径,`<output_dir>`是转换后的IR模型的输出目录,`--data_type`指定了推理过程中使用的数据精度,可以根据需求选择FP16或FP32。 3. 推理应用开发:根据使用场景和需求,使用OpenVINO提供的API开发推理应用程序。可以使用C++、Python等主流编程语言进行开发,OpenVINO提供了相应的API接口供开发者使用。开发过程中需要加载转换后的模型文件,并进行图像的预处理、推理计算等操作。 4. 编译和优化:使用OpenVINO提供的Model Optimizer工具,可以对推理应用进行编译和优化,以提高推理性能。具体命令如下: ```bash mo.py --input_model <model_xml> --model_name yolov5 --output_dir <output_dir> --data_type FP16 --batch 1 ``` 这里的`<model_xml>`是前面转换得到的IR模型的路径,`<output_dir>`是优化后的模型文件的输出目录,`--batch`指定了模型的批处理大小,可以根据需求进行调整。 5. 部署和推理:在部署和推理阶段,可以将优化后的模型和开发的应用程序部署到目标设备上,并进行推理计算。OpenVINO提供了适用于多种硬件平台的推理引擎,可以选择合适的推理引擎来进行部署。 综上所述,使用OpenVINO 2022部署YOLOv5的推理需要进行模型转换、推理应用开发、编译和优化等步骤。通过结合YOLOv5OpenVINO 2022,可以实现高效的目标检测应用部署和推理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值