【OpenVINO™】使用 OpenVINO™ C# 异步推理接口部署YOLOv8 ——在Intel IGPU 上速度依旧飞起!!

  OpenVINO Runtime支持同步或异步模式下的推理。Async API的主要优点是,当设备忙于推理时,应用程序可以并行执行其他任务(例如,填充输入或调度其他请求),而不是等待当前推理首先完成。 当我们使用异步API时,第二个请求的传输与第一个推理的执行重叠,这防止了任何硬件空闲时间。

  在上一篇文章中我们已经实现了使用OpenVINO™ C++ 异步API接口部署YOLOv8 实现视频快速推理,得到了大家的一致肯定。一些C#开发者也想在使用OpenVINO™在C#中实现异步推理,那么该如何实现呢?那么他来了,下面我们将会演示如何使用OpenVINO™异步接口在C#中部署YOLOv8 实现视频快速推理。首先我们看一下两种不同的推理方式其效果差异:

异步推理效果同步推理效果
150150

1. OpenVINO™ C# API

  英特尔发行版 OpenVINO™ 工具套件基于 oneAPI 而开发,可以加快高性能计算机视觉和深度学习视觉应用开发速度工具套件,适用于从边缘到云的各种英特尔平台上,帮助用户更快地将更准确的真实世界结果部署到生产系统中。通过简化的开发工作流程,OpenVINO™ 可赋能开发者在现实世界中部署高性能应用程序和算法。

image-20240620130218162

OpenVINO™ C# API 是一个 OpenVINO™ 的 .Net wrapper,应用最新的 OpenVINO™ 库开发,通过 OpenVINO™ C API 实现 .Net 对 OpenVINO™ Runtime 调用,使用习惯与 OpenVINO™ C++ API 一致。OpenVINO™ C# API 由于是基于 OpenVINO™ 开发,所支持的平台与 OpenVINO™ 完全一致,具体信息可以参考 OpenVINO™。通过使用 OpenVINO™ C# API,可以在 .NET、.NET Framework等框架下使用 C# 语言实现深度学习模型在指定平台推理加速。

2. OpenVINO™ C# 异步接口

2.1 创建推断请求

  可以从以下位置创建:InferRequest

var infer_request = compiled_model.create_infer_request();

InferRequest可以运行推理,支持同步和异步模式进行推理。

2.2 同步模式

InferRequest.infer可以使用来阻止应用程序执行,以同步模式下进行模型推理。

infer_request.infer();

2.3 异步模式

  异步模式可以提高应用程序的整体帧速率,方法是使其在加速器繁忙时在主机上工作,而不是等待推理完成。要在异步模式下推断模型,需要使用InferRequest.start_async接口。

infer_request.start_async();

  异步模式支持应用程序等待推理结果的两种方式:

InferRequest.wait_for:指定阻止方法的最大持续时间(以毫秒为单位)。该方法将被阻止,直到指定的时间过去,或者结果变得可用,以先到者为准。

infer_request.wait_for(long timeout);

InferRequest.wait:等到推理结果可用

infer_request.wait();

  其中这两种等待推理结果的方法都是线程安全的。

3. 项目环境

  • 推理设备:OpenVINO IGPU
  • CPU: Intel Core i7-1165G7
  • IGPU: Intel Iris Xe Graphics
  • 推理模型: YOLOv8s
  • 视频分辨率:1920×1080

4. 代码实现

4.1 定义YOLOv8数据处理方法

  首先定义了一下YOLOv8模型前后处理的方法,包括输入数据处理接口pre_process(cv::Mat* img, int length, float* factor, std::vector<float>& data)以及预测结果处理接口std::vector<DetResult> post_process(float* result, float factor, int outputLength) ,具体不做过多讲解,代码如下所示:

