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. 2024 VEXIQ 赛季笔(游)记 Pt.1

    2024/03/07 老师让我们做机器初步思考了. 搞搞戒指,只要一个小夹子加上赛季的抬升吸环改一下就可以了,方便的一批. 于是夹子 10 分钟不到搞完了,现在是缝合怪时间. 但是老师下课不让我搞了 ...

  2. Selenium 八大元素定位方式

    UI自动化测本质无非就是: 定位元素 -> 操作元素 -> 模拟页面动作 -> 断言结果 -> 生成测试报告. 所以我们做UI自动化的第一步就是定位元素,如果连元素都定位不到就 ...

  3. 使用sbt对Scala程序进行打包并运行(Spark单机运行)

    十.使用sbt对Scala程序进行打包并运行(Spark单机运行) 在./sparkapp 中新建文件 simple.sbt(vim ./sparkapp/simple.sbt),添加内容如下,声明该 ...

  4. 详解SSL证书系列(8)了解HTTPS及和HTTP的区别

    上一篇我们介绍了HTTP协议的三大缺点,那么怎么避免和解决HTTP的缺点呢,是时候请出我们的HTTPS了,那HTTPS和HTTP有什么区别呢? HTTP加上加密处理和认证以及完整性保护后即是HTTPS ...

  5. #Tarjan,拓扑排序#洛谷 3436 [POI2006]PRO-Professor Szu

    题目 分析 考虑有向图缩点然后拓扑排序, 最恶心的地方是这题有自环, 一旦存在自环就意味着答案一定超过阈值 其实更难过的是Tarjan大小写写错没有发现qwq 代码 #include <cstd ...

  6. OHOS IDE和SDK的安装方法

    参照OpenHarmony应用开发环境安装流程,下载安装OHOS的IDE,过程中需要全程联网. IDE,安装至D:\Tools\Huawei\DevEcoStudio. IDE安装成功之后,按照提示下 ...

  7. C语言 04 基本数据类型

    整数 整数就是不包含小数点的数字,整数包含以下几种类型: short :占用 2 个字节,16 个 bit 位. int:占用 4 个字节,32 个 bit 位,能够表示 -2^32 到 2^32 之 ...

  8. RabbitMQ 03 直连模式-可视化界面

    这里先演示最简单的模型:直连模式.其结构图为: 一个生产者 -> 消息队列 -> 一个消费者 生产者只需要将数据丢进消息队列,而消费者只需要将数据从消息队列中取出,这样就实现了生产者和消费 ...

  9. JavaScript 迈入 AI 新纪元

    随着人工智能技术的不断进步,JavaScript 也迎来了自己的 AI 时代. JS-Torch 是一个全新的深度学习库,专为 JavaScript 设计,其语法习惯与广受欢迎的 PyTorch 框架 ...

  10. 第十六篇:jQuery基础

    一.jQuery和Dom的关系 http://jquery.cuishifeng.cn/ 模块,类库 DOM/BOM/JavaScript的类库: 二.jQuery选择器 1.查找元素 DOM: 10 ...