看图识熊(三)

使用Windows Machine Learning加载ONNX模型并推理

环境要求

Windows Machine Learning支持在Windows应用程序中加载并使用训练好的机器学习模型。Windows 10从10.0.17763.0版本开始提供这套推理引擎,所以需要安装17763版本的Windows 10 SDK进行开发,并且需要运行在17763及以上版本的Windows 10中。

创建UWP项目

打开Visual Studio 2017,新建项目,在Visual C#分类中选择,填写项目名称为,点击确定空白应用(通用 Windows)``ClassifyBear

img

在弹出的对话框中,设置目标版本和最低版本都是17763

img

添加模型文件到项目中

打开解决方案资源管理器中,在项目中的目录上点右键->添加->现有项,添加模型文件Assets``BearModel.onnx

模型是在应用运行期间加载的,所以在编译时需要将模型复制到运行目录下。在模型文件上点右键,属性,然后在属性面板上,将属性改为,将属性改为。生成操作``内容``复制到输出目录``如果较新则复制

img

打开解决方案资源管理器,应该可以看到在项目根目录自动生成了和模型同名的代码文件,里面就是对该模型的一层封装,包括了输入输出的定义、加载模型的方法以及推理的方法。BearModel.cs

如果在解决方案资源管理器中没有看到该文件,说明生成失败,失败的原因可能是路径中包含中文、或者onnx模型不合法、或者其它原因,可以尝试手动生成。

在开始菜单中找到并打开,运行如下命令VS 2017的开发人员命令提示符

mlgen.exe -i d:\BearModel.onnx -o d:\BearModel.cs -l CS -n BearModel

其中,指定ONNX模型路径,指定要生成的封装代码的路径,指定代码的语言,指定代码使用的命名空间。注意,命令中不要出现中文字符。-i``-o``-l``-n

生成成功后,可以手动将生成的BearModel.cs添加项目中;如果还是生成失败,需要根据错误信息继续排查原因

设计界面

打开,将整个Grid片段替换为如下代码:MainPage.xaml

<Grid>
    <StackPanel Margin="12">
        <TextBlock Text="输入要识别的图片地址:" Margin="12"></TextBlock>
        <TextBox x:Name="tbImageUrl" Margin="12"></TextBox>
        <Button x:Name="tbRun" Content="识别" Tapped="TbRun_Tapped" Margin="12"></Button>
        <TextBlock x:Name="tbBearType" Margin="12"></TextBlock>
        <Grid BorderBrush="Gray" BorderThickness="1" Margin="12" Width="454" Height="454">
            <Image x:Name="imgBear" Stretch="Fill" ImageOpened="ImgBear_ImageOpened" ImageFailed="ImgBear_ImageFailed"></Image>
        </Grid>
    </StackPanel>
</Grid>

显示效果如下图:

img

  • 输入框中用来输入要识别的图片的URLtbImageUrl

  • 按钮用来触发加载图片tbRun

  • 文本框用来显示识别的结果tbBearType

  • 图片控件用来预览要识别的图片,同时,我们也从这个控件中取出对应的图片数据,传给我们的模型推理类库去推理。这里将图片控件设置为正方形并且将属性设置为,可以保证图片拉伸显示为一个正方形的形状,这样可以方便我们直观的了解模型的输入,因为在前面查看模型信息的时候也看到了,该模型的输入图片应是227*227的正方形。imgBear``Stretch``Fill

上面的片段中分别给按钮和图片控件添加了事件响应,我们在后续小节中添加对应的实现。XAML

添加按钮的事件响应

前面文件中给按钮添加事件,这里在中完成对应的实现,从输入框中读入图片的URL,然后让图片控件加载该URL对应的图片:XAML``MainPage.xaml.cs

private void TbRun_Tapped(object sender, TappedRoutedEventArgs e)
{
    tbBearType.Text = string.Empty;
​
    Uri imageUri = null;
    try
    {
        imageUri = new Uri(tbImageUrl.Text);
    }
    catch (Exception)
    {
        tbBearType.Text = "URL不合法";
        return;
    }
​
    tbBearType.Text = "加载图片...";
​
    imgBear.Source = new BitmapImage(imageUri);
}

添加图片控件的事件响应

前面文件中给图片控件添加了两个事件:图片加载完成的事件和加载失败的事件,这里在中完成对应的实现:XAML``MainPage.xaml.cs

private void ImgBear_ImageOpened(object sender, RoutedEventArgs e)
{
    RecognizeBear();
}
​
private void ImgBear_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
    tbBearType.Text = "图片加载失败";
}

###处理模型的输入

打开自动生成的模型封装文件可以看到需要的输入如下:BearModel.cs

public sealed class BearModelInput
{
    public ImageFeatureValue data; // BitmapPixelFormat: Bgra8, BitmapAlphaMode: Premultiplied, width: 227, height: 227
}

