AI看图识熊实战(一)

使用ONNX Runtime封装onnx模型并推理

进行这一步之前,请确保已正确安装配置了Visual Studio 2017 和 C#开发环境。

项目的代码也可以在这里找到,下面的步骤是带着大家从头到尾做一遍。

界面设计

创建Windows窗体应用(.NET Framework)项目,这里给项目起名ClassifyBear。

在解决方案资源管理器中找到Form1.cs,双击,打开界面设计器。从工具箱中向Form中依次拖入控件并调整,最终效果如下图所示:

左侧从上下到依次是:

  • Label控件,将内容改为“输入要识别的图片地址:”

  • TextBox控件,可以将控件拉长一些,方便输入URL

  • Button控件,将内容改为“识别”

  • Lable控件,将label的内容清空,用来显示识别后的结果。因为label也没有边框,所以在界面看不出来。可以将此控件的字体调大一些,能更清楚的显示推理结果。

右侧的控件是一个PictureBox,用来预览输入的图片,同时,我们也从这个控件中取出对应的图片数据,传给我们的模型推理类库去推理。建议将控件属性的SizeMode更改为StretchImage,并将控件长和宽设置为同样的值,保持一个正方形的形状,这样可以方便我们直观的了解模型的输入,因为在前面查看模型信息的时候也看到了,该模型的输入图片应是正方形(当前最新的定制化视觉服务导出的模型需要的输入图片大小为224*224)。

添加模型文件到项目中

打开解决方案资源管理器中,在项目上点右键->添加->现有项,在弹出的对话框中,将文件类型过滤器改为所有文件,然后导航到模型所在目录,选择模型文件并添加。本示例中使用的模型文件是BearModel.onnx

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

添加OnnxRuntime库

微软开源的OnnxRuntime库提供了NuGet包,可以很方便的集成到Visual Studio项目中。

打开解决方案资源管理器,在引用上点右键,管理NuGet程序包。

在打开的NuGet包管理器中,切换到浏览选项卡,搜索onnxruntime,找到Microsoft.ML.OnnxRuntime包,当前版本是0.4.0,点击安装,稍等片刻,按提示即可完成安装。

当前NuGet发布的OnnxRuntime库支持x64及x86架构的运行库,建议使用x64的,所以这里将项目的目标架构改为x64。

在解决方案上点右键,选择配置管理器。在配置管理器对话框中,将活动解决方案平台切换为x64。如果没有x64,在下拉框中选择新建,按提示新建x64平台。

处理输入并加载模型进行推理

在Form1.cs上点右键,选择查看代码,打开Form1.cs的代码编辑窗口。

添加一个成员变量

// 使用Netron查看模型,得到模型的输入应为224*224大小的图片
private const int imageSize = 224;

回到Form1的设计界面,双击识别按钮,会自动跳转到代码页面并添加了button1_Click方法,在其中添加以下代码:

首先,每次点击识别按钮时都先将界面上显示的上一次的结果清除

