YOLO-World是一个融合了实时目标检测与增强现实(AR)技术的创新平台,旨在将现实世界与数字世界无缝对接。该平台以YOLO(You Only Look Once)算法为核心,实现了对视频中物体的快速准确识别,并通过AR技术将虚拟元素与真实场景相结合,为用户带来沉浸式的交互体验。在本文中,我们将结合OpenVINO C# API 使用最新发布的OpenVINO 2024.0部署 YOLO-World实现实时开放词汇对象检测:

OpenVINO C# API项目链接:

https://github.com/guojin-yan/OpenVINO-CSharp-API.git

使用 OpenVINO C# API 部署 YOLO-World全部源码:

https://github.com/guojin-yan/OpenVINO-CSharp-API-Samples/tree/master/model_samples/yolo-world/yolo-world-opencvsharp-net4.8

1. 前言

1.1 OpenVINO C# API

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

2024年3月7日,英特尔发布了开源 OpenVINO 2024.0 工具包,用于在各种硬件上优化和部署人工智能推理。OpenVINO 是英特尔出色的开源 AI 工具包,不仅可以在 x86_64 CPU 上加速 AI 推断,还可以在 ARM CPU 和其他架构、英特尔集成显卡和独立显卡等硬件上加速 AI 推断,包括最近推出的 NPU 插件,用于利用新酷睿超 “Meteor Lake “系统芯片中的英特尔神经处理单元。 OpenVINO 2024.0 更注重生成式人工智能(GenAI),为 TensorFlow 句子编码模型提供了更好的开箱即用体验,支持专家混合(MoE)。同时还提高了 LLM 的 INT4 权重压缩质量,增强了 LLM 在英特尔 CPU 上的性能,简化了 Hugging Face 模型的优化和转换,并改进了其他 Hugging Face 集成。

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# 语言实现深度学习模型在指定平台推理加速。

1.2 YOLO-World

YOLO-World是一种创新的实时开放词汇对象检测技术,由腾讯AI实验室开发。它旨在解决传统目标检测方法在开放场景中受预定义类别限制的问题,通过视觉语言建模和大规模数据集预训练,增强了YOLO系列检测器对开放词汇的检测能力。

该技术的核心思想在于,利用一个可重参数化的视觉语言路径聚合网络(RepVL-PAN)来连接文本和图像特征,并引入基于区域的文本对比损失进行预训练。这种设计使得YOLO-World能够在没有见过具体样本的情况下,检测出广泛的物体类别。同时,它还能在保持高性能的同时,降低计算要求,从而适用于实时应用。

通过这种方式,YOLO-World能够增强对开放词汇的检测能力,使其能够在没有预先定义类别的情况下识别出广泛的物体。这种能力使得YOLO-World在实时应用中,如自动驾驶、视频监控、工业质检等领域具有广泛的应用前景。同时,YOLO-World还通过优化模型架构和训练策略,实现了高性能和实时性的平衡。它能够在保持高准确率的同时,降低计算要求,从而满足实际应用中对于实时性的需求。

总的来说,YOLO-World是一种高效、实时且灵活的开放词汇目标检测器,具有广泛的应用前景和巨大的潜力。它不仅能够解决传统目标检测方法在开放场景中的局限性,还能够为各行业提供实时、准确的物体检测解决方案。

2. 模型获取

YOLO-World模型可以通过YOLO-World GitHub获取,小编尝试了一下,步骤比较复杂,且配置起来比较麻烦,因此如果是初学者,不建议使用,下面介绍一个比较简单的导出方式:通过Ultralytics 导出。

Ultralytics 提供了一系列用于计算机视觉任务的工具,包括目标检测、图像分类、语义分割和人脸识别等。这些工具基于流行的深度学习框架如PyTorch,并通过简化复杂任务的实现过程,使用户能够更轻松地进行模型训练和性能评估。

  • 首先安装Ultralytics 环境:

Ultralytics 可以通过pip安装,在环境中输入以下指令即可:

pip install ultralytics
  • 然后通过Python导出模型:

模型导出代码如下所示:

from ultralytics import YOLO
# Initialize a YOLO-World model
model = YOLO('yolov8s-worldv2.pt')
# Define custom classes
model.set_classes(["person", "bus"])
# Export the model
model.export(format='onnx')

模型导出后结构如下图所示:

与其他模型不同的时,YOLO-World模型在推理时需要指定目标对象名称,因此其输入包括一个目标对象名称的节点,但是目前ONNX模型不支持字符输入。因此在模型导出时,根据自己的模型需求,对需要进行识别的对象名称,进行定义;接着在导出模型时,会将定义的类别字符转换为权重,直接加载到模型中。