public static float[] preprocess(Mat img, out float factor)
{Mat mat = new Mat();Cv2.CvtColor(img, mat, ColorConversionCodes.BGR2RGB);mat = Resize.letterbox_img(mat, 640, out factor);mat = Normalize.run(mat, true);return Permute.run(mat);
}public static DetResult postprocess(float[] result, float factor)
{// Storage results listList<Rect> positionBoxes = new List<Rect>();List<int> classIds = new List<int>();List<float> confidences = new List<float>();// Preprocessing output resultsfor (int i = 0; i < 8400; i++){for (int j = 4; j < 84; j++){float source = result[8400 * j + i];int label = j - 4;if (source > 0.2){float maxSource = source;float cx = result[8400 * 0 + i];float cy = result[8400 * 1 + i];float ow = result[8400 * 2 + i];float oh = result[8400 * 3 + i];int x = (int)((cx - 0.5 * ow) * factor);int y = (int)((cy - 0.5 * oh) * factor);int width = (int)(ow * factor);int height = (int)(oh * factor);Rect box = new Rect(x, y, width, height);positionBoxes.Add(box);classIds.Add(label);confidences.Add(maxSource);}}}DetResult re = new DetResult();int[] indexes = new int[positionBoxes.Count];CvDnn.NMSBoxes(positionBoxes, confidences, 0.2f, 0.5f, out indexes);for (int i = 0; i < indexes.Length; i++){int index = indexes[i];re.add(classIds[index], confidences[index], positionBoxes[index]);}return re;
}

4.2 异步推理实现

  与在C++一致,在C#中进行异步推理时,需要创建两个以上的推理通道InferRequest,首先读取第一帧数据并将其添加在第一个推理通道上,并开启异步推理;然后读取下一帧视频数据,并加载到另一个推理通道上;接着等待上一帧数据推理是否结束,如果结束,便会读取推理结果,进行结果处理;接着读取下一帧数据,并将推理结果加载到对应的通道上,依次往复,便可以实现视频数据的异步推理。

static void yolov8_async_det()
{string video_path = "E:\\ModelData\\NY.mp4";string model_path = "E:\\Model\\yolo\\yolov8s.onnx";Core core = new Core();Model model = core.read_model(model_path);CompiledModel compiled_model = core.compile_model(model, "GPU");VideoCapture capture = new VideoCapture(video_path);if (!capture.IsOpened()){Console.WriteLine("ERROR: 视频无法打开");return;}List<InferRequest> requests = new List<InferRequest> { compiled_model.create_infer_request(), compiled_model.create_infer_request() };Mat frame = new Mat();capture.Read(frame);float factor = 0f;float[] input_data = preprocess(frame, out factor);requests[0].get_input_tensor().set_data(input_data);requests[0].start_async();Stopwatch sw = new Stopwatch();float[] total_infs = new float[3];while (true){Mat next_frame = new Mat();if (!capture.Read(next_frame)){break;}sw.Restart();input_data = preprocess(frame, out factor);requests[1].get_input_tensor().set_data(input_data);sw.Stop();total_infs[0] = sw.ElapsedMilliseconds;sw.Restart();requests[1].start_async();requests[0].wait();sw.Stop();total_infs[1] = sw.ElapsedMilliseconds;sw.Restart();float[] output_data = requests[0].get_output_tensor().get_data<float>(8400 * 84);DetResult result = postprocess(output_data, factor);sw.Stop();total_infs[2] = sw.ElapsedMilliseconds;Cv2.PutText(frame, "PreProcess: " + (1000.0 / total_infs[0]).ToString("0.00") + "FPS  " + (total_infs[0]).ToString("0.00") + "ms",new Point(20, 40), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 255), 2);Cv2.PutText(frame, "Inference: " + (1000.0 / total_infs[1]).ToString("0.00") + "FPS  " + (total_infs[1]).ToString("0.00") + "ms",new Point(20, 70), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 255), 2);Cv2.PutText(frame, "PostProcess: " + (1000.0 / total_infs[2]).ToString("0.00") + "FPS  " + (total_infs[2]).ToString("0.00") + "ms",new Point(20, 100), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 255), 2);Cv2.PutText(frame, "Total: " + (1000.0 / (total_infs[0] + total_infs[1] + total_infs[2])).ToString("0.00")+ "FPS   " + ((total_infs[0] + total_infs[1] + total_infs[2])).ToString("0.00") + "ms",new Point(20, 130), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 255), 2);Mat res_mat = Visualize.draw_det_result(result, frame);Cv2.ImShow("Result", res_mat);Cv2.WaitKey(10);swap(requests);frame = next_frame;}
}

  上面已经展示了该项目实现的全部代码,如果想获取项目文件,通过下面链接进行下载:

