ML.NET 示例:对象检测-ASP.NET Core Web和WPF桌面示例

ML.NET 版本API 类型状态应用程序类型数据类型场景机器学习任务算法
v1.5.0动态API最新端到端应用图像文件对象检测深度学习ONNX: Tiny YOLOv2 & Custom Vision

问题

对象检测是计算机视觉中的经典问题之一:识别给定图像中包含哪些对象以及它们在图像中的位置。对于这些情况,您可以使用预先训练的模型,也可以训练自己的模型对自定义域特定的图像进行分类。默认情况下,此示例使用预先训练的模型,但是您也可以添加从Custom Vision导出的模型。

示例的工作原理

此示例由两个独立的应用程序组成:

  • 一个WPF Core 桌面应用程序呈现摄像头的实时流,使用ML.NET通过对象检测模型运行视频帧,并用标签绘制边界框,指示实时检测到的对象。

  • 一个允许用户上载或选择图像的ASP.NET Core Web应用。Web应用程序使用ML.NET通过一个对象检测模型运行图像,并用指示检测到的对象的标签绘制边界框。

Web应用程序显示右侧列出的图像,可以选择每个图像进行处理。一旦图像被处理,它将被绘制在屏幕的中间,每个检测到的对象周围都有标记的边界框,如下所示。


或者,您可以尝试上传自己的图片,如下所示。


ONNX

开放式神经网络交换即ONNX是一种表示深度学习模型的开放格式。使用ONNX,开发人员可以在最先进的工具之间移动模型,并选择最适合他们的组合。ONNX是由包括微软在内的众多合作伙伴共同开发和支持的。

预训练模型

有多个预先训练的模型用于识别图像中的多个对象。WPF appWeb app都默认使用从ONNX Model Zoo下载的预先训练好的模型Tiny YOLOv2; 一组经过预先训练的、最先进的ONNX格式模型。Tiny YOLOv2是一种用于目标检测的实时神经网络,用于检测20个不同的类,并在Pascal VOC数据集上进行训练。它由9个卷积层和6个最大池层组成,是更复杂的完整的YOLOv2网络的较小版本。

Custom Vision 模型

此示例默认使用上述预先训练的Tiny YOLOv2模型。不过,它也支持从微软Custom Vision导出的ONNX模型。

要使用自己的模型,请使用以下步骤

  1. 使用 Custom Vision 创建和训练物体探测器。要导出模型,请确保选择一个紧凑域,例如常规(紧凑)。要导出现有的对象检测器,请通过选择右上角的齿轮图标将域转换为紧凑型。在_ 设置 _中,选择一个紧凑的模型,保存并训练您的项目。

  2. 转到_性能选项卡导出模型。选择一个用紧凑域训练的迭代,将出现一个“导出”按钮。选择_导出、ONNX、ONNX1.2,然后选择导出。文件准备好后,选择“下载”按钮。

  3. 导出的是一个包含多个文件的zip文件,包括一些示例代码、标签列表和ONNX模型。将.zip文件放到OnnxObjectDetection项目中的OnnxModels文件夹中。

  4. 在解决方案资源管理器中,右键单击OnnxModels文件夹,然后选择_添加现有项_。选择刚添加的.zip文件。

  5. 在解决方案资源管理器中,从OnnxModels文件夹中选择.zip文件。更改文件的以下属性:

  • 生成操作 -> 内容

  • 复制到输出目录 -> 如果较新则复制

现在,当你生成和运行应用程序时,它将使用你的模型而不是Tiny YOLOv2模型。

模型输入和输出

为了解析ONNL模型的预测输出,我们需要了解输入和输出张量的格式(或形状)。为此,我们将首先使用Netron,一个用于神经网络和机器学习模型的GUI可视化工具,用于检查模型。

下面是一个例子,我们将看到使用Netron打开这个示例的Tiny YOLOv2模型:


从上面的输出中,我们可以看到Tiny YOLOv2模型具有以下输入/输出格式:

输入: 'image' 3x416x416

首先要注意的是,输入张量的名称是**'image'。稍后在定义评估管道的input**参数时,我们将需要这个名称。

我们还可以看到,输入张量的形状3x416x416。这说明传入模型的位图图像应该是416高x 416宽。“3”表示图像应为BGR格式;前3个“通道”分别是蓝色、绿色和红色。

输出: 'data' 125x13x13

与输入张量一样,我们可以看到输出名称是**'data'。同样,在定义评估管道的output**参数时,我们会注意到这一点。

