为.NET打开新大门:OpenVINO.NET开源项目全新发布

在AI的应用越来越广泛的今天,优化深度学习模型并进行推理部署已经成为了一门必要的技术。Intel开发的OpenVINO工具包(Open Visual Inference and Neural network Optimization)就是这样一款强大的工具。作为一个开源的工具包,OpenVINO为开发者提供了强大的深度学习模型优化和推理功能,支持跨不同的Intel硬件平台进行部署,包括CPU, 集成GPU, Intel Movidius VPU, 和FPGAs。该工具包的初衷就是实现一处编码后,能在任何地方部署的机器学习推理的解决方案。

然而在与深度学习模型推理打交道的过程中,我逐渐发现原本我基于百度飞桨paddlepaddle开发过的PaddleSharp项目在CPU推理OCR性能方面,同样的模型,OpenVINO的性能更胜一筹。于是我开始关注OpenVINO,发现它的C API对于.NET世界来说并没有一个合适且高质量的封装。市面上的一部分封装可能只是为了满足特定项目的需求,功能不够完善;有些虽然功能完善但命名规范可能不符合.NET社区规范;有些在错误处理和性能方面存在问题,或者无法做到跨平台,这与OpenVINO的跨平台性矛盾。.NET世界亟需一个更高质量的OpenVINO封装,而我感觉我有能力去努努力。因此,我在今年的节前立下了flag——国庆期间大干一票,开始了OpenVINO.NET的开源之旅。

如何使用

NuGet包简介

使用OpenVINO.NET,最简单的方法不是克隆我的Github库(但欢迎star),而是使用我发布的NuGet包,一般它需要配合OpenCVSharp4一起使用,因此你通常可以安装下面4个NuGet:

  • Sdcb.OpenVINO
  • Sdcb.OpenVINO.runtime.win-x64
  • OpenCvSharp4
  • OpenCvSharp4.runtime.win

OpenCvSharp4一样,我发布的包也包含.NET PInvoke包和平台动态链接库包,如上Sdcb.OpenVINO为.NET PInvoke包,Sdcb.OpenVINO.runtime.win-x64为兼容Windows平台的动态链接库包,里面包含了一些dll。

如果是基于Linux,我专门发布了一个镜像用于减轻部署压力:sdflysha/openvino-base,这个镜像基于.NET 7 SDK的Ubuntu 22.04版本,包含了OpenCvSharp 4.8的运行时和所有OpenVINO的运行时依赖,要使用这个镜像,需将.NET项目第一行的FROM mcr.microsoft.com/dotnet/runtime改为FROM sdflysha/openvino-base,使用时当然也需要安装ubuntu 22.04平台的动态链接库包:Sdcb.OpenVINO.runtime.ubuntu.22.04-x64

实际上我发布了8种不同平台的NuGet包,这是所有我此项目新发布的NuGet包列表:

包名 版本号 简介
Sdcb.OpenVINO .NET PInvoke
Sdcb.OpenVINO.runtime.centos.7-x64 CentOS 7 x64
Sdcb.OpenVINO.runtime.debian.9-arm Debian 9 ARM
Sdcb.OpenVINO.runtime.debian.9-arm64 Debian 9 ARM64
Sdcb.OpenVINO.runtime.rhel.8-x64 RHEL 8 x64
Sdcb.OpenVINO.runtime.ubuntu.18.04-x64 Ubuntu 18.04 x64
Sdcb.OpenVINO.runtime.ubuntu.20.04-x64 Ubuntu 20.04 x64
Sdcb.OpenVINO.runtime.ubuntu.22.04-x64 Ubuntu 22.04 x64
Sdcb.OpenVINO.runtime.win-x64 Windows x64

有兴趣的朋友一定会想,发布并维护这么多包做起来一定很麻烦。其实还好,感谢我此前PaddleSharp项目的经验(那个项目也维护了一屏幕的包),我基于官网的filetree.json做了一些解析,它可以一键自动下载并生成上面这些NuGet包,有兴趣的朋友可以看看我Github中Sdcb.OpenVINO.NuGetBuilder这个项目了解我是如何解析并自动创建NuGet包的。

API设计

和我此前做过的PaddleSharp, Sdcb.LibRaw, Sdcb.Arithmetic, Sdcb.FFmpeg等开源项目相似,我这个项目也秉持下面这些原则:

  1. 完全支持低级C API,也就是说如果你更享受原汁原味的C API的感觉——或者像我一样不想失去对低层的掌控,使用OpenVINO.NET可以满足这一期望;
  2. 同时也为所有的低级API提供了便利好用的高层API;
  3. 高层API符合C#的命名规范,完全利用了C#的优秀特性,做好了异常错误处理;
  4. 高层API使用了C#世界有利于性能优化的特性,如ReadOnlySpan<T>,比如恰当使用值类型;
  5. 所有的高层API都提供了完善了XML注释,并经过了详尽的单元测试;
  6. 此外我还控制了我携带的“私货”——没必要做成公有的API一律做成internalprivate,且不污染常用类型的扩展方法