ttps://download.csdn.net/download/Grape_yan/89460175

5. 时间测试

写完代码后,对同步接口以及异步推理接口进行了时间测试,如下表所示:

APIPrePocessInferencePostProcessTotalFPS
Sync11.97 ms34.68 ms1.58 ms48.23 ms20.73
Async14.26 ms0.01 ms1.22 ms15.49 ms64.56

  其中同步推理一帧平均推理时间为48.23毫秒,而异步接口一帧平均推理时间仅为15.49毫秒,异步接口一秒钟平均可以实现64.56FPS的推理,是同步推理的3.11倍,速度快到飞起!!之前我们已经测试过C++异步推理时间,如下表所示:

APIPrePocessInferencePostProcessTotalFPS
Sync9.83 ms33.18 ms0.1 ms43.02 ms23.25
Async11.27 ms0.02 ms0.08 ms11.37 ms87.98

6. 总结

  在该项目中,我们实现了在C#中使用OpenVINO异步模式下的推理,并和同步推理进行了对比,异步推理速度提升了3.78倍,并且在没有进行任何优化掉前提下,使用集成显卡中便实现了视频的快速推理。

   最后如果各位开发者在使用中有任何问题,欢迎大家与我联系。

个人账号 - 2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/30801.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Type-C诱骗芯片LDR6500

随着科技的飞速发展&#xff0c;电子设备的智能化和便携化已成为趋势。在这个过程中&#xff0c;Type-C接口因其高速传输、正反可插以及强大的扩展能力&#xff0c;逐渐成为主流接口标准。然而&#xff0c;Type-C接口的广泛应用也带来了一系列挑战&#xff0c;其中之一便是如何…

千呼新零售2.0【更新日志】持续更新ing

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看下…

存u盘里的视频没删除找不到了怎么办?别急,这几招来帮您

在数字化时代&#xff0c;U盘已成为我们随身携带、存储和传输文件的重要设备。然而&#xff0c;有时我们会突然发现存放在U盘中的视频文件不翼而飞&#xff0c;这常常让我们感到困扰和焦虑。视频文件可能包含了重要的工作资料、珍贵的家庭记忆或是无法再找回的独特素材。面对这…

股票交易系统

效果展示&#xff0c;如下动图&#xff1a; 首先简述一下股票交易规则&#xff1a; 买卖股票&#xff0c;股民可以自行选择股票的买入或卖出价格和股票的数量&#xff0c;但是用户不一定马上就交易成功&#xff0c;只有当股票价格低于买入价才有机会买入&#xff0c;高于卖出价…

startActivity启动流程

从桌面点击应用图标开始到Activity创建并执行onCreate&#xff0c;activity的启动涉及到两个进程system_server(AMS所在进程)和Zygote(如果进程没有创建需要先创建) 下图是从点击图标开始执行startActivity&#xff0c;一直到ActivityTaskSupervisor&#xff0c;到ActivityTas…

2004年下半年软件设计师【下午题】试题及答案

文章目录 2004年下半年软件设计师下午题--试题2004年下半年软件设计师下午题--答案2004年下半年软件设计师下午题–试题

Python爬虫小白入门(四)PhatomJS+Selenium篇下

一、前言 前文介绍了PhatomJS 和Selenium 的用法&#xff0c;工具准备完毕&#xff0c;我们来看看如何使用它们来改造我们之前写的小爬虫。 我们的目的是模拟页面下拉到底部&#xff0c;然后页面会刷出新的内容&#xff0c;每次会加载10张新图片。 大体思路是&#xff0c;用S…

RuoYi-Vue-Plus(vue3)点击字典详情页面报404

复现过程&#xff1a; 1.新增菜单目录&#xff0c;设置目录路由地址为data 2.打开字典管理 -》 点击字典数据 -》 页面404 路由地址不允许重复 如果设置的地址重复就把字典顶掉l 建菜单的时候 这个路由名称不要使用data 后添加的/data 默认首字母大写 name为Data 覆盖了字典详…