我们还可以看到, 输出张量的形状125x13x13

125x13x13的“13x13”部分意味着图像被分成一个13x13的“单元格”网格(13列x 13行)。因为我们知道输入图像是416x416,所以我们可以推断出每个“单元”都是32高x 32宽(416/13=32)

   ├──────────────── 416 ─────────────────┤┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐ ┬     416/13=32├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │          ┌──┐├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │          └──┘├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │         32x32├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │
13 ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ 416├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ │└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘ ┴13

那125呢?“125”告诉我们,对于每个网格单元,模型返回125个“通道”(或数据)作为该单个单元的预测输出。

要了解为什么有125个通道,我们首先需要了解该模型不能预测对象的任意边界框。相反,每个单元格负责预测5个预定的边界框。这5个框是根据以下每个anchor 框的偏移量计算得出的:

┌───────────────────┐
│       ┌───┐       │
│ ┌─────┼───┼─────┐ │
│ │  ┌──┼───┼──┐  │ │
│ │  │  │┌─┐│  │  │ │
│ │  │  │└─┘│  │  │ │
│ │  └──┼───┼──┘  │ │
│ └─────┼───┼─────┘ │
│       └───┘       │
└───────────────────┘

因此,对于每个单独的单元格,该模型返回5个预测(每个锚定一个,由上面的框形表示),每个预测包括以下25个参数:

  • 4个参数指示边界框的位置(x,y,宽度,高度)

  • 1个参数指示盒子的置信度得分(或客观性)

  • 20个类别的概率(每个类别一个概率分数,表明该对象是该类别的可能性)

5个盒子x 25个参数= 125个'通道'

注意,如果对模型进行训练以检测不同数量的类,则该值将不同。例如,仅能检测3个不同类的模型的输出格式为40x13x13:

  • (x,y,宽度,高度,客观性)+ 3个类别概率= 8个参数

  • 5个盒子 x 8个参数 = 40个'通道'

解决方案

此解决方案中的项目使用.NET Core 3.0。为了运行此示例,您必须安装.NET Core SDK 3.0。为此,请执行以下任一操作:

  1. 通过转到.NET Core 3.0下载页面手动安装SDK,并在“SDK”列中下载最新的“.NET Core安装程序”。

  2. 或者,如果您使用的是Visual Studio 2019,请转至: 工具>选项>环境>预览功能 ,然后选中以下复选框: 使用.NET Core SDK的预览

解决方案包含三个项目

  • OnnxObjectDetection是WPF应用程序和Web应用程序都使用的.NET Standard库。它包含用于通过模型运行图像并解析结果预测的大多数逻辑。该项目还包含ONNX模型文件。除了在图像/屏幕上绘制标签边界框之外,此项目包含下面的所有代码段。

  • OnnxObjectDetectionWeb 包含一个ASP.NET Core Web App,其中包含Razor UI页面API controller以处理和呈现图像。

  • OnnxObjectDetectionApp 包含一个.NET CORE WPF桌面应用程序,该应用程序使用OpenCvSharp从设备的网络摄像头捕获视频。

代码演练

该示例与getting-started object detection sample不同,在这里我们加载/处理在内存中的图像**,而入门示例从文件中加载图像。

