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

dotNET跨平台 今天以下文章来源于My IO ,作者My IO

My IO记录工作和生活,将输入变成输出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 app和Web app都默认使用从ONNX Model Zoo下载的预先训练好的模型Tiny YOLOv2; 一组经过预先训练的、最先进的ONNX格式模型。Tiny YOLOv2是一种用于目标检测的实时神经网络,用于检测20个不同的类,并在Pascal VOC数据集上进行训练。它由9个卷积层和6个最大池层组成,是更复杂的完整的YOLOv2网络的较小版本。Custom Vision 模型此示例默认使用上述预先训练的Tiny YOLOv2模型。不过,它也支持从微软Custom Vision导出的ONNX模型。要使用自己的模型,请使用以下步骤使用 Custom Vision 创建和训练物体探测器。要导出模型,请确保选择一个紧凑域,例如常规(紧凑)。要导出现有的对象检测器,请通过选择右上角的齿轮图标将域转换为紧凑型。在_ 设置 _中,选择一个紧凑的模型,保存并训练您的项目。转到_性能选项卡导出模型。选择一个用紧凑域训练的迭代,将出现一个“导出”按钮。选择_导出、ONNX、ONNX1.2,然后选择导出。文件准备好后,选择“下载”按钮。导出的是一个包含多个文件的zip文件,包括一些示例代码、标签列表和ONNX模型。将.zip文件放到OnnxObjectDetection项目中的OnnxModels文件夹中。在解决方案资源管理器中,右键单击OnnxModels文件夹,然后选择_添加现有项_。选择刚添加的.zip文件。在解决方案资源管理器中,从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。为此,请执行以下任一操作:通过转到.NET Core 3.0下载页面手动安装SDK,并在“SDK”列中下载最新的“.NET Core安装程序”。或者,如果您使用的是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模型的input和output参数。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属性中得到一个大小为21125的float数组。这是前面讨论过的模型的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上部署此应用程序时,您可能会遇到一些常见问题。应用程序返回5xx代码要在Azure门户中添加.NET Core 3.0支持,请选择相应应用程序服务的开发工具>扩展部分中的添加按钮。然后,从扩展列表中选择选择扩展并选择ASP.NET Core 3.0(x64)Runtime并接受法律条款,继续将扩展添加到应用程序服务。部署应用程序后,您可能会得到5xx代码的一个原因是平台。web应用程序仅在64位体系结构上运行。在Azure中,更改设置>配置>常规设置菜单中相应应用程序服务中的平台设置。部署应用程序后使用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首选的版本。阅读 455赞在看2写下你的留言

(0)