网络文化经营许可证:互联网时代的护航之舵

文网文由中国文化和旅游部&#xff08;原文化部&#xff09;颁发&#xff0c;旨在对网络文化活动进行规范管理&#xff0c;确保文化内容的健康积极。通过对文化市场的严格监管&#xff0c;文网文有效杜绝了低俗、违法、侵权等不良现象的发生。网络文化市场的良性发展&#xff0…

2024年【N1叉车司机】作业考试题库及N1叉车司机实操考试视频

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年N1叉车司机作业考试题库为正在备考N1叉车司机操作证的学员准备的理论考试专题&#xff0c;每个月更新的N1叉车司机实操考试视频祝您顺利通过N1叉车司机考试。 1、【多选题】《中华人民共和国特种设备安全法》第…

计算机专业毕设-springboot论坛系统

1 项目介绍 基于SSM的论坛网站&#xff1a;后端 SpringBoot、Mybatis&#xff0c;前端thymeleaf&#xff0c;具体功能如下&#xff1a; 基本功能&#xff1a;登录注册、修改个人信息、修改密码、修改头像查看帖子列表&#xff1a;按热度排序、按更新时间排序、查看周榜月榜查…

golang去掉前后空格

str : " ce s "str strings.TrimSpace(str)fmt.Printf("--%v--", str)

如何移植libwebsockets

libwebsockets是一个高性能的开源C语言库&#xff0c;专为实现WebSocket协议及相关的HTTP协议而设计。它不仅使开发者能够在客户端与服务器端轻松构建WebSocket连接&#xff0c;还可以用作标准HTTP服务器。WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;可以…

卷积神经网络(CNN)理解

1、引言&#xff08;卷积概念&#xff09; 在介绍CNN中卷积概念之前&#xff0c;先介绍一个数字图像中“边缘检测edge detection”案例&#xff0c;以加深对卷积的认识。图中为大小8X8的灰度图片&#xff0c;图片中数值表示该像素的灰度值。像素值越大&#xff0c;颜色越亮&…

视觉应用线扫相机速度反馈(倍福CX7000PLC应用)

运动控制实时总线相关内容请参考运动控制专栏,这里不再赘述 1、运动控制常用单位u/s运动控制单位[u/s]介绍_运动控制 unit是什么单位-CSDN博客文章浏览阅读176次。运动控制很多手册上会写这样的单位,这里的u是英文单词unit的缩写,也就是单位的意思,所以这里的单位不是微米…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 05:糖果机接口

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

Word 文本框技巧2则

1 调整大小 一种方法是&#xff0c;选中文本框&#xff0c;周围出现锚点&#xff0c;然后用鼠标拖动来调整大小&#xff1b; 精确按数值调整&#xff0c;在 格式 菜单下有多个分栏&#xff0c;一般最后一个分栏是 大小 &#xff1b;在此输入高度和宽度的数值&#xff0c;来调整…

MySQL的数据存储一定是基于硬盘吗?

一、典型回答 不是的&#xff0c;MySQL也可以基于内存的&#xff0c;即MySQL的内存表技术。它允许将数据和索引存储在内存中&#xff0c;从而提高了检验速度和修改数据的效率。优点包括具有快速响应的查询性能和节约硬盘存储空间。此外&#xff0c;使用内存表还可以实现更高的复…

【C++】类和对象(三)构造与析构

文章目录 一、类的6个默认成员函数二、 构造函数干嘛的&#xff1f;语法定义特性综上总结什么是默认构造函数&#xff1f; 三、析构函数干嘛的 &#xff1f;语法定义析构顺序 一、类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。空类中并不是真的什么…

Mac数据如何恢复?3 款最佳 Mac 恢复软件

如果您认为 Mac 上已删除的文件永远丢失了&#xff0c;那您就大错特错了&#xff01;实际上&#xff0c;即使您清空了 Mac 上的垃圾箱&#xff0c;也有许多解决方案可以帮助您恢复已删除的文件。最好的解决方案之一是 Mac 恢复删除软件。最好的Mac 恢复删除应用程序可以轻松准确…