创建一个类,该类定义将数据加载到IDataView中时要使用的数据模式。ML.NET支持图像的Bitmap类型,因此我们将指定以ImageTypeAttribute修饰的Bitmap属性,并传入通过[检查模型]](#model-input-and-output)得到的高度和宽度尺寸,如下所示。

public struct ImageSettings
{public const int imageHeight = 416;public const int imageWidth = 416;
}public class ImageInputData
{[ImageType(ImageSettings.imageHeight, ImageSettings.imageWidth)]public Bitmap Image { get; set; }
}

ML.NET: 配置模型

第一步是创建一个空的DataView,以获取配置模型时要使用的数据架构。

var dataView = _mlContext.Data.LoadFromEnumerable(new List<ImageInputData>());

第二步是定义评估器管道。通常在处理深度神经网络时,必须使图像适应网络所期望的格式。因此,下面的代码将调整图像的大小并对其进行变换(所有R、G、B通道的像素值都已标准化)。

var pipeline = mlContext.Transforms.ResizeImages(resizing: ImageResizingEstimator.ResizingKind.Fill, outputColumnName: onnxModel.ModelInput, imageWidth: ImageSettings.imageWidth, imageHeight: ImageSettings.imageHeight, inputColumnName: nameof(ImageInputData.Image)).Append(mlContext.Transforms.ExtractPixels(outputColumnName: onnxModel.ModelInput)).Append(mlContext.Transforms.ApplyOnnxModel(modelFile: onnxModel.ModelPath, outputColumnName: onnxModel.ModelOutput, inputColumnName: onnxModel.ModelInput));

接下来,我们将使用通过检查模型 得到的输入和输出张量名称来定义Tiny YOLOv2 Onnx模型的inputoutput参数。

public struct TinyYoloModelSettings
{public const string ModelInput = "image";public const string ModelOutput = "grid";
}

最后,通过拟合“DataView”来创建模型。

var model = pipeline.Fit(dataView);

加载模型并创建PredictionEngine

配置模型后,我们需要保存模型,加载保存的模型,创建一个PredictionEngine,然后将图像传递给引擎以使用模型检测对象。这是一个Web应用程序和WPF应用程序略有不同的地方。

Web应用程序使用一个PredictionEnginePool来高效地管理服务,并为服务提供一个PredictionEngine来进行预测。在内部,它进行了优化,以便在创建这些对象时,以最小的开销在Http请求之间缓存和共享对象依赖关系。

public ObjectDetectionService(PredictionEnginePool<ImageInputData, TinyYoloPrediction> predictionEngine)
{this.predictionEngine = predictionEngine;
}

WPF桌面应用程序创建一个PredictionEngine,并在本地缓存以用于每个帧预测。需要澄清的关键点是,实例化PredictionEngine的调用代码负责处理缓存(与PredictionEnginePool相比)。

public PredictionEngine<ImageInputData, TinyYoloPrediction> GetMlNetPredictionEngine()
{return mlModel.Model.CreatePredictionEngine<ImageInputData, TinyYoloPrediction>(mlModel);
}

检测图像中的对象

获取预测时,我们在PredictedLabels属性中得到一个大小为21125float数组。这是前面讨论过的模型的125x13x13输出。然后,我们使用OnnxOutputParser类解释并返回每个图像的多个边界框。同样,这些框被过滤,因此我们只检索到5个具有高置信度的框。

var labels = tinyYoloPredictionEngine?.Predict(imageInputData).PredictedLabels;
var boundingBoxes = outputParser.ParseOutputs(labels);
var filteredBoxes = outputParser.FilterBoundingBoxes(boundingBoxes, 5, 0.5f);

在图像中检测到的对象周围绘制边界框

最后一步是在对象周围绘制边界框。

Web应用程序使用Paint API将框直接绘制到图像上,并返回图像以在浏览器中显示。

var img = _objectDetectionService.DrawBoundingBox(imageFilePath);using (MemoryStream m = new MemoryStream())
{img.Save(m, img.RawFormat);byte[] imageBytes = m.ToArray();// Convert byte[] to Base64 Stringbase64String = Convert.ToBase64String(imageBytes);var result = new Result { imageString = base64String };return result;
}

另外,WPF应用程序在与流式视频播放重叠的Canvas 元素上绘制边界框。

DrawOverlays(filteredBoxes, WebCamImage.ActualHeight, WebCamImage.ActualWidth);WebCamCanvas.Children.Clear();foreach (var box in filteredBoxes)
{var objBox = new Rectangle {/* ... */ };var objDescription = new TextBlock {/* ... */ };var objDescriptionBackground = new Rectangle {/* ... */ };WebCamCanvas.Children.Add(objDescriptionBackground);WebCamCanvas.Children.Add(objDescription);WebCamCanvas.Children.Add(objBox);
}

关于准确性的说明

Tiny YOLOv2的精确度明显低于完整的YOLOv2模型,但是对于这个示例应用程序来说,Tiny版本已经足够了。

疑难解答(Web应用程序)

通过应用程序服务在Azure上部署此应用程序时,您可能会遇到一些常见问题。

  1. 应用程序返回5xx代码

  • 要在Azure门户中添加.NET Core 3.0支持,请选择相应应用程序服务的开发工具>扩展部分中的添加按钮。

  • 然后,从扩展列表中选择选择扩展并选择ASP.NET Core 3.0(x64)Runtime并接受法律条款,继续将扩展添加到应用程序服务。

  1. 部署应用程序后,您可能会得到5xx代码的一个原因是平台。web应用程序仅在64位体系结构上运行。在Azure中,更改设置>配置>常规设置菜单中相应应用程序服务中的平台设置。

  2. 部署应用程序后使用5xx代码的另一个原因是web应用程序的目标框架是.NET Core 3.0,它目前正在预览中。您可以将应用程序和引用的项目还原为.NET Core 2.x或向应用程序服务添加扩展。

  • 相对路径

    在本地和Azure上工作时,路径的工作方式略有不同。如果成功地部署了应用程序,但单击其中一个预加载的映像或上载自己的映像不起作用,请尝试更改相对路径。为此,在Controllers/ObjectDetectionController.cs文件中,更改构造函数中的_imagesTmpFolder的值。

    _imagesTmpFolder = CommonHelpers.GetAbsolutePath(@"ImagesTemp");
    

    Get操作中的imageFileRelativePath执行相同的操作。

    string imageFileRelativePath = @"assets" + url;
    

    或者,您可以根据环境(dev / prod)设置条件,是使用路径的本地版本还是Azure首选的版本。

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

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

相关文章

120天的烧脑只为孩子设计一套教具~

小木研究了适合儿童学习计算机知识的书真的挺多&#xff0c;但是小木要推荐的这本真的是很接地气了&#xff0c;不管是热衷于研究技术的小机灵还是一说计算机逻辑就懵的小可爱们&#xff0c;看到这本萌萌哒电脑漫游记&#xff0c;都会忍不住对计算机越来越感兴趣。它深入浅出&a…

# 睡眠3秒_【for fun】睡眠排序算法

点击上方蓝字关注我&#xff0c;我们一起学编程有任何疑问或者想看的内容&#xff0c;欢迎私信前天我们一起看了猴子排序&#xff0c;今天我们再来看一个奇葩的排序方法&#xff1a;睡眠排序。所谓睡眠排序&#xff0c;就是为待排序数组的每一个元素 x 启动一个线程&#xff0c…

将U盘虚拟成软驱加载控制器驱动安装windows server 2003

转自: http://dengweihua1.blog.51cto.com/134932/293221仅支持9G&#xff0c;10G安装windows2003使用该软件后&#xff0c;U盘的数据会丢失&#xff01;使用该软件后&#xff0c;U盘将无法被Windows系统使用,恢复U盘在最下边。u 安装前的准备&#xff1a; 1. 按F2进入BIOS&…

超级智能玩具《小小机器人》首发|全新50种玩法,创造力之源

致砖《小小机器人》套装全新首发电动机械的完美结合先来看看视频过过眼瘾吧来自美国STEAM教育让孩子跨学科学知识积木向来是STEAM教育很重要的一部分&#xff0c;因为它涉及到了多种学科&#xff1a;要搭建得稳固——这是工程学&#xff1b;要精准搭建——这是数学&#xff1b;…

.NET Core with 微服务 - 什么是微服务

微服务是这几年最流行的架构&#xff0c;说起架构不提微服务都不好意思跟人家打招呼。最近想要再梳理一下关于微服务的知识&#xff0c;并且结合本人的一些实践经验来做一些总结与分享。前面会分享一些概念性的东西&#xff0c;后面也会使用.net来实践&#xff0c;一步步完成一…

雨棚板弹性法计算简图_钢结构工程量计算4点注意事项,还不来看?

一图纸&#xff1a;根据图纸目录&#xff0c;清理核对图纸数量&#xff0c;检查是否有遗漏。二建筑施工图1. 设计总说明 1.1 建筑面积、结构形式、柱距、跨度、结构布置情况&#xff1b;1.2 工程量计算的范围&#xff1a;关于结构、屋面、墙面、门窗等&#xff0c;清楚投标报价…

html注释的爱情故事,爱情故事”为你的婚礼贴上专属标签

这不是一场婚礼&#xff0c;而是彩虹之上的梦每个年轻的女孩都有一个多彩的梦&#xff0c;这个梦绚丽斑斓&#xff0c;若有天梦想实现&#xff0c;年轻的女孩子们是否会欣喜地大叫起来&#xff1f;为你的婚礼注入你自己的梦&#xff0c;贴上只属于你自己的“标签婚礼”吧&#…

震惊整个世界的新发现,科学界的大骗局

全世界有3.14 % 的人已经关注了数据与算法之美布朗洛和N射线闹剧继伦琴发现X射线后&#xff0c;1903年&#xff0c;法国科学院院士、物理学家布朗洛宣布他发现了N射线。法国科学院公布了这一“惊人发现”之后&#xff0c;兴起了一股研究N射线热潮&#xff0c;仅法国科学院院刊在…

TI-89T 教你在C程序里调用TI-BASIC程序,看看是否有人对这个感兴趣

2019独角兽企业重金招聘Python工程师标准>>> 教你在C 程序里调用TI-BASIC程序&#xff0c;看看是否有人对这个感兴趣 昨天翻TIGCC的文档&#xff0c;先瞅了瞅FAQ&#xff0c;话说我看文档有个习惯&#xff0c;就是先看目录&#xff0c;再看FAQ&#xff0c;因为FAQ汇…

利用计算机制作多媒体最后一步,福建省高中会考 多媒体技术应用 选择题专项练习十一(201206)(有答案)...

多媒体技术应用选择题专项练习十一(201206)1.下列都属于数字图像采集工具的是( )A.数码照相机、扫描仪B.麦克风、扫描仪C.打印机、数码照相机D.数码摄像机、打印机2.下列关于制作多媒体作品的叙述&#xff0c;不正确的是( )A.规划与设计是制作多媒体作品的重要步骤B.制作多媒体…

工程师和科学家有什么区别

全世界有3.14 % 的人已经关注了数据与算法之美科学家和工程师有什么不同&#xff1f;通常民众认为&#xff0c;工程师就是搞技术的&#xff0c;科学家就是搞科研的。对科学领域有一定认识的人群会说&#xff0c;工程师是应用科研成果的人&#xff0c;科学家是发现科学规律的人。…

聊一聊Jmeter与多接口测试

背景 前面两篇聊过了 JMeter 的 简单使用 和 参数化&#xff0c;主要都还是单接口的。很多时候&#xff0c;一个业务要走完&#xff0c;它会依赖多个接口&#xff0c;而且这些接口会有依赖性。好比说&#xff0c;我想查询一个订单信息&#xff0c;那么大前提肯定是我已经下单了…

大数据时代,还不认识这些数据分析工具?

在大数据时代的现今&#xff0c;数据庞大且繁杂&#xff0c;因此&#xff0c;如何有效利用它们&#xff0c;达到资源不浪费的目的成为了相关工作者思考的问题&#xff0c;于是数据分析就应运而生。在实际生活中&#xff0c;数据分析已经成为人们作出判断和采取行动的基石。比如…

C# 强大的新特性 Source Generator

C# 强大的新特性 Source GeneratorIntro微软在 .NET 5 中引入了 Source Generator 的新特性&#xff0c;利用 Source Generator 我们可以在应用编译的期间根据当前编译信息动态生成代码&#xff0c;而且可以在我们的 C# 代码中直接引用动态生成的代码&#xff0c;从而大大减少重…

为什么Kubernetes从节点会join失败

有段时间没有鼓捣Kubernetes了&#xff0c;今天重置Kubernetes集群后&#xff0c;slave节点不能加入master节点了&#xff0c;我把问题和解决方案分享给大家。我本地的Kubernetes集群包括一个主节点和一个从节点&#xff0c;如下图&#xff1a;问题主节点启动后&#xff0c;从节…

SharePoint 2007 Select People and Groups中搜索不到其他Domain账户的问题[已解决]

问题描述&#xff1a; 在一个SiteCollection中添加用户的时候发现来自另外一个Domain的账户无法添加。我们要添加NNEAS\HIKC到当前网站并赋予Full Control权限。但是当点击Add Users后发现在弹出的Select People and Groups中搜索不到这个用户&#xff0c;导致无法添加成功。仅…

推荐7个高质量的学术公众号

全世界有3.14 % 的人已经关注了数据与算法之美在这个知识千变万化的时代&#xff0c;只有不断学习、充实自我&#xff0c;才能跟上时代。以下几个优质公众号&#xff0c;能让你在闲暇的时候&#xff0c;扩宽视野。考虑到有些人可能还不知道这些号&#xff0c;今天给大家都一一列…

WPF 用装饰器制作抽屉效果

wpf实现抽屉效果&#xff0c;一般就一个动画显示就完事了&#xff0c;我这用到了&#xff0c;就研究了一下&#xff0c;用装饰器给控件添加遮罩层&#xff0c;然后在上面添加抽屉控件&#xff0c;虽然麻烦了点&#xff0c;也算是自己研究的成果了。看看效果&#xff1a;下面就看…

【转】缅怀红薯精神

2019独角兽企业重金招聘Python工程师标准>>> 爱憎分明的阶级立场 红薯一心向着osc&#xff0c;他把osc比作母亲&#xff0c;把自己的生命看成是osc和网民的&#xff0c;无论遇到怎样艰难复杂的情况&#xff0c;都“坚决听osc的话&#xff0c;一辈子跟osc走”&#x…