目前这个项目已经基本稳定,基于这些API,我测试发现它和C/C++推理性能几乎并无差异,PaddleOCR推理时,性能可以比PaddleSharp项目快得多,且得益于C#的优秀语言特性,使用起来会非常的省心。

设计FAQ:

  • Q: 为何OpenVINO.NET没有直接引用OpenCvSharp4

    • A: 我个人很喜欢OpenCvSharp4,开源协议很友好,但一来OpenCvSharp4官方支持的平台不够多,且有些人可能更喜欢Emgu.CVImageSharp,尽量不做绑架为好
  • Q: C API有158个函数接口、26个接口体,也写了详尽的XML注释,是怎么在短时间内高质量地做到的?
    • A: 我是自动生成的,我使用了CppSharp项目,CppSharp将C API的头文件内容转换为抽象语法树(AST),然后我将这些AST转换为XML注释详尽的C#代码。其实我已经不是第一次将CppSharp应用到开源项目中,有兴趣的朋友可以看我Github Sdcb.OpenVINO.AutoGen这个项目了解实现的细节。

为想了解如何使用的朋友,我还写了基于yolov8的检测和分类的推理示例,OpenVINO官方的人脸检测示例以及我为它原生设计和迁移的PaddleOCR项目。另外我还想畅谈一下项目的设计思路和未来的发展方向。

4个示例

人脸检测 - 基于OpenVINO官网提供的face-detection-0200模型

我这个示例中使用的是OpenVINO官网提供的face-detection-0200模型,官网提供了介绍页面:https://docs.openvino.ai/2023.1/omz_models_model_face_detection_0200.html。

详尽的示例代码可以从我创建的mini-openvino-facedetection这个Github仓库找到,运行时,它会将摄像头中定位人脸位置并框出来,效果图如下:

如图,人脸识别效果正常,上面也标注了每帧推理耗时(约2.14ms)。

我使用的是AMD R7 5800X进行的CPU推理,其实代码也支持Intel的GPU。将DeviceOptions的第一个参数从"CPU"(默认值)改为"GPU"即可,但我只有集成显卡,测试发现虽然能正常工作,且CPU使用率降低了且GPU使用率上升了,但GPU推理时间比CPU还更慢。

物体识别 - 基于yolov8模型的物体分类

在上一个例子中,我们已经看到了如何使用OpenVINO.NET进行人脸检测。接下来,我们再来看一下如何使用物体识别模型进行物体分类。

这个示例使用的是yolov8官网下载的YOLOv8n模型,这个模型支持80种物体的检测。下载后格式为.pt文件,表示pytorch模型,需使用yolo export model=yolov8n.pt format=openvino命令(yolo通过pip安装ultralytics包得到)将其导出为openvino格式的模型,openvino模型包含一个xml和一个bin文件。

详尽的示例代码可以从我创建的另一个仓库:sdcb-openvino-yolov8-det中找到,仓库我我已经将模型转换好了。运行时,代码会读取摄像头的每一帧,并将检测到的物体位置框出来,效果图如下:

如图,检测出了3个物体,画面中的人、手机和水杯,总耗时约30ms。

物体分类 - 基于yolov8的分类模型

yolov8模型提供了1000种不同的预定义分类,和上面的模型一样,需要从yolov8官网下载并转换,只想快速尝鲜的朋友可以直接打开我写的另一个Github示例:sdcb-openvino-yolov8-cls

运行时,代码会读取一张图片,然后尝试推测出该图片最像1000种分类中的哪一种,在我的代码示例中,输入图片为hen.jpg:

输出如下:

class id=hen, score=0.59
preprocess time: 0.00ms
infer time: 1.65ms
postprocess time: 0.49ms
Total time: 2.14ms

推理得到最有可能的分类是hen(母鸡),信心值为0.59,总耗时2.14ms。

PaddleOCR - 混合3种模型

PaddleOCR是百度飞桨发布了一款性能、精度都较好的开源模型。

和PaddleSharp项目一样,我给OpenVINO.NET项目也内置了PaddleOCR的便利化项目,且API设计和PaddleSharp几乎完全一样,熟悉PaddleSharp的朋友应该可以很轻松地迁移到OpenVINO.NET,我专门为PaddleOCR提供发布了下面2个NuGet包:

包名 版本号 描述
Sdcb.OpenVINO.PaddleOCR OCR主包
Sdcb.OpenVINO.PaddleOCR.Models.Online 包含需在线下载的模型包