这样在模型推理时,就无需再进行文本权重转换,提升模型推理的速度;但这样也会导致导出的模型无法再修改类别,如果需要更改类别,就需要重新导出模型。

3. 项目配置

3.1 源码下载与项目配置

首先使用Git克隆项目源码。输入以下指令:

git clone https://github.com/guojin-yan/OpenVINO-CSharp-API-Samples.git

代码下载完成后,使VS 2022打开解决方案Samples.sln文件,找到yolo-world-opencvsharp-net4.8项目,如下图所示:

接下来安装依赖项。首先是安装OpenVINO C# API项目依赖,通过NuGet安装一下包即可:

OpenVINO.CSharp.API
OpenVINO.runtime.win
OpenVINO.CSharp.API.Extensions
OpenVINO.CSharp.API.Extensions.OpenCvSharp

关于在不同平台上搭建 OpenVINO C# API 开发环境请参考以下文章: 《在Windows上搭建OpenVINOC#开发环境》《在Linux上搭建OpenVINOC#开发环境》《在MacOS上搭建OpenVINOC#开发环境》

接下来安装使用到的图像处理库 OpenCvSharp,通过NuGet安装一下包即可:

OpenCvSharp4
OpenCvSharp4.Extensions
OpenCvSharp4.runtime.win

关于在其他平台上搭建 OpenCvSharp 开发环境请参考以下文章:《【OpenCV】在Linux上使用OpenCvSharp》《【OpenCV】在MacOS上使用OpenCvSharp》

添加完成项目依赖后,项目的配置文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bcl.AsyncInterfaces" version="5.0.0" targetFramework="net48" />
<package id="OpenCvSharp4" version="4.9.0.20240103" targetFramework="net48" />
<package id="OpenCvSharp4.Extensions" version="4.9.0.20240103" targetFramework="net48" />
<package id="OpenCvSharp4.runtime.win" version="4.9.0.20240103" targetFramework="net48" />
<package id="OpenVINO.CSharp.API" version="2024.0.0.1" targetFramework="net48" />
<package id="OpenVINO.CSharp.API.Extensions" version="1.0.1" targetFramework="net48" />
<package id="OpenVINO.CSharp.API.Extensions.OpenCvSharp" version="1.0.4" targetFramework="net48" />
<package id="OpenVINO.runtime.win" version="2024.0.0.2" targetFramework="net48" />
<package id="SharpCompress" version="0.35.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Drawing.Common" version="7.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.Text.Encoding.CodePages" version="8.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
<package id="ZstdSharp.Port" version="0.7.4" targetFramework="net48" />
</packages>

3.2 定义模型预测方法

使用 OpenVINO C# API 部署模型主要包括以下几个步骤:

  • 初始化 OpenVINO Runtime Core
  • 读取本地模型(将图片数据预处理方式编译到模型)
  • 将模型编译到指定设备
  • 创建推理通道
  • 处理图像输入数据
  • 设置推理输入数据
  • 模型推理
  • 获取推理结果
  • 处理结果数据

下面根据模型部署流程,详细介绍一下该模型的部署代码:

该项目主要使用到OpenCvSharpOpenVINO C# API这两个工具包,因此需要添加以下命名空间:

using OpenCvSharp;
using OpenVinoSharp;
using OpenVinoSharp.Extensions.process;
  • 初始化 OpenVINO Runtime Core

    Core core = new Core();
  • 读取本地模型(将图片数据预处理方式编译到模型)

    Model model = core.read_model(tb_model_path.Text);
  • 将模型编译到指定设备

    CompiledModel compiled_model = core.compile_model(model, cb_device.SelectedItem.ToString());
  • 创建推理通道

    InferRequest request = compiled_model.create_infer_request();
  • 处理图像输入数据

    Mat image = Cv2.ImRead(tb_input_path.Text);
    Mat mat = new Mat();
    Cv2.CvtColor(image, mat, ColorConversionCodes.BGR2RGB);
    mat = OpenVinoSharp.Extensions.process.Resize.letterbox_img(mat, (int)input_shape[2], out factor);
    mat = Normalize.run(mat, true);
    float[] input_data = Permute.run(mat);
  • 设置推理输入数据

    Tensor input_tensor = request.get_input_tensor();
    input_tensor.set_data(input_data);
  • 模型推理

     request.infer();
  • 获取推理结果

    Tensor output_boxes = request.get_tensor("boxes");
    float[] boxes = output_boxes.get_data<float>((int)output_boxes.get_size());
    Tensor output_scores = request.get_tensor("scores");
    float[] scores = output_scores.get_data<float>((int)output_scores.get_size());
    Tensor output_labels = request.get_tensor("labels");
    int[] labels = output_labels.get_data<int>((int)output_labels.get_size());
  • 处理结果数据

    DetResult postprocess(float[] result, int categ_nums, float factor)
    {
    Mat result_data = new Mat(4 + categ_nums, 8400, MatType.CV_32F,result);
    result_data = result_data.T(); // Storage results list
    List<Rect> position_boxes = new List<Rect>();
    List<int> classIds = new List<int>();
    List<float> confidences = new List<float>();
    // Preprocessing output results
    for (int i = 0; i < result_data.Rows; i++)
    {
    Mat classesScores = new Mat(result_data, new Rect(4, i, categ_nums, 1));
    Point maxClassIdPoint, minClassIdPoint;
    double maxScore, minScore;
    // Obtain the maximum value and its position in a set of data
    Cv2.MinMaxLoc(classesScores, out minScore, out maxScore,
    out minClassIdPoint, out maxClassIdPoint);
    // Confidence level between 0 ~ 1
    // Obtain identification box information
    if (maxScore > 0.25)
    {
    float cx = result_data.At<float>(i, 0);
    float cy = result_data.At<float>(i, 1);
    float ow = result_data.At<float>(i, 2);
    float oh = result_data.At<float>(i, 3);
    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();
    box.X = x;
    box.Y = y;
    box.Width = width;
    box.Height = height; position_boxes.Add(box);
    classIds.Add(maxClassIdPoint.X);
    confidences.Add((float)maxScore);
    }
    }
    // NMS non maximum suppression
    int[] indexes = new int[position_boxes.Count];
    float score = float.Parse(tb_score.Text);
    float nms = float.Parse(tb_nms.Text);
    CvDnn.NMSBoxes(position_boxes, confidences, score, nms, out indexes);
    DetResult re = new DetResult();
    //
    for (int i = 0; i < indexes.Length; i++)
    {
    int index = indexes[i];
    re.add(classIds[index], confidences[index], position_boxes[index]);
    }
    return re;
    }

以上就是使用 OpenVINO C# API 部署YOLO-World模型的关键代码,具体代码可以下载项目源码进行查看。

4. 项目运行与演示

配置好项目后,点击运行,本次我们提供给大家的是使用.NET Framework4.8开发的窗体应用程序,如下图所示,主要还包含五个部分,分别为推理设置区域、控制按钮、推理信息输出区域、原图展示区域、推理结果展示区域。在使用时,用户可以根据自己需求,选择导出的模型以及待推理数据,支持图片数据以及视频数据,接着输入自己导出的lables名称,同时还可以修改推理设备、数据处理所需的参数等,接着就可以依次点击加载模型、模型推理按钮,进行模型推理。最后模型推理结果如图所示。

该模型在导出时,只定义了busperson类别,因此在模型推理后,可以识别出图片中的busperson元素。

接着又测试了导出时只定义person类别的模型,如下图所示,最后识别出来的结果只有person

最后,我们提供了一个行人检测视频案例,视频链接如下所示:

https://mp.weixin.qq.com/s/7dlLtUE2NTIHHyKvOskGhg

5. 总结

在该项目中,我们结合之前开发的 OpenVINO C# API 项目部署YOLOv9模型,成功实现了对象目标检测与实例分割,并且根据不同开发者的使用习惯,同时提供了OpenCvSharp以及Emgu.CV两种版本,供各位开发者使用。最后如果各位开发者在使用中有任何问题,欢迎大家与我联系。