// 识别之前先重置界面显示的内容
label1.Text = string.Empty;
pictureBox1.Image = null;
pictureBox1.Refresh();然后,让图片控件加载图片bool isSuccess = false;
try
{pictureBox1.Load(textBox1.Text);isSuccess = true;
}
catch (Exception ex)
{MessageBox.Show($"读取图片时出现错误:{ex.Message}");throw;
}如果加载成功,将图片数据处理成需要的大小,然后加载模型进行推理。if (isSuccess)
{// 图片加载成功后,从图片控件中取出224*224的位图对象Bitmap bitmap = new Bitmap(pictureBox1.Image, imageSize, imageSize);
​float[] imageArray = new float[imageSize * imageSize * 3];
​// 按照先行后列的方式依次取出图片的每个像素值for (int y = 0; y < imageSize; y++){for (int x = 0; x < imageSize; x++){var color = bitmap.GetPixel(x, y);
​// 使用Netron查看模型的输入发现// 需要依次放置224 *224的蓝色分量、224*224的绿色分量、224*224的红色分量imageArray[y * imageSize + x] = color.B;imageArray[y * imageSize + x + 1 * imageSize * imageSize] = color.G;imageArray[y * imageSize + x + 2 * imageSize * imageSize] = color.R;}}
​// 设置要加载的模型的路径,跟据需要改为你的模型名称string modelPath = AppDomain.CurrentDomain.BaseDirectory + "BearModel.onnx";
​using (var session = new InferenceSession(modelPath)){var container = new List<NamedOnnxValue>();
​// 用Netron看到需要的输入类型是float32[None,3,224,224]// 第一维None表示可以传入多张图片进行推理// 这里只使用一张图片,所以使用的输入数据尺寸为[1, 3, 224, 224]var shape = new int[] { 1, 3, imageSize, imageSize };var tensor = new DenseTensor<float>(imageArray, shape);
​// 支持多个输入,对于mnist模型,只需要一个输入,输入的名称是datacontainer.Add(NamedOnnxValue.CreateFromTensor<float>("data", tensor));
​// 推理var results = session.Run(container);
​// 输出结果有两个,classLabel和loss,这里只关心classLabelvar label = results.FirstOrDefault(item => item.Name == "classLabel")? // 取出名为classLabel的输出.AsTensor<string>()?.FirstOrDefault(); // 支持多张图片同时推理,这里只推理了一张,取第一个结果值
​// 显示在控件中label1.Text = label;}
}

注意,这里的数据转换一定要按照前面查看的模型的信息来转换,图片大小需要长宽都是224像素,并且要依次放置所有的蓝色分量、所有的绿色分量、所有的红色分量,如果顺序不正确,不能达到最佳的推理结果。

测试

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

如果运行时遇到类似于找不到onnxruntime的dll的问题,可能是编译时相关库没有拷到运行目录下,可以尝试先清理解决方案,然后再重新编译解决方案。也可以手动到解决方案目录\packages\Microsoft.ML.OnnxRuntime.0.4.0\runtimes\win-x64\native下将onnxruntime.dll拷到程序运行目录

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

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

相关文章

数字化工厂产品推荐 带OPC UA的分布式IO模块

背景 近年来&#xff0c;为了提升在全球范围内的竞争力&#xff0c;制造企业希望自己工厂的机器之间协同性更强&#xff0c;自动化设备采集到的数据能够发挥更大的价值&#xff0c;越来越多的传统型工业制造企业开始加入数字化工厂建设的行列&#xff0c;实现智能制造。 数字化…

基于SSM的《数据库系统原理》课程平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

用js玩一玩猜数字游戏

需求&#xff1a; 1. 生成随机的数字 0 到 20 2. 只能猜 5 次&#xff0c; 5 次机会用完提示 这都猜不到 3. 猜对了&#xff0c; 就提示 恭喜猜对拉 4. 猜小了&#xff0c; 您猜的数字小了 5. 猜大了&#xff0c; 就提示用户 您猜的数字大了 <script>// 1. 生成随机…

mysql之视图mysql连接案例索引

文章目录 一、视图1.1 含义1.2 操作1.2.1 创建视图1.2.2 视图的修改1.2.3 删除视图1.2.4 查看视图 二、连接案例01)查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数02)查询同时存在" 01 "课程和" 02 "课程的情况03&#xff0…

etcd储存安装

目录 etcd介绍: etcd工作原理 选举 复制日志 安全性 etcd工作场景 服务发现 etcd基本术语 etcd安装(centos) 设置&#xff1a;etcd后台运行 etcd 是云原生架构中重要的基础组件&#xff0c;由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册…

I/O流基础

1.输入/输出流 流是一组有序的数据序列&#xff0c;根据操作的类型&#xff0c;可以分为输入流和输出流两种。 Java定义的输入输出类被放在java.io包中 所有的输入流类都是抽象类InputStream&#xff08;字节输入流&#xff09;或抽象类Reader&#xff08;字符输入流&#xff…

基于多目标粒子群算法的支配解求解,基于多目标粒子群的帕累托前沿求解,基于mopso的多目标求解,基于mopso+bp的多目标求解资源

目录 摘要 测试函数shubert 粒子群算法的原理 粒子群算法的主要参数 粒子群算法原理 基于多目标粒子群算法的支配解求解,基于多目标粒子群的帕累托前沿求解,基于mopso的多目标求解,基于mopso+bp的多目标求解资源 代码 结果分析 展望 代码下载:基于多目标粒子群算法的支配解…

关于图像分类任务中划分数据集,并且生成分类类别的josn字典文件

1. 前言 在做图像分类任务的时候&#xff0c;数据格式是文件夹格式&#xff0c;相同文件夹下存放同一类型的类别 不少网上的数据&#xff0c;没有划分数据集&#xff0c;虽然代码简单&#xff0c;每次重新编写还是颇为麻烦&#xff0c;这里记录一下 如下&#xff0c;有的数据…

Ant Design 使用出现 Error_ Can‘t resolve ‘_antd_dist_antd.css‘

推荐阅读 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;一&#xff09; 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;二&#xff09; 文章目录 推荐阅读问题描述问题解决方法一&#xff1a;进行版本回退&#xff0c;安装指定版本方…

Keil使用手册

文章目录 1 设置1.1 背景1.2 Project窗口显示.h文件1.3 注释1.4 Project窗口消失TAB转空格的设置keilsourceInsight 显示cannot evaluate普通局部变量静态全局变量静态局部变量 2 报错与解决2.1 warning&#xff1a;#1-D last line of file ends without anewline2.2 中文乱码 …

数据结构与算法教程,数据结构C语言版教程!(第二部分、线性表详解:数据结构线性表10分钟入门)九

第二部分、线性表详解&#xff1a;数据结构线性表10分钟入门 线性表&#xff0c;数据结构中最简单的一种存储结构&#xff0c;专门用于存储逻辑关系为"一对一"的数据。 线性表&#xff0c;基于数据在实际物理空间中的存储状态&#xff0c;又可细分为顺序表&#xff…

Window端口占用处理

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…