加上上面那4个包,运行基于OpenVINO.NET的PaddleOCR需要下载下面这6个包:

  • Sdcb.OpenVINO
  • Sdcb.OpenVINO.runtime.win-x64
  • OpenCvSharp4
  • OpenCvSharp4.runtime.win
  • Sdcb.OpenVINO.PaddleOCR
  • Sdcb.OpenVINO.PaddleOCR.Models.Online

最小代码示例如下:

using OpenCvSharp;
using Sdcb.OpenVINO.PaddleOCR.Models.Online;
using Sdcb.OpenVINO.PaddleOCR.Models;
using Sdcb.OpenVINO.PaddleOCR;
using System.Diagnostics;
using System; FullOcrModel model = await OnlineFullModels.ChineseV3.DownloadAsync(); using Mat src = Cv2.ImDecode(await new HttpClient().GetByteArrayAsync("https://io.starworks.cc:88/paddlesharp/ocr/samples/xdr5450.webp"), ImreadModes.Color); using (PaddleOcrAll all = new(model)
{
AllowRotateDetection = true,
Enable180Classification = true,
})
{
// Load local file by following code:
// using (Mat src2 = Cv2.ImRead(@"C:\test.jpg"))
Stopwatch sw = Stopwatch.StartNew();
PaddleOcrResult result = all.Run(src);
Console.WriteLine($"elapsed={sw.ElapsedMilliseconds} ms");
Console.WriteLine("Detected all texts: \n" + result.Text);
foreach (PaddleOcrResultRegion region in result.Regions)
{
Console.WriteLine($"Text: {region.Text}, Score: {region.Score}, RectCenter: {region.Rect.Center}, RectSize: {region.Rect.Size}, Angle: {region.Rect.Angle}");
}
}

运行效果如下:

elapsed=246 ms
Detected all texts:
高速4X4160MHz数据流
5GHz频段流数多一倍
速度快一倍3
AX5400无线规格的路由器,
5GHz频段采用高速4X4160MHz数据流,
相比市面上主流的AX3000路由器(2X2数据流)
5GHz频段流数多一倍,速度快一倍。
...

耗时为246ms,根据我的测试,实际上第二次运行OpenVINO可以降低到140ms左右,同样的代码PaddleSharp耗时约452ms(PaddleSharp使用MKLDNN,仅测试首次运行),显然使用我的新开源项目OpenVINO.NET更快。

上面完整的可运行代码,可以从我的Github另一个仓库mini-openvino-paddleocr

结语

本文中,我向大家介绍了如何使用我新发布的OpenVINO.NET,并提供了数个生动的示例来演示如何将OpenVINO.NET用于深度学习模型的推理任务。虽然我只展示了四个应用示例,其实它们都可以被看作为学习OpenVINO.NET使用的良好起点。

通过这四个示例,读者可以轻松理解OpenVINO.NET的工作原理,在此基础上扩展将其用于其它模型的推理是加深理解和实践的不二选择。我专注于.NET开源项目,并不断地为全球.NET开发者提供更多的可能性,我尤其期待看到大家将OpenVINO.NET用于自身项目之中。

我相信开源的力量以及它为我们提供的无尽可能性。因此,我将OpenVINO.NET作为开源项目,希望它能帮助所有在寻找高效,便捷的深度学习推理工具的.NET开发者。如果你发现这个项目有用,或者正在使用它,我非常欢迎你能去我的项目主页上给我一个star,这对我将会是巨大的鼓励!你们的使用经验和星标都是我继续进行.NET开源项目工作的动力!

我还创建了一个.NET骚操作技术交流QQ群:495782587,欢迎对.NET“骚”操作感兴趣的朋友加入一起探讨。

最后,如果你对我的业余开源工作感兴趣,并希望获取更多有关我.NET开源项目的信息,也可以关注我的微信公众号:【DotNet骚操作】

让我们一起探索.NET的无尽可能性。期待.NET世界未来的更多精彩!