这里需要一个类型的数据,可以使用从中创建。使用时,你可以不用担心图片格式的转换和缩放,系统会自动处理图片来匹配模型需要的输入格式。目前支持的像素格式为Gray8、Rgb8和Bgr8,色值范围为0-255。ImageFeatureValue``ImageFeatureValue.CreateFromVideoFrame``VidelFrame``ImageFeatureValue

下面是处理图片输入的代码:

private async Task<BearModelInput> GetInputData()
{
    // 将图片控件重绘到图片上
    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(imgBear);
​
    // 取得所有像素值
    var pixelBuffer = await rtb.GetPixelsAsync();
​
    // 构造模型需要的输入格式
    SoftwareBitmap softwareBitmap = SoftwareBitmap.CreateCopyFromBuffer(pixelBuffer, BitmapPixelFormat.Bgra8, rtb.PixelWidth, rtb.PixelHeight);
    VideoFrame videoFrame = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
    ImageFeatureValue imageFeatureValue = ImageFeatureValue.CreateFromVideoFrame(videoFrame);
​
    BearModelInput bearModelInput = new BearModelInput();
    bearModelInput.data = imageFeatureValue;
    return bearModelInput;
}

加载模型并推理

这是最关键的一步,也是非常简单的一步。自动生成的模型封装文件中已经封装了加载模型的方法和推理的方法,直接调用就可以:BearModel.cs

private async void RecognizeBear()
{
    // 加载模型
    StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/BearModel.onnx"));
    BearModelModel model = await BearModelModel.CreateFromStreamAsync(modelFile);
​
    // 构建输入数据
    BearModelInput bearModelInput = await GetInputData();
​
    // 推理
    BearModelOutput output = await model.EvaluateAsync(bearModelInput);
​
    tbBearType.Text = output.classLabel.GetAsVectorView().ToList().FirstOrDefault();
}

测试

编译运行,然后在网上找一张熊的图片,把地址填到输入框内,然后点击识别按钮,就可以看到识别的结果了。注意,这个URL应该是图片的URL,而不是包含该图片的网页的URL。

img

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

XML技术分析01

一、什么是XML eXtensible Markup Language ——可扩展标记语言 1、标记&#xff08; markup &#xff09;及标记语言&#xff1a; markup的含义是指插入到文档(document)中的标记 标记&#xff1a;是以标志的格式附加在文档中的。标志赋予文档的某一部分一个标记的标识…

HTML5+CSS3小实例:人物介绍卡片2.0

实例:人物介绍卡片2.0 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><…

PDF控件Spire.PDF for .NET【安全】演示:获取并验证 PDF 中的数字签名

在 PDF 中创建数字签名广泛用于保护 PDF 文件。因此&#xff0c;当您查看一些带有数字签名的PDF文件时&#xff0c;需要获取并验证数字签名。本文向您展示了一种通过使用Spire.PDF和 C# 代码来获取和验证 PDF 中的数字签名的解决方案。 Spire.PDF for .NET 是一款独立 PDF 控件…

搭建一个教育小程序的必要步骤

随着科技的飞速发展&#xff0c;小程序已经深入到我们生活的方方面面。对于教育行业来说&#xff0c;小程序的出现不仅为教育机构提供了新的宣传和互动平台&#xff0c;更为学生和家长带来了更为便捷的学习体验。那么&#xff0c;如何开发一款适合教育机构的小程序呢&#xff1…

基于springboot的sql防注入过滤器

目录 何为SQL注入基于springboot的sql防注入过滤器 回到顶部 何为SQL注入 SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现…

牛客网BC12-字符圣诞树

字符圣诞树 解题思路&#xff1a; 确定行数&#xff0c;一共5行&#xff0c;循环5次确定每行答应的内容&#xff0c;分成两部分&#xff0c;空格和字符 打印空格的个数依次递减打印字符的个数依次递增 找出打印空格和字符的个数与行数之间的关系 int main() {char ch 0;scanf(…

C# StringBuilder对比string的优点和15大案例

文章目录 StringBuilder和String 对比1. **循环内字符串连接**2. **构建大型日志消息**3. **格式化长字符串**4. **SQL 查询构造**5. **从文件读取并合并行**6. **拼接数组元素**7. **格式化电子邮件模板**8. **处理用户输入流**9. **JSON 或 XML 格式的序列化与构建**10. **动…

静态网页设计——天行九歌(HTML+CSS+JavaScript)(dw、sublime Text、webstorm、HBuilder X)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a;https://www.bilibili.com/video/BV1de411m7y4/?vd_source5f425e0074a7f92921f53ab87712357b 源码&#xff1a;https://space.bilibili.com…

光明源@智慧环卫新标杆,智慧公厕系统全面升级