【OpenVINO™】使用OpenVINO™ C# API 部署 YOLO-World实现实时开放词汇对象检测的更多相关文章

  1. Asp.net web api部署在某些服务器上老是404

    asp.net web api部署在Windows服务器上后,按照WebAPI定义的路由访问,老是出现404,但定义一个静态文件从站点访问,却又OK. 这时,便可以确定是WebAPI路由出了问题,经调 ...

  2. python3.8.0 Django 开发后端接口api 部署到 Linux Centos7上

    经历了两天的时候终于把本地使用python3 django开发的接口API部署到服务器上了,还是记录一下,以免之后忘记,哈哈 注意一点,就是,centos7是基于python2的,我这边默认的是pyt ...

  3. .net core Api 部署到Linux

    一.环境介绍 1..net开发环境:asp.net core 3.1 2.Linux环境:CentOS Linux release 7.9.2009 (Core) 3.Swagger: Swashbu ...

  4. Qt刷新机制的一些总结(Qt内部画的时候是相当于画在后台一个对象里,然后在刷新的时候调用bitblt统一画,调用window的api并不会影响到后面的那个对象)

    前段时间做过一个界面刷新的优化,遇到的坑比较多,在这里做一点点总结吧.     优化的方案是滚动滚动条的时候用截屏的方式代替界面全部刷新,优化完成后,界面在滚动时效率能提升大概一倍,背景介绍完毕.   ...

  5. YOLO、SSD、FPN、Mask-RCNN检测模型对比

    YOLO.SSD.FPN.Mask-RCNN检测模型对比 一.YOLO(you only look once) YOLO 属于回归系列的目标检测方法,与滑窗和后续区域划分的检测方法不同,他把检测任务当 ...

  6. 如何将.NET 4.0写的Windows service和Web API部署到docker上面

    Web API. 看这篇文章: https://docs.microsoft.com/en-us/aspnet/mvc/overview/deployment/docker-aspnetmvc Win ...

  7. [Asp.Net] web api 部署注意事项

    在将web api项目部署到IIS上的时候 要将应用程序池设置成.net framework 4.0版本

  8. .net core web api部署到docker

    一.创建.net core web api 的Demo 修改部分代码 端口随意指定,ip用星号“*”,方便接下来docker虚拟网络自动分配ip 下一步是Dockerfile文件,如果发现你的项目中没 ...

  9. Docker系列(三):将.Net Core Api部署到Kubernetes (K8s)中

    1.新建一个WebApi项目,并添加Dockerfile文件: FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base WORKDIR /app EX ...

  10. .NET Core api部署到IIS上405的问题

    今天部署到iis 服务器上,api的put请求一直报405.其他像get post都没问题. google了半天,找到两种解决方案,亲测都可以.但我个人认为不是最理想的解决方案. 1.IIS拒绝PUT ...

随机推荐

  1. Java 中的异常处理机制的简单原理和应用。

    Java 中的异常处理机制的简单原理和应用. 异常是指 java 程序运行时(非编译)所发生的非正常情况或错误. Java 对异常进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根 ...

  2. MySQL索引Innodb存储引擎

    MySQL索引优化 一.基础理解 MySQL语句的查询效率主要和索引树的高度有关,想要降低查询的次数提高查询的速度,减少直接对磁盘的I/O流的次数,就要让索引树的高度越低越好. 索引的定义:索引是帮助 ...

  3. #Pollard-Rho,高精度#洛谷 3499 [POI2010]NAJ-Divine Divisor

    题目 给定\(m\)个数\(a_i\),令\(n=\prod_{i=1}^m a_i\), 问有多少个大于1的正整数\(d\)满足\(d^{\max k}|n\) 并输出\(\max k\),\(m\ ...

  4. OpenHarmony有氧拳击之设备端开发

    一.简介 在一个风和日丽,阳光明媚的下午,码农们都像往常一样正在专注地码代码.突然前面的小哥哥站起来,手握开发板,来回出拳.这是怎么回事? 原来这是一款拳击互动游戏,本文将带你一同解开其中的奥秘.开发 ...

  5. k8s之持久卷NFS

    一.简介 NFS网络存储卷,Kubernetes原生支持NFS作为Kubernetes的持久存储卷之一.NFS可以实现Pod的跨界点的数据持久性. 首先需要创建一个nfs 服务器,作为存储服务器: 将 ...

  6. Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件-Nacos 、Sentinel等

    概述 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此项目包含开发分布式应用服务的必需组件. 方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发 ...

  7. CentOS6.4中yum命令安装php5.2.17[转载未亲测]

    最近给公司部署服务器的时候发现他们提供的服务器是centos6.4系统的,装好系统和相关服务httpd,mysql,php,一跑代码,发现php5.3中的zend加密不能用,安装Zend Guard ...

  8. jenkins 持续集成和交付 —— git hook(七)

    前言 这个hook的意思叫做钩子哈,前端听得多. 正文 好吧,这个git hook 有什么用呢? 前面说了一个轮询SCM这个东西呢,我是真的觉得这东西没啥用,经常扫描仓储算怎么回事呢? 但是如果主动通 ...

  9. Pytorch-tensor的创建,索引,切片

    1.基本概念 标量:就是一个数,是0维的,只有大小,没有方向 向量:是1*n的一列数,是1维的,有大小,也有方向 张量:是n*n的一堆数,是2维的,n个向量合并而成 2.a.size(),a.shap ...

  10. js中this对象的理解

    一.定义 函数的 this 关键字在 JavaScript 中的表现略有不同,此外,在严格模式和非严格模式之间也会有一些差别 在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定) th ...