相关推荐

  • 实用教程详解:用OpenCV的DNN模块部署YOLOv5目标检测

    作者丨nihate 审稿|邓富城 编辑丨极市平台 极市导读 本文中介绍的整套程序只依赖OpenCV库就能正常运行,彻底摆脱了对深度学习框架的依赖.文章讲述了作者在自己编写用OpenCV的dnn模块做Y ...

  • .NET 5 重大变更

    .NET 5 重大变更系列的最后一个主题是 WPF 和 Windows Forms.这些桌面技术在.NET Core 3.0 之前是不可用的,因为.NET Core 的早期版本主要专注于基于 Web ...

  • 将ONNX对象检测模型转换为iOS Core ML

    在本系列中,我们将使用预训练的模型来创建一个iOS应用程序,该应用程序将在实时摄像头Feed中(而非静态图片中)检测多个人和物体. 在本文中,我们将从YOLO对象检测模型从开放神经网络交换格式(ONN ...

  • 一文看懂:什么是.NET Core以及.NET Core能做什么?

    我们都知道.NET Core是一个可以用来构建现代.可伸缩和高性能的跨平台软件应用程序的通用开发框架.可用于为Windows.Linux和MacOS构建软件应用程序. 与其他软件框架不同,.NET C ...

  • 如何将多目标检测用于建筑平面图? | MixLab智能建筑

    在建筑平面图的分析中,一些复杂的平面图总是会让人感到头晕脑胀,不同的标注方式以及不同的图形符号更难以让普通人去解读. 5种不同图形符号的浴缸以及真实场景中具有的遮挡,标注等信息 有时,图形符号又会极其 ...

  • 【翻译】.NET 5 Preview 1 发布

    去年年底,我们发布了.NET Core 3.0和3.1.这些版本添加了桌面应用程序模型Windows Forms(WinForms)和WPF,ASP.NET Blazor用于构建SPA应用程序和用于构 ...

  • 百度提出PADDLESEG:一个高效的图像分割开发工具

    重磅干货,第一时间送达 小白导读 论文是学术研究的精华和未来发展的明灯.小白决心每天为大家带来经典或者最新论文的解读和分享,旨在帮助各位读者快速了解论文内容.个人能力有限,理解难免出现偏差,建议对文章 ...

  • Yolov5 系列2

    上一篇<Yolov5 系列1- Yolo发展史以及Yolov5模型详解>讲了Yolo的发展历史,这一篇的目的是讲述如何使用Yolo v5训练自定的数据集,并会分析一些常见的选项以及背后的故 ...

  • 温故知新,DotNet Core SDK和.Net CLI十八般武艺

    简介 .NET命令行接口 (CLI) 工具是用于开发.生成.运行和发布.NET应用程序的跨平台工具链. https://docs.microsoft.com/zh-cn/dotnet/core/too ...

  • 4.创建ASP.NET Core Web应用程序

    这篇文章中,我将教大家如何从头到尾创建ASP.NET Core Web应用程序,这个系列,前面我已经写了三篇文章,大家看这篇文章之前,可以先去熟悉一下前面的3篇文章,打一下基础.在这篇文章中,我将和大 ...

  • 针对ASP.NET Core Web API的先进架构

    WEB前端开发社区 昨天.NET Core 最初是在2016年发布的,随着.NET Core 2.0的发布,微软拥有了下一个通用.模块化.跨平台和开源的平台主版本..NET Core已经创建了许多AP ...

  • 深入探究ASP.NET Core读取Request.Body的正确方式

    dotNET跨平台 今天 以下文章来源于yi念之间 ,作者yi念之间 前言 相信大家在使用ASP.NET Core进行开发的时候,肯定会涉及到读取Request.Body的场景,毕竟我们大部分的POS ...

  • NET问答: 如何给 ASP.NET Core 配置指定端口 ?

    今天 以下文章来源于NET技术问答 ,作者Stackoverflow NET技术问答精选 StackOverFlow 上的.NET 相关技术问题解答 咨询区 Drew Noakes: 我是 ASP.N ...

  • 如何解决在ASP.NET Core中找不到图像时设置默认图像

    dotNET跨平台 今天 以下文章来源于UP技术控 ,作者conan5566 UP技术控不止IT 还有生活 背景 web上如果图片不存在一般是打xx,这时候一般都是会设置默认的图片代替.现在用中间件的 ...

  • 使用ASP .NET Core Razor页面,Web API和实体框架进行分页和排序

      如何实现分页和排序以产生良好的性能     如何使用.NETCoreRazor页面,WebAPI和实体框架实现分页和排序以产生良好的性能.     该项目的特点是:     选择页面大小     ...

  • 如何使用页面渲染,TypeScript和“ require”创建ASP.NET Core API项目

    我创建了一个ASP.NETCoreWebAPI项目而不是ASP.NETCoreWebApp项目,因为我正在实现一个API,而不是Web应用程序.但是,我的API包含用于管理和测试API函数的默认页面, ...

  • ASP.Net 管道模型 VS Asp.Net Core 管道 总结

    dotNET跨平台 今天 1 管道模型 1 Asp.Net Web Form管道 请求进入Asp.Net工作进程后,由进程创建HttpWorkRequest对象,封装此次请求有关的所有信息,然后进入H ...