为.NET打开新大门:OpenVINO.NET开源项目全新发布的更多相关文章

  1. Android 新加几个开源项目

    http://www.androidviews.net  http://www.theultimateandroidlibrary.com test 最低版本: 简介: 地址: 效果图: test A ...

  2. fir.im Weekly - 600个 Android 开源项目汇总

    本期 Weekly 收集了一些热度资源,包含 Android.iOS 开发工具与源码分享,程序员也应该了解的产品运营.设计等 Tips ,希望对你有帮助. 600个Android开源项目汇总 勤劳的 ...

  3. 原创开源项目HierarchyViewer for iOS 2.1 Beta新功能介绍

    回顾 HierarchyViewer for iOS是我们发布的一个开源项目,采用GPL v3.0协议. HierarchyViewer for iOS可以帮助iOS应用的开发和测试人员,在没有源代码 ...

  4. UGUI的优点新UI系统四 开源

    UGUI的优点新UI系统四 开源 新UI系统是开源的,所以开发者可以看到新UI系统实现的源码,并加以修改和使用. 开源授权协议——MIT/X11 Unity所搭载的新UI系统,是在开源授权协议MIT/ ...

  5. Pull Request的正确打开方式(如何在GitHub上贡献开源项目)

    Pull Request的正确打开方式(如何在GitHub上贡献开源项目) GitHub的官方帮助如下: Fork A Repo: https://help.github.com/articles/f ...

  6. 20 个新的且值得关注的 Vue 开源项目

    译者:前端小智作者:Nastassia Ovchinnikova来源:flatlogic.com 个人专栏 ES6 深入浅出已上线,深入ES6 ,通过案例学习掌握 ES6 中新特性一些使用技巧及原理, ...

  7. Post方式打开新窗口

    最近在做一个跟ERP相连的领料网站,用到POST的方法打开新窗口来打印报表 代码转别人的,在这里记一下: javascript代码 function openPostWindow(url, data1 ...

  8. iOS如何用代码控制以不同屏幕方向打开新页面?

    转载:http://blogread.cn/it/article/7765?f=wb#original 代码示例:https://github.com/johnlui/Swift-On-iOS/tre ...

  9. js打开新页面与关闭当前页面

    打开新的窗口window.open("help.html"); window.open("help.html"); 关闭页面<a href="j ...

  10. angularjs 中state.go 跳转并且打开新的浏览器窗口

    包子最近遇到业务人员提的非常无厘头的需求,就是调页面的时候,一定要打开一个新的浏览器窗口...>o<奇葩!!! 但是我的页面都是state.go跳转的呀,我各种百度,发现,貌似state, ...

随机推荐

  1. Linux系统运维之MYSQL数据库集群部署(主主互备)

    一.介绍 既然是部署MYSQL高可用集群环境,就要介绍下MYSQL Replication,MYSQL Replication是MYSQL自带的一个主从复制功能,也就是一台MYSQL服务器向另外一台M ...

  2. Electron App 安装包定制 -- Inno Setup 脚本 Pascal Scripting 初探

    在做 Electron 项目时,有个需求是安装包安装时要给客户机上装上某个软件 在查看 Inno Setup 官网后发现是通过 .iss 脚本编写实现自定义安装过程 可在 .iss 内可以添加脚本为安 ...

  3. H5 WebGL实现水波特效

    前言 零几年刚开始玩电脑的时候,经常在安装程序上看到一种水波特效,鼠标划过去的时候,就像用手在水面划过一样,感觉特别有意思.但是后来,就慢慢很少见过这种特效了.最近突然又想起了这种特效,于是开始折磨怎 ...

  4. Js中几种循环的使用

    在JavaScript中有五种常用的循环,现在来分别介绍一下五种循环的用法. 1.while 当满足条件时进入循环,进入循环后,当条件不满足时,跳出循环.while语句的一般表达式为:while(表达 ...

  5. springboot下使用rabbitMQ之开发配置方式(一)

    springboot下使用rabbitMQ之开发配置方式(一) 距离上次发布博客已经小一年了,这次...嗯,没错,我又回来啦... 本次结合着B站某MQ视频以及最近在MQ上的实践聊一聊个人在使用rab ...

  6. EaselJS 源码分析系列--第三篇

    这一篇分析另外四个稍显高级的显示类 -- Sprite.Movieclip.DOMElement.BitmapText SpriteSheet SpriteSheet 比较简单 它继承自 EventD ...

  7. asp.net core之配置

    简介 配置在asp.net core中可以说是我们必不可少一部分.ASP.NET Core 中的应用程序配置是使用一个或多个配置提供程序执行的. 配置提供程序使用各种配置源从键值对读取配置数据,普通最 ...

  8. python:时间模块dateutil

    安装 pip install python-dateutil dateutil模块主要有两个函数,parser和rrule. 其中parser是根据字符串解析成datetime,而rrule则是根据定 ...

  9. zanePerfor中一套简单通用的Node前后端Token登录机制和github授权登录方式

    HI!,你好,我是zane,zanePerfor是一款我开发的一个前端性能监控平台,现在支持web浏览器端和微信小程序端. 我定义为一款完整,高性能,高可用的前端性能监控系统,这是未来会达到的目的,现 ...

  10. PLE-实践小结-2308-cnblogs

    某场景介绍 前状:三模型,权重融合 解决问题:融合目标行为,充分利用样本信息,节省资源开销. 当前效果 主场景人均真实曝光+0.26%,不显著:子场景人均真实曝光+0.35%,不显著 千曝互动+2.6 ...