在城市的喧嚣之中&#xff0c;一个看似不太引人注目但却无法忽视的领域正在经历一场革命性的变革。作为城市基础设施的一部分&#xff0c;公厕一直以来被人们忽略&#xff0c;然而&#xff0c;随着科技的迅速发展&#xff0c;一项前所未有的升级正向我们走来——智慧公厕系统。…

2024.1.7周报

目录 摘要 ABSTRACT 一、文献阅读 1、题目 2、摘要 3、模型架构 4、文献解读 一、Introduction 二、创新点 三、实验过程 四、结论 二、深度学习知识 一、从Encoder-Decoder框架中理解为什么要有Attention机制 二、Attention思想 三、Seq2Seq Attention代码逐…

【C++】- 类和对象(!!C++类基本概念!this指针详解)

类和对象 引入类类的定义类的访问限定操作符类的作用域类的实例化类对象模型this指针 引入类 在 C中&#xff0c;引入了一个新的定义----------类。类是一种用户自定义的数据类型&#xff0c;用于封装数据和行为。类可以看作是一个模板或蓝图&#xff0c;描述了一组相关的数据和…

CCC数字钥匙设计【NFC】--NFC通信之APDU TLV

CCC3.0&#xff0c;包含NFC、BLE、UWB技术。当采用NFC通信时&#xff0c;车端与手机端是通过APDU来进行交互的。而在APDU中的data数据段&#xff0c;又可能会嵌入TLV协议的数据&#xff0c;以完成车端与手机端的通信交互。 本文先介绍APDU及TLV的一些基础知识&#xff0c;再通…

书生·浦语大模型第二课作业

作业一&#xff1a;小故事创作 作业要求&#xff1a;使用 InternLM-Chat-7B 模型生成 300 字的小故事&#xff08;需截图&#xff09; 完成情况&#xff1a; 作业二&#xff1a;熟悉 hugging face 下载功能 作业要求&#xff1a;熟悉 hugging face 下载功能&#xff0c;使用…

Anaconda 环境中安装OpenCV (cv2)

1、使用Anaconda 的对应环境&#xff0c;查看环境中的Python版本号 (1)使用Anaconda 查看存在的环境&#xff1a;conda info --env (2)激活环境&#xff1a;conda activate XXX 2、根据版本号&#xff0c;下载对应的 python-opencv 包 &#xff08;1&#xff09;选择国内源的…

[MySQL]视图索引以及连接查询案列

目录 1.视图 1.1视图是什么 1.2视图的作用 1.3操作 1.3.1创建视图 1.3.2视图的修改 1.3.3删除视图 1.3.4查看视图 2.索引 2.1什么是索引 2.2为什么要使用索引 2.3索引的优缺点 2.3.1优点 2.3.2缺点 2.4索引的分类 3.连接查询案列 4.思维导图 1.视图 1.1视图是什么 视图…

el-table魔改样式出现BUG,表格内容区域出现滚动条

问题&#xff1a;el-table表格内容区域在高度自适应的情况下冒出滚动条 解决办法&#xff1a; 代码排查后发现时我设置了fixed:“xxx” 属性就会导致滚动条出现的问题&#xff0c;不设置则无。 [{ type: index, label: 序号, fixed: left },{ prop: enterprisesName, label: …

【C++】带你学会使用C++线程库thread、原子库atomic、互斥量库mutex、条件变量库condition_variable

C线程相关知识讲解 前言正式开始C官方为啥要提供线程库thread构造函数代码演示this_threadget_id()yield()sleep_until和sleep_for mutex构造函数lock和unlock上锁全局锁局部锁lambda表达式 try_lock 其他锁时间锁递归版本专用锁recursive_mutex 锁的异常处理lock_guardunique_…

springboot整合缓存技术

缓存&#xff08;cache&#xff09; 为啥需要使用缓存 问题描述&#xff1a;企业级应用主要作用是信息处理&#xff0c;当需要读取数据时&#xff0c;由于受限于数据库的访问效率&#xff0c;导致整体系统性能偏低。&#xff08;就是说&#xff1a;应用程序直接与数据库打交道…

深入C++继承:面向对象编程的核心概念

C是一种功能强大的编程语言&#xff0c;支持面向对象编程&#xff08;OOP&#xff09;范式。在面向对象编程中&#xff0c;继承是一种重要的概念&#xff0c;它使得我们能够创建具有层次结构的类&#xff0c;并实现代码的重用和扩展。本文将深入探讨C中的继承机制&#xff0c;介…

[C#]C# OpenVINO部署yolov8-pose姿态估计模型

【源码地址】 github地址&#xff1a;https://github.com/ultralytics/ultralytics 【算法介绍】 Yolov8-Pose算法是一种基于深度神经网络的目标检测算法&#xff0c;用于对人体姿势进行准确检测。该算法在Yolov8的基础上引入了姿势估计模块&#xff0c;通过联合检测和姿势…