OpenVINO 2022.3实战二:Window 10 环境下用 OpenVINO 2022.3部署yolov5-seg 7.0

1 配置OpenVINO C++开发环境

见 OpenVINO 2022.3实战一:Window 10 环境下用 OpenVINO 2022.3部署yolov5 7.0_mingo_敏的博客-CSDN博客

2 下载并转换YOLOv5-Seg预训练模型

下载yolov5代码 ultralytics/yolov5

python export.py --weights yolov5s-seg.pt --include torchscript onnx openvino

导出模型为 yolov5s-seg_openvino_model

3 C++代码

YOLOv5-Seg模型对数据预处理的要求跟YOLOv5模型一样。YOLOv5-Seg模型的输出有两个张量,一个张量输出检测detect(1 x 25200 x 117),一个张量输出proto (1 x 32 x 160x160), 其中第一个张量detect中117个字段为 85 (cx、cy、w、h、confidence和80个类别分数)+ 32分割字段,detect 后32个字段与第二个张量的输出做矩阵乘法,可以获得尺寸为160x160的检测目标的掩码(mask)。

yolov5-seg_openvino.cpp

#pragma warning(disable:4996)#include "yolov5_seg.h"#include <iostream>
#include <string>#include <openvino/openvino.hpp> //include openvino runtime header files
#include <opencv2/opencv.hpp>    //opencv header fileusing namespace std;/* ---------  Please modify the path of yolov5 model and image -----------*/
std::string model_file = "E:/cpp_code/weights/yolov5s-seg_openvino_model/yolov5s-seg.xml";
std::string image_file = "E:/cpp_code/images/zidane.jpg";
std::vector<cv::Scalar> colors = { cv::Scalar(0, 0, 255) , cv::Scalar(0, 255, 0) , cv::Scalar(255, 0, 0) ,cv::Scalar(255, 255, 0) , cv::Scalar(0, 255, 255) , cv::Scalar(255, 0, 255) };const std::vector<std::string> class_names = {"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light","fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow","elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee","skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard","tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple","sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch","potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone","microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear","hair drier", "toothbrush" };cv::Mat letterbox(cv::Mat& img, std::vector<float>& paddings, std::vector<int> new_shape = { 640, 640 })
{// Get current image shape [height, width]// Refer to https://github.com/ultralytics/yolov5/blob/master/utils/augmentations.py#L111int img_h = img.rows;int img_w = img.cols;// Compute scale ratio(new / old) and target resized shapefloat scale = std::min(new_shape[1] * 1.0 / img_h, new_shape[0] * 1.0 / img_w);int resize_h = int(round(img_h * scale));int resize_w = int(round(img_w * scale));paddings[0] = scale;// Compute paddingint pad_h = new_shape[1] - resize_h;int pad_w = new_shape[0] - resize_w;// Resize and pad image while meeting stride-multiple constraintscv::Mat resized_img;cv::resize(img, resized_img, cv::Size(resize_w, resize_h));// divide padding into 2 sidesfloat half_h = pad_h * 1.0 / 2;float half_w = pad_w * 1.0 / 2;paddings[1] = half_h;paddings[2] = half_w;// Compute padding boarderint top = int(round(half_h - 0.1));int bottom = int(round(half_h + 0.1));int left = int(round(half_w - 0.1));int right = int(round(half_w + 0.1));// Add bordercv::copyMakeBorder(resized_img, resized_img, top, bottom, left, right, 0, cv::Scalar(114, 114, 114));return resized_img;
}float sigmoid_function(float a)
{float b = 1. / (1. + exp(-a));return b;
}int yolov5_seg_demo(){// -------- Get OpenVINO runtime version --------std::cout << ov::get_openvino_version().description << ':' << ov::get_openvino_version().buildNumber << std::endl;// -------- Step 1. Initialize OpenVINO Runtime Core --------ov::Core core;// -------- Step 2. Compile the Model --------auto compiled_model = core.compile_model(model_file, "CPU"); //GPU.1 is dGPU A770// -------- Step 3. Create an Inference Request --------ov::InferRequest infer_request = compiled_model.create_infer_request();// -------- Step 4. Read a picture file and do the preprocess --------cv::RNG rng;cv::Mat img = cv::imread(image_file); //Load a picture into memorycv::Mat masked_img;std::vector<float> paddings(3);       //scale, half_h, half_wcv::Mat resized_img = letterbox(img, paddings); //resize to (640,640) by letterbox// BGR->RGB, u8(0-255)->f32(0.0-1.0), HWC->NCHWcv::Mat blob = cv::dnn::blobFromImage(resized_img, 1 / 255.0, cv::Size(640, 640), cv::Scalar(0, 0, 0), true);// -------- Step 5. Feed the blob into the input node of YOLOv5 -------// Get input port for model with one inputauto input_port = compiled_model.input();// Create tensor from external memoryov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), blob.ptr(0));// Set input tensor for model with one inputinfer_request.set_input_tensor(input_tensor);// -------- Step 6. Start inference --------infer_request.infer();// -------- Step 7. Get the inference result --------auto detect = infer_request.get_output_tensor(0);auto detect_shape = detect.get_shape();std::cout << "The shape of Detection tensor:" << detect_shape << std::endl;auto proto = infer_request.get_output_tensor(1);auto proto_shape = proto.get_shape();std::cout << "The shape of Proto tensor:" << proto_shape << std::endl;// --------- Do the Post Process// Detect Matrix: 25200 x 117  cv::Mat detect_buffer(detect_shape[1], detect_shape[2], CV_32F, detect.data());// Proto Matrix:  1x32x160x160 => 32 x 25600cv::Mat proto_buffer(proto_shape[1], proto_shape[2] * proto_shape[3], CV_32F, proto.data());// -------- Step 8. Post-process the inference result -----------float conf_threshold = 0.25;float nms_threshold = 0.5;std::vector<cv::Rect> boxes;std::vector<int> class_ids;std::vector<float> class_scores;std::vector<float> confidences;std::vector<cv::Mat> masks;// cx,cy,w,h,confidence,c1,c2,...c80float scale = paddings[0];for (int i = 0; i < detect_buffer.rows; i++) {float confidence = detect_buffer.at<float>(i, 4);if (confidence < conf_threshold) {continue;}cv::Mat classes_scores = detect_buffer.row(i).colRange(5, 85);cv::Point class_id;double score;cv::minMaxLoc(classes_scores, NULL, &score, NULL, &class_id);// class score: 0~1if (score > 0.25){cv::Mat mask = detect_buffer.row(i).colRange(85, 117);float cx = detect_buffer.at<float>(i, 0);float cy = detect_buffer.at<float>(i, 1);float w = detect_buffer.at<float>(i, 2);float h = detect_buffer.at<float>(i, 3);int left = static_cast<int>((cx - 0.5 * w - paddings[2]) / scale);int top = static_cast<int>((cy - 0.5 * h - paddings[1]) / scale);int width = static_cast<int>(w / scale);int height = static_cast<int>(h / scale);cv::Rect box;box.x = left;box.y = top;box.width = width;box.height = height;boxes.push_back(box);class_ids.push_back(class_id.x);class_scores.push_back(score);confidences.push_back(confidence);masks.push_back(mask);}}// NMSstd::vector<int> indices;cv::dnn::NMSBoxes(boxes, confidences, conf_threshold, nms_threshold, indices);cv::Mat rgb_mask = cv::Mat::zeros(img.size(), img.type());// -------- Step 8. Visualize the detection results -----------for (size_t i = 0; i < indices.size(); i++) {int index = indices[i];int class_id = class_ids[index];cv::Rect box = boxes[index];int x1 = std::max(0, box.x);int y1 = std::max(0, box.y);int x2 = std::max(0, box.br().x);int y2 = std::max(0, box.br().y);cv::Mat m = masks[index] * proto_buffer;for (int col = 0; col < m.cols; col++) {m.at<float>(0, col) = sigmoid_function(m.at<float>(0, col));}cv::Mat m1 = m.reshape(1, 160); // 1x25600 -> 160x160int mx1 = std::max(0, int((x1 * scale + paddings[2]) * 0.25));int mx2 = std::max(0, int((x2 * scale + paddings[2]) * 0.25));int my1 = std::max(0, int((y1 * scale + paddings[1]) * 0.25));int my2 = std::max(0, int((y2 * scale + paddings[1]) * 0.25));cv::Mat mask_roi = m1(cv::Range(my1, my2), cv::Range(mx1, mx2));cv::Mat rm, det_mask;cv::resize(mask_roi, rm, cv::Size(x2 - x1, y2 - y1));for (int r = 0; r < rm.rows; r++) {for (int c = 0; c < rm.cols; c++) {float pv = rm.at<float>(r, c);if (pv > 0.5) {rm.at<float>(r, c) = 1.0;}else {rm.at<float>(r, c) = 0.0;}}}rm = rm * rng.uniform(0, 255);rm.convertTo(det_mask, CV_8UC1);if ((y1 + det_mask.rows) >= img.rows) {y2 = img.rows - 1;}if ((x1 + det_mask.cols) >= img.cols) {x2 = img.cols - 1;}cv::Mat mask = cv::Mat::zeros(cv::Size(img.cols, img.rows), CV_8UC1);det_mask(cv::Range(0, y2 - y1), cv::Range(0, x2 - x1)).copyTo(mask(cv::Range(y1, y2), cv::Range(x1, x2)));add(rgb_mask, cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), rgb_mask, mask);cv::rectangle(img, boxes[index], colors[class_id % 6], 2, 8);std::string label = class_names[class_id] + ":" + std::to_string(class_scores[index]);cv::putText(img, label, cv::Point(boxes[index].tl().x, boxes[index].tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .5, colors[class_id % 6]);cv::addWeighted(img, 0.5, rgb_mask, 0.5, 0, masked_img);}cv::namedWindow("YOLOv5-Seg OpenVINO Inference C++ Demo");cv::imshow("YOLOv5-Seg OpenVINO Inference C++ Demo", masked_img);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

OpenVINO 2022.3实战二:Window 10 环境下用 OpenVINO 2022.3部署yolov5-seg 7.0相关推荐

  1. WIndow 10 环境下使用CURL工具完成企业微信机器人的提醒功能

    企业微信机器人提醒功能实现说明 本文档主要讲解企业微信机器人的提醒功能的在window下的实现方法,主要内容包括机器人的创建,CURL工具使用环境的搭建和最终实现消息提醒功能三个主要模块.企业微信机器 ...

  2. OpenVINO之二:Windows环境下OpenVINO安装与配置

    OpenVINO系列: OpenVINO之一:OpenVINO概述 OpenVINO之二:Windows环境下OpenVINO安装与配置 OpenVINO之三:Linux环境下OpenVINO安装与配 ...

  3. 【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发...

    <ASP.NET Core 微服务实战>译者序:https://blog.jijiechen.com/post/aspnetcore-microservices-preface-by-tr ...

  4. 【云原生之kubernetes实战】在k8s环境下部署Snipe-IT固定资产管理平台

    [云原生之kubernetes实战]在k8s环境下部署Snipe-IT固定资产管理平台 一.Snipe-IT介绍 二.检查本地k8s环境 1.检查工作节点状态 2.检查系统pod状态 3.检查kube ...

  5. 【云原生之kubernetes实战】在k8s环境下部署OneNav个人书签工具

    [云原生之kubernetes实战]在k8s环境下部署OneNav个人书签工具 一.OneNav介绍 1.OneNav简介 2.OneNav特点 二.检查本地k8s环境 1.检查工作节点状态 2.检查 ...

  6. 【云原生之kubernetes实战】在k8s环境下部署Homepage个人导航页

    [云原生之kubernetes实战]在k8s环境下部署Homepage个人导航页 一.Homepage简介 二.检查本地k8s环境 1.检查工作节点状态 2.检查系统pod状态 三.安装docker- ...

  7. Docker Toolbox在window 10 home 下挂载宿主机目录到容器的正确操作

    Docker Toolbox在window 10 home 下挂载宿主机目录到容器的正确操作 原文:Docker Toolbox在window 10 home 下挂载宿主机目录到容器的正确操作 由于我 ...

  8. 计算机网络组建对等网,计算机网络实验二组建WINDOWS环境下的对等网并共享资源.pdf...

    实验课程名称 计算机网络实验 专 业 班 级 学 生 姓 名 学 号 指 导 教 师 2012 至 2013 学年第 一 学期第 1 至 18 周 <计算机网络实验>实验报告 __2012 ...

  9. Docker环境下的前后端分离部署与运维 脚本

    <Docker环境下的前后端分离部署与运维>脚本 文章目录 <Docker环境下的前后端分离部署与运维>脚本 一.Docker虚拟机常用命令 二.安装PXC集群,负载均衡,双机 ...

最新文章

  1. 安装python程序后要进行什么设置-安装好Pycharm后如何配置Python解释器简易教程...
  2. java的final修饰_java final 修饰符详解
  3. for oracle中pivot_Oracle PIVOT 行转列方法
  4. Android布局Include的好处,Android布局之include文件的使用中的疑难杂症
  5. 7-1 最长连续递增子序列 (20 分)
  6. MYSQL小函数大用途之-------FIND_IN_SET
  7. 微信小程序 View:flex 布局
  8. 阿里云搭建图片服务器,图片资源服务器搭建
  9. 跟计算机断层扫描相关的技术,数字化X线摄影设备、计算机断层扫描设备和相关方法与流程...
  10. XGBOOST的基本原理以及使用
  11. 阿里巴巴国际站 网站和PC客户端都登录不了,其他电脑或手机可以
  12. 「Python入门」Python代码规范(风格)
  13. mysql怎么查询借阅相同图书_MySQL查询练习2
  14. Macaca 使用实践——阿里开源自动化解决方案
  15. 2020黑客大会——深入浅出现代Windows Rootkit
  16. 大学生创业之火如何再次燎原
  17. 90后在校大学生开旅游公司创业
  18. 按钮(click button)
  19. 【C++】STL —— unordered_map/unordered_set的基本使用
  20. SM2加密解密工具类

热门文章

  1. 为什么html中无序排列点的颜色和大小变了
  2. 超码、候选码、主码、主属性、非主属性
  3. php $str1=,PHP——字符串
  4. Core Web Vitals和Mobile-First Indexing来袭,中国跨境电商平台的Web性能优化之道
  5. 苹果开发者账号提示“Unable to verify mobile phone number”的解决方案
  6. 下面个人免费版的xshell
  7. 【离散数学】偏序和全序的区别与解释、哈斯图
  8. 用户画像的相关个人笔记
  9. 利用递归函数求斐波那契数列(兔子数列)
  10. 中间件